A few people seem to be playing with I2C, and hitting common problems, so I did some I2C updates this afternoon:
- Move to specifiying address as 8-bit rather than 7-bit
- Return success from read/write (ACK)
- Wrote a simple program to find I2C devices on a bus, and list their addresses
Here are the details:
1) I2C addresses are 7-bit, sent as the top bits of a byte with the bottom bit saying whether it is a read or write. However, most datasheets actually list the address already aligned to the top bits (shifted left by one) i.e. 8-bit, and some even list two addresses; the write and the read address (write | 1).
+----------------------+
| 7-bit address | R/W |
+----------------------+
As such, the majority of first uses of I2C have tried the wrong address :(
So rather than fight the flow, i've updated the library to use what seems more conventional. You specify the address as 8-bit, and the library will force the bottom bit to 0 for a write, and 1 for a read. This should make things more in line with how things seem to be documented.
2) The library used to die if a transaction failed, for any reason, including a NACK. This was more a quick fix when I first played with getting the library working. However, for some devices (RAM/PROM), it is required to be able to detect the NACK, as that is how you detect whether e.g. the device is still busy.
Whilst not ideal, for now the I2C read/write functions return 0 if everything went ok (ACK), and non-0 if not (NACK). It still needs a proper think and reworking, but this gets some additional functionality working straight away. In particular, it lets you see if a device responds, which leads to:
3) I2CU is a quick program I wrote to go through all the I2C addresses on a bus, and see if anything responds. It lists the devices it hears from, and hence should be a good way to see if your bus is up and running, and whether devices are on it. The basic idea is:
for (int address=0; address<256; address+=2) {
if (!i2c.write(address, NULL, 0)) { // 0 returned is ok
printf(" - I2C device found at address 0x%02X\n", address);
}
}
The full program can be imported from http://mbed.org/users/simon/published/7250cc082e343d0dba3ee345cfcf0cf2/I2CU.zip
Hopefully this will be ideal for a first test step before worrying about device addresses and command structures etc. It could be improved to diagnose the exact faults better, but for now it is limited by the I2C library functionality; i'll aim to update both when some of our I2C test parts come in.
If you are having trouble with your I2C bus or devices, run this first!
Simon
A few people seem to be playing with I2C, and hitting common problems, so I did some I2C updates this afternoon:
Here are the details:
1) I2C addresses are 7-bit, sent as the top bits of a byte with the bottom bit saying whether it is a read or write. However, most datasheets actually list the address already aligned to the top bits (shifted left by one) i.e. 8-bit, and some even list two addresses; the write and the read address (write | 1).
As such, the majority of first uses of I2C have tried the wrong address :(
So rather than fight the flow, i've updated the library to use what seems more conventional. You specify the address as 8-bit, and the library will force the bottom bit to 0 for a write, and 1 for a read. This should make things more in line with how things seem to be documented.
2) The library used to die if a transaction failed, for any reason, including a NACK. This was more a quick fix when I first played with getting the library working. However, for some devices (RAM/PROM), it is required to be able to detect the NACK, as that is how you detect whether e.g. the device is still busy.
Whilst not ideal, for now the I2C read/write functions return 0 if everything went ok (ACK), and non-0 if not (NACK). It still needs a proper think and reworking, but this gets some additional functionality working straight away. In particular, it lets you see if a device responds, which leads to:
3) I2CU is a quick program I wrote to go through all the I2C addresses on a bus, and see if anything responds. It lists the devices it hears from, and hence should be a good way to see if your bus is up and running, and whether devices are on it. The basic idea is:
The full program can be imported from http://mbed.org/users/simon/published/7250cc082e343d0dba3ee345cfcf0cf2/I2CU.zip
Hopefully this will be ideal for a first test step before worrying about device addresses and command structures etc. It could be improved to diagnose the exact faults better, but for now it is limited by the I2C library functionality; i'll aim to update both when some of our I2C test parts come in.
If you are having trouble with your I2C bus or devices, run this first!
Simon