diff options
author | Daniel Jarai <daniel.jarai@bartec-pixavi.com> | 2018-07-19 11:35:43 +0200 |
---|---|---|
committer | Daniel Jarai <daniel.jarai@bartec-pixavi.com> | 2018-12-14 17:56:15 +0100 |
commit | 5ef209c86344caedf23c09eb991e7434385cba96 (patch) | |
tree | c821d823b7aa4f9704aac7def12c1485f688cb2c | |
parent | feb0086cca1724004b98682ea44a5c6403e46bcc (diff) | |
download | device_google_contexthub-5ef209c86344caedf23c09eb991e7434385cba96.tar.gz device_google_contexthub-5ef209c86344caedf23c09eb991e7434385cba96.tar.bz2 device_google_contexthub-5ef209c86344caedf23c09eb991e7434385cba96.zip |
nanohub: stm32: i2c: always wait for the BTF event in the DmaTxDone ISR
This interrupt is fired when the DMA transfer completes, ie. all bytes
have been transmitted to the I2C peripheral. However, It's possible that
the I2C transfer didn't finish yet, so before touching the peripheral,
wait for the BTF (byte transfer finished) flag to be set.
This fixes the issue where the last byte of a transfer was randomly lost,
especially at higher core clock frequencies (>= 40 MHz).
Change-Id: I126e43f1e9cfdc831f61d0a0a1940367440dce55
-rw-r--r-- | firmware/os/platform/stm32/i2c.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/firmware/os/platform/stm32/i2c.c b/firmware/os/platform/stm32/i2c.c index 7ba7b7ce..8ae35cf7 100644 --- a/firmware/os/platform/stm32/i2c.c +++ b/firmware/os/platform/stm32/i2c.c @@ -543,14 +543,16 @@ static void stmI2cMasterDmaTxDone(void *cookie, uint16_t bytesLeft, int err) state->tx.offset = state->tx.size - bytesLeft; state->tx.size = 0; + stmI2cDmaDisable(pdev); + + while (!(regs->SR1 & I2C_SR1_BTF)) + ; + if (err == 0 && state->rx.size > 0) { atomicWriteByte(&state->masterState, STM_I2C_MASTER_START); stmI2cStartEnable(pdev); } else { - while (!(regs->SR1 & I2C_SR1_BTF)) - ; - stmI2cStopEnable(pdev); stmI2cMasterTxRxDone(pdev, err); } |