I'm getting snubbed by my I2C device
CannibalRobotics
Posts: 535
I'm trying to communicate with a TI BQ32000 clock/cal chip.
For whatever reason, I'm getting no ack back.
The code is borrowed and slightly modified from Agyeman's EEPROM driver. My confusion is why there is no ack coming back in the 9th clock pulse.
The two scope captures attached show the first two then the first 6 bytes in the burst. Data is on top in blue, clock is below on bottom.
Any ideas - am I missing something really easy here?
Thanks in advance....
Jim-
RTClockData is called about every 5 seconds to load a buffer.
For whatever reason, I'm getting no ack back.
The code is borrowed and slightly modified from Agyeman's EEPROM driver. My confusion is why there is no ack coming back in the 9th clock pulse.
The two scope captures attached show the first two then the first 6 bytes in the burst. Data is on top in blue, clock is below on bottom.
Any ideas - am I missing something really easy here?
Thanks in advance....
Jim-
RTClockData is called about every 5 seconds to load a buffer.
PRI RTClockData | i startDataTransfer transmitPacket(%1101_0000) ' Slave Address, write transmitPacket(%0000_0000) ' Sub-Address of starting register startDataTransfer ' do start again per spec transmitPacket(%1101_0001) ' Slave Address again read mode Repeat i from 0 to 7 ' Start reading the registers RT_Bytes[i] := receivePacket(7-i) ' get the 8 bytes from the clock stopDataTransfer PRI transmitPacket(value) ' 4 Stack Longs value := ((!value) >< 8) dira[RTClk] := 0 dira[RTDat] := 0 repeat 8 dira[RTDat] := value dira[RTClk] := false dira[RTClk] := true value >>= 1 dira[RTDat] := false dira[RTClk] := false result := not(ina[RTDat]) dira[RTClk] := true dira[RTDat] := true PRI receivePacket(aknowledge) ' 4 Stack Longs dira[RTDat] := false repeat 8 result <<= 1 dira[RTClk] := false result |= ina[RTDat] dira[RTClk] := true dira[RTDat] := (not(not(aknowledge))) dira[RTClk] := false dira[RTClk] := true dira[RTDat] := true PRI startDataTransfer ' 3 Stack Longs outa[RTDat] := false outa[RTClk] := false dira[RTDat] := true dira[RTClk] := true PRI stopDataTransfer ' 3 Stack Longs dira[RTClk] := false dira[RTDat] := false
Comments
I knew someone would pick it up quick.
J-
Peeking at your first picture, it looks as if you are not sending a START bit...... or is this picture mid-stream after the start has already been sent ?
Cheers,
Peter (pjv)
According to I2c specs, the Start condition is the falling edge of SLC while holding SDA low. That condition occurs below the trigger marker (down pointing white arrow) on the far left of the screen. I am not aware of a 'start bit' or maybe I'm missunderstanding.
This is the very first communication from the prop about 10 seconds after everyone got powered up.
J-
I think there's a driver by Mike Green in OBEX that has an example of this function...
As I recall, it's just sending a lot of zeros...
This may be the source of the problem, especially since it's one of those "everything but the kitchen sink" efforts (the I2C driver, that is). When learning new parts I always start with simplistic drivers first, just to make sure all the connections are good. If you can get things working with a simple driver, you can certainly get things going with a more sophisticated driver later.
In racing school they used to tell us, "slow in, fast out" when referring to corners. I find the same rule applies to product development.
I don't have that chip but I wrote and attached a really simple demo that I would start with if I did. Note that my driver follows the I2C rules and requires a pull-up on the clock pin.
Thanks Jon!
Here is the final result with the code below.
If you look at the data sheet you'll see that the last byte in a multi-byte read gets a NAK, not ACK as you're doing. Here's the fix:
Now your scope shot shows a proper START bit!
Cheers,
Peter (pjv)