From bbf16b27d9b5d185837140102f355a2fa00c71d8 Mon Sep 17 00:00:00 2001 From: Brennan Ashton Date: Tue, 15 Sep 2020 22:57:45 -0700 Subject: [PATCH] nRF52: Add basic error handling for i2c in polling mode There was no error handling before and it would block on common cases like NACK which meant that you could not use the i2ctool to perform a scan of the bus. This does not handle the interrupt flow which also has incomplete error handling. --- arch/arm/src/nrf52/nrf52_i2c.c | 61 +++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/nrf52/nrf52_i2c.c b/arch/arm/src/nrf52/nrf52_i2c.c index 29ee5d608d0..6cf954ede48 100644 --- a/arch/arm/src/nrf52/nrf52_i2c.c +++ b/arch/arm/src/nrf52/nrf52_i2c.c @@ -325,6 +325,25 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev, #ifdef CONFIG_I2C_POLLED while (nrf52_i2c_getreg(priv, NRF52_TWIM_EVENTS_LASTTX_OFFSET) != 1); + while (1) + { + regval = nrf52_i2c_getreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET) & 0x7; + if (regval != 0) + { + i2cerr("Error SRC: %x\n", regval); + ret = -1; + nrf52_i2c_putreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET, 0x7); + goto errout; + } + + if (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_LASTTX_OFFSET) == 1) + { + break; + } + } /* Clear event */ @@ -357,8 +376,25 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev, /* Wait for last RX done */ #ifdef CONFIG_I2C_POLLED - while (nrf52_i2c_getreg(priv, - NRF52_TWIM_EVENTS_LASTRX_OFFSET) != 1); + while (1) + { + regval = nrf52_i2c_getreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET) & 0x7; + if (regval != 0) + { + i2cerr("Error SRC: %x\n", regval); + ret = -1; + nrf52_i2c_putreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET, 0x7); + goto errout; + } + + if (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_LASTRX_OFFSET) == 1) + { + break; + } + } /* Clear event */ @@ -387,8 +423,25 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev, /* Wait for stop event */ #ifdef CONFIG_I2C_POLLED - while (nrf52_i2c_getreg(priv, - NRF52_TWIM_EVENTS_STOPPED_OFFSET) != 1); + while (1) + { + regval = nrf52_i2c_getreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET) & 0x7; + if (regval != 0) + { + i2cerr("Error SRC: %x\n", regval); + ret = -1; + nrf52_i2c_putreg(priv, + NRF52_TWIM_ERRORSRC_OFFSET, 0x7); + goto errout; + } + + if (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_STOPPED_OFFSET) == 1) + { + break; + } + } /* Clear event */