Skip to content

Commit a100426

Browse files
Various i2c fixes (#282)
* i2c: Clear error flags clear the error flags after detecting them as the hardware does not autoclear on read. Signed-off-by: Sjoerd Simons <sjoerd@luon.net> * i2c: Send stop after acknowledge error If the remote device fails to acknowledge send a stop. This allows the bus to go back to idle again. Signed-off-by: Sjoerd Simons <sjoerd@luon.net> * i2c: Set ack bit on multibyte reads Enable the ack bit on multibyte (>2) reads otherwise bytes from the remote device are not acknowledged. Signed-off-by: Sjoerd Simons <sjoerd@luon.net> * Update changelog Co-authored-by: Frans Skarman <frans.skarman@protonmail.com>
1 parent a6dde78 commit a100426

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- LSB/MSB bit format selection for `SPI`
1313

14+
### Fixed
15+
- Fix > 2 byte i2c reads
16+
- Send stop after acknowledge errors on i2c
17+
- Fix i2c interactions after errors
18+
1419
## [v0.7.0]- 2020-10-17
1520

1621
### Breaking changes

src/i2c.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,16 @@ macro_rules! wait_for_flag {
220220
let sr1 = $i2c.sr1.read();
221221

222222
if sr1.berr().bit_is_set() {
223+
$i2c.sr1.write(|w| w.berr().clear_bit());
223224
Err(Other(Error::Bus))
224225
} else if sr1.arlo().bit_is_set() {
226+
$i2c.sr1.write(|w| w.arlo().clear_bit());
225227
Err(Other(Error::Arbitration))
226228
} else if sr1.af().bit_is_set() {
229+
$i2c.sr1.write(|w| w.af().clear_bit());
227230
Err(Other(Error::Acknowledge))
228231
} else if sr1.ovr().bit_is_set() {
232+
$i2c.sr1.write(|w| w.ovr().clear_bit());
229233
Err(Other(Error::Overrun))
230234
} else if sr1.$flag().bit_is_set() {
231235
Ok(())
@@ -432,12 +436,17 @@ where
432436
last_ret
433437
}
434438

435-
fn write_without_stop(&mut self, addr: u8, bytes: &[u8]) -> NbResult<(), Error> {
436-
self.send_start_and_wait()?;
439+
fn send_addr_and_wait(&mut self, addr: u8, read: bool) -> NbResult<(), Error> {
437440
self.nb.i2c.sr1.read();
438-
self.nb.send_addr(addr, false);
441+
self.nb.send_addr(addr, read);
442+
let ret = busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout);
443+
if ret == Err(Other(Error::Acknowledge)) {
444+
self.nb.send_stop();
445+
}
446+
ret
447+
}
439448

440-
busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout)?;
449+
fn write_bytes_and_wait(&mut self, bytes: &[u8]) -> NbResult<(), Error> {
441450
self.nb.i2c.sr1.read();
442451
self.nb.i2c.sr2.read();
443452

@@ -451,6 +460,17 @@ where
451460

452461
Ok(())
453462
}
463+
464+
fn write_without_stop(&mut self, addr: u8, bytes: &[u8]) -> NbResult<(), Error> {
465+
self.send_start_and_wait()?;
466+
self.send_addr_and_wait(addr, false)?;
467+
468+
let ret = self.write_bytes_and_wait(bytes);
469+
if ret == Err(Other(Error::Acknowledge)) {
470+
self.nb.send_stop();
471+
}
472+
ret
473+
}
454474
}
455475

456476
impl<I2C, PINS> Write for BlockingI2c<I2C, PINS>
@@ -476,9 +496,7 @@ where
476496

477497
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
478498
self.send_start_and_wait()?;
479-
self.nb.i2c.sr1.read();
480-
self.nb.send_addr(addr, true);
481-
busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout)?;
499+
self.send_addr_and_wait(addr, true)?;
482500

483501
match buffer.len() {
484502
1 => {
@@ -515,6 +533,7 @@ where
515533
self.nb.i2c.cr1.modify(|_, w| w.ack().set_bit());
516534
}
517535
buffer_len => {
536+
self.nb.i2c.cr1.modify(|_, w| w.ack().set_bit());
518537
self.nb.i2c.sr1.read();
519538
self.nb.i2c.sr2.read();
520539

0 commit comments

Comments
 (0)