Slowing down my i2c routines on a native mode device

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Slowing down my i2c routines on a native mode device

Post by FFMan »

I've got some I2c routines I used with an LCD that were taken from the examples code on this forum.

When I moved my code to a zx24n the display didn't work properly, and I found by judicious inserting of sleep statements I got it to work again.

My sleep value is down to 1 and the display works but there is some tiny but noticeable delay in display of each character.

What can I use to introduce smaller delays ?
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Slowing down my i2c routines on a native mode device

Post by dkinzer »

FFMan wrote:What can I use to introduce smaller delays ?
Both Pause() and PulseOut() can be used to realize delays of less than the 1.95mS minimum delay of Sleep().

That said, perhaps slowing down the I2C clock would have a beneficial effect. What type of device are you communicating with and on what commands do you see the problem?
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

I'm just communicating with a an I2c to LCD interface chip. Its the second item on this page http://www.byvac.co.uk/di_i2c.php

The only problem with using pause instead is this program is multi-tasking, and the other task is time critical reading serial gps data at 57600 baud on h/w com2. Would using pulseout be better or do the resources requird conflict ?

The problem I see without my sleep is display corruption, and it works ok on the zx24a so i'm thinking its a timing issue. After experimenting it seems I can get away with only having a sleep (1) after the statement that sets scl high - but this does lead to a very slightly laggy display.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:After experimenting it seems I can get away with only having a sleep (1) after the statement that sets scl high - but this does lead to a very slightly laggy display.
The section 9.1 of the datasheet may contain a clue as to what is happening. In particular, it indicates that the device uses slave clock stretching to indicate that it is busy executing a command and that the master should hold off further commands.

Are you using the hardware I2C channel or one of the software I2C channels? Channel 0 is the hardware channel while channels 1-4 are software channels. I know that the software channels do not look for slave clock stretching before issuing a start condition. I do not know, off hand, if the I2C hardware on the AVR does but should I suspect that it would. In any event, you could monitor the SCL line and hold off issuing I2C commands until it is high. Note, particularly, that you shouldn't use GetPin() for this purpose. Rather, use something like the code below to read the Pin register directly.

Code: Select all

'
'' PinState
'
' Determine the current state of a pin.
'
Function PinState(ByVal pin as Byte) as Byte
  If CBool(Register.Pin(pin) And PortMask(pin)) Then
    PinState = 1
  Else
    PinState = 0
  End If
End Function
- Don Kinzer
FFMan
Posts: 502
Joined: 09 January 2010, 12:52 PM

Post by FFMan »

> Are you using the hardware I2C channel or one of the software I2C channels?

Don - I've emailed you the module that does the I2c stuff. I think the answer to your question is neither, I think P H Anderson has implemented I2C directly - perhaps this code is from my previous BX24 projects ?

This code works fine on VM devices but produces a corrupted display on native mode if the in_Sleepy value is 0
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

FFMan wrote:This code works fine on VM devices but produces a corrupted display on native mode if the in_Sleepy value is 0
It is quite likely that the timing for PH Anderson's bit-bang code is way too fast when compiled in native mode. The standard slow I2C speed is 100KHz (SCL frequency) but some devices go up to 400KHz. Note, too, that the PH Anderson code does not support slave clock stretching. Moreover, it ignores the ack/nak value sent by the slave for each data byte it receives.

It should be fairly easy change over to using the ZBasic low-level I2C routines on either the HW I2C channel or one of the SW I2C channels. There is nearly a 1:1 correspondance between the PH Anderson routines and the ZBasic low-level routines. The ZBasic SW I2C channels are also implemented with bit-bang methodology but the code uses the I/O Timer to implement the required I2C timing. That is all done in hardware when using the HW channel.
- Don Kinzer
Post Reply