From 4619896c190c2725ac1d24d9a597d5c776e2dcc8 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 21 Jun 2023 18:48:13 +0200 Subject: [PATCH] nrf: wait for stop condition after reading from the I2C bus Found while working on the PineTime. For some reason it still kind of works in most cases, but I was hitting this issue when interacting with two different I2C devices (the touch sensor and the BMA421). --- src/machine/machine_nrf5x.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/machine/machine_nrf5x.go b/src/machine/machine_nrf5x.go index f36c7c93..8c012b49 100644 --- a/src/machine/machine_nrf5x.go +++ b/src/machine/machine_nrf5x.go @@ -70,11 +70,16 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) { i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_SUSPEND_Disabled) } - // Stop explicitly when no reads were executed, stoping unconditionally would be a mistake. - // It may execute after I2C peripheral has already been stopped by the shortcut in the read block, - // so stop task will trigger first thing in a subsequent transaction, hanging it. if len(r) == 0 { + // Stop the I2C transaction after the write. i2c.signalStop() + } else { + // The last byte read has already stopped the transaction, via + // TWI_SHORTS_BB_STOP. But we still need to wait until we receive the + // STOPPED event. + for i2c.Bus.EVENTS_STOPPED.Get() == 0 { + } + i2c.Bus.EVENTS_STOPPED.Set(0) } return