I’m using the XBIB-U-SS dev board from the programmable xbee kit and trying to communicate with I2C devices. I’ve wired SDA and SCL with 2k2 pullup resistors. I’ve also removed R37 to ensure SDA wasn’t connected to anything else on the board.
I’ve tried two different I2C devices and they both display the same incorrect behavior.
An i2c_write() command always succeeds. I get a proper ACK back from the device. In the case of one of the devices, it has a LED that blinks when it accepts a write command, so I know it has succeeded.
However, i2c_read() is ALWAYS failing with -203 return value. Any ideas of additional things I can try to get i2c devices talking?
Sorry to resurrect this thread, but I had the same problem and thought my solution might be helpful to others.
Probing the I2C line with an oscilloscope showed no sign of any activity on calls to the i2c_read() function, not even a start bit. I tried the i2c_read function on two different XBees without success, so it’s unlikely to be a fluke. You can read the code behind the I2C functions in CodeWarrior’s project explorer at \Sources\drivers\i2c\i2c.c. I tried editing that file to add a start bit to i2c_read() like that in the i2c_write function, and… it worked!
Here’s what I did. Notice that the “drivers” folder is a link, so CodeWarrior wouldn’t let me edit the file found in its project explorer. Instead, right-click the “i2c” folder in CodeWarrior’s project explorer and click “Show in Windows Explorer”. This will take you to your Digi software installation directory. Open the “real” i2c.c file shown there, and scroll down to the i2c_read function. Comment out the line saying “i2c_set_rep_start();,” and next to it, add the line “i2c_start();.”
As best as I can tell from the datasheet of the MCS08QE32 (the second processor inside the programmable XBees), the code behind the i2c_set_rep_start() function enables repeated start condition functionality, which you can read more about here https://www.i2c-bus.org/repeated-start-condition/. Basically, it is used to keep control of the bus for several consecutive transactions (such as reading data from several different slaves) in a multi-master scenario. Unfortunately, and I am unable to determine why, using the i2c_read() function with repeated start condition functionality enabled causes erratic behavior on my XBee such as intermittent resets and, of course, broken I2C reads. So, I disabled that functionality and use the i2c_start() function to generate the start bit instead.
I have not tested this workaround in a multi-master scenario, but I imagine it would stop preventing one master from interrupting another’s control of the bus. But, in my single-master situation, it has so far worked fine. Hope this helps!