1346: fix I2C controller problems after NACK r=Dirbaio a=Juravenator

While tinkering with I2C on a NUCLEO-H723ZG, I noticed that when trying to communicate with a non-existent device you do receive a proper NACK error, but afterwards any future communications with any device no longer works as expected.

The use case is auto-detection of devices, in this case a series of Adafruit 24LC32 I2C EEPROM boards.

On closer inspection with a logic analyzer, I observed that after the NACK, any data bytes sent out by the board to the devices are just zeros. Even though the embassy code specifies the correct data in `set_txdata` in `write_internal`. Something seems to be going wrong with the controller or buffers on the board itself.

Then I noticed what seems to be a logic error in `flush_txdr`, which is called when issuing a NACK.

After flipping the if statement, I2C communications keep working as expected after issuing a NACK.

Co-authored-by: Glenn Dirkx <glenn.dirkx@gmail.com>
This commit is contained in:
bors[bot] 2023-04-10 14:49:12 +00:00 committed by GitHub
commit 53c60df997
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -262,7 +262,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
if T::regs().isr().read().txis() { if T::regs().isr().read().txis() {
T::regs().txdr().write(|w| w.set_txdata(0)); T::regs().txdr().write(|w| w.set_txdata(0));
} }
if T::regs().isr().read().txe() { if !T::regs().isr().read().txe() {
T::regs().isr().modify(|w| w.set_txe(true)) T::regs().isr().modify(|w| w.set_txe(true))
} }
} }