Shop OBEX P1 Docs P2 Docs Learn Events
OBJ i2c lowlevel, PUB i2cstop — Parallax Forums

OBJ i2c lowlevel, PUB i2cstop

bozobozo Posts: 70
edited 2007-10-02 07:48 in Propeller 1
Hi, I'm trying to get a DS1307 to reliably recover from an abnormal termination and since I'm new to i2c, I am struggling.

The abnormal termination that I'm deliberately making is simply a tap on the F10 key to reload/restart the prop in the middle of a continuous loop to read the DS1307.
Regular as clockwork, after a couple of restarts the device 'hangs'.

I'm using object i2c lowlevel, and there's a comment in the middle of the code for i2cstop that looks like it might be a clue...

PUB i2cStop 'SDA goes LOW to HIGH while SCL is HIGH
dira[noparse][[/noparse]_SCL]~ 'Make SCL pin an INPUT - Pullup resistor makes this HIGH
dira[noparse][[/noparse]_SDA]~ 'Make SDA pin an INPUT - Pullup resistor makes this HIGH
'Fixes Glitch in Read Mode during abnormal termination
dira[noparse][[/noparse]_SCL]~~ 'Drive SCL pin LOW
dira[noparse][[/noparse]_SCL]~ 'Make SCL pin an INPUT - Pullup resistor makes this HIGH

can anyone shed some light on what the nature of this glitch is?
and specifically how the code here fixes it?

When I said above that the device hangs, I mean that when i2cstart is called, it never returns (probably waiting forever for SDA/SCL pins to go high).

I'm making 9 repeated calls to i2cstop, followed by a call to Initialize, then a call to DevicePresent which contains the aforementioned call to i2cstart which never returns, and I have SDA and SCL pins pulled high by external 10k resistors.

Or am I stumbling over a typical newb trap? Any clues appreciated.

Cheers,
MarkW

Comments

  • hippyhippy Posts: 1,981
    edited 2007-10-01 22:34
    Take a look at the BASIC_I2C_Driver.spin from the Object Exchange. There's some code in there which should unjam I2C devices -
    PUB Initialize(SCL) | SDA              ' An I2C device may be left in an
       SDA := SCL + 1                      '  invalid state and may need to be
       outa[noparse][[/noparse]SCL] := 1                       '   reinitialized.  Drive SCL high.
       dira[noparse][[/noparse]SCL] := 1
       dira[noparse][[/noparse]SDA] := 0                       ' Set SDA as input
       repeat 9
          outa[noparse][[/noparse]SCL] := 0                    ' Put out up to 9 clock pulses
          outa[noparse][[/noparse]SCL] := 1
          if ina[noparse][[/noparse]SDA]                      ' Repeat if SDA not driven high
             quit                          '  by the EEPROM
    
  • bozobozo Posts: 70
    edited 2007-10-01 22:39
    Yair, thanks Hippy, I saw that ... but it looks like that does the same thing as my 9 repeated calls to i2cstop ... I'll try it out anyways and see what happens.
  • Beau SchwabeBeau Schwabe Posts: 6,559
    edited 2007-10-01 23:06
    bozo,
    ·
    The reference here refers to something I noticed when reading data from I2C memories...
    'Fixes Glitch in Read Mode during abnormal termination"
    ...it should be transparent to other I2C devices because it never meets a required START condition that you would need following a STOP.
    ·
    ·
    ·
    ·
    Instead of just "blasting" a string of 9·i2cstops, it is important to understand what the·i2c slaves·consider a STOP and what they should do to respond.
    ·
    For a STOP condition, the i2c bus is basically·looking for the SCL to make a transition from LOW to HIGH followed by the SDA making a transition from LOW to HIGH.
    ·
    ·
    1) force both SCL and SDA LOW
    2) make SCL an input
    3) make SDA an input
    ·
    ... A "Glitch" can occur if another I2C device is holding the SCL or SDA line LOW.· So perhaps before #1 is initiated you should make both pins inputs and·"test" that they
    are both HIGH.
    ·
    1) make both SCL and SDA inputs ; wait until they both go HIGH before proceeding to the next step.
    2) force both SCL and SDA LOW
    3) make SCL an input ; wait until SCL goes HIGH
    4) make SDA an input ; wait until SDA goes HIGH
    ·
    The reason that 9 i2cstops are most often used, is to "shiftout" or terminate any lingering BYTE (8-bits) that may have been in the middle of reading or writing on the i2c bus.
    This may or may not work in every situation.·
    ·
    Reference:
    http://www.esacademy.com/faq/i2c/
    http://www.esacademy.com/faq/i2c/busevents/i2cstast.htm




    ·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 10/1/2007 11:12:49 PM GMT
  • bozobozo Posts: 70
    edited 2007-10-02 07:48
    thanks for the pointers Beau,

    I modified some of the i2c initialization code so as to force the stop and start conditions
    as per the book, and now everything reliably restarts 100% of the time from abnormal terminations.

    Gotta love standards.

    Cheers,
    Mark
Sign In or Register to comment.