libbase/i2c: fix i2c_poll
Change made in 1989d85
was supposed to poll I2C devices using both
writes and reads.
Here is a sequence that was supposed to happen:
- I2C start
- start I2C write
- start I2C read
- I2C stop
Unfortunately, the change worked differently:
- I2C start
- start I2C write
- write byte of (slave_addr << 1 | 1)
- I2C stop
This way, not only did the read not happen, but a potentially harmful
write was happening.
This commit makes it so following sequence takes place:
- I2C start
- start I2C write
- if (I2C write returned NACK)
- start I2C read
- if (I2C read returned ACK)
- read 1 byte and NACK it
- I2C stop
An additional 1 byte read is happening, as some devices may be unable
to process I2C stop after initiating I2C read.
Signed-off-by: Michal Sieron <msieron@antmicro.com>
This commit is contained in:
parent
b85705351c
commit
ac99709031
|
@ -274,7 +274,12 @@ bool i2c_poll(unsigned char slave_addr)
|
|||
|
||||
i2c_start();
|
||||
result = i2c_transmit_byte(I2C_ADDR_WR(slave_addr));
|
||||
result |= i2c_transmit_byte(I2C_ADDR_RD(slave_addr));
|
||||
if (!result) {
|
||||
i2c_start();
|
||||
result |= i2c_transmit_byte(I2C_ADDR_RD(slave_addr));
|
||||
if (result)
|
||||
i2c_receive_byte(false);
|
||||
}
|
||||
i2c_stop();
|
||||
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue