Skip to content

Commit 5ccdd12

Browse files
authored
generic: i2c: Fix ping_device hanging in read mode
It turns out that I2C by design cannot perform zero-sized read transfers. After the bus master addresses a peripheral in read-mode, the peripheral acknowledges and **immediately** sends the first byte of data before the bus master can interrupt again. Thus, the previous implementation of probing devices and immediately sending a stop after they acknowledge leads to an illegal bus situation. Instead, we must wait for the first byte to be clocked out and only then interrupt further transmission with a NACK. Link: #622 (comment)
1 parent cd3edea commit 5ccdd12

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

avr-hal-generic/src/i2c.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ where
289289
pub fn ping_device(&mut self, address: u8, direction: Direction) -> Result<bool, Error> {
290290
match self.p.raw_start(address, direction) {
291291
Ok(_) => {
292+
if direction == Direction::Read {
293+
self.p.raw_read(&mut [0], true)?
294+
}
292295
self.p.raw_stop()?;
293296
Ok(true)
294297
}

0 commit comments

Comments
 (0)