Shop OBEX P1 Docs P2 Docs Learn Events
I2C with spin: Actively Driving SDA (probable rehash) — Parallax Forums

I2C with spin: Actively Driving SDA (probable rehash)

I am fiddling with the HT16K33 16 by 8 LED controller. It has an I2C interface. I downloaded Mike Green's Basic I2C Driver . I used I2CStart, I2CStop, and I2CWriteByte. Here is the WriteByte snippet.
PUB I2cWriteByte(data)
    data <<= 24            'align first bit
    repeat 8
      outa[SDA] := (data <-= 1) & 1   'send one bit, msb first
      outa[SCL]~~
      outa[SCL]~
    dira[SDA]~       'allow ack bit
    outa[SCL]~~      'ignore ack bit  
    outa[SCL]~
    outa[SDA]~
    dira[SDA]~~         

The screen grab ActiveHighSDA shows writing data to a LED. The slave address is $E0, the register address is 0, and the data written is $2120 (a nonsense glyph). Everything looks great; got ACKs, Start, Stop. And it functions just fine. Stuff shows up on the LEDs just like it should. But look a little closer (BusCrash.jpg) After the eight data bit of the $21 byte, there is 8.6 (or so) microseconds of the SDA line being about half high.

I believe what's happening is this: The slave device is driving SDA LOW (ACK) while the propellor is still driving SDA HIGH (the "1" in $21). Looking at the snippet above, spin cannot execute the dira[SDA]~ instantly after making the clock LOW. Now, is this really a problem? I think it would shorten the life of the two opposing output stages, and would cause some RFI.

The fix is really simple; be sure there is a pullup on SDA and only ever drive it LOW. Here is a modified WriteByte:
PUB I2cWriteByte(data)       'modified to not drive SDA HIGH
                             'assumes it is driving SDA LOW when enters
    data <<= 24            'align first bit
    repeat 8
      if ((data <-= 1) & 1) == 0   'extract one bit, msb first
        dira[SDA]~~                'drive it low
      else
        dira[SDA]~                 'pullup pulls high   
      outa[SCL]~~
      outa[SCL]~
    dira[SDA]~       'allow ack bit
    outa[SCL]~~      'ignore ack bit  
    outa[SCL]~
    outa[SDA]~
    dira[SDA]~~

OpenCollSDA.jpg shows the bus with this code.




Comments

Sign In or Register to comment.