arch/{nrf52|nrf53|nrf91}: handle I2C errors in interrupt mode

This commit is contained in:
raiden00pl 2023-08-14 08:55:01 +02:00 committed by Xiang Xiao
parent d18988521f
commit b73e1b9591
3 changed files with 61 additions and 49 deletions

View File

@ -41,14 +41,6 @@
#include "hardware/nrf52_twi.h"
#include "hardware/nrf52_utils.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* I2C errors not functional yet */
#undef CONFIG_NRF52_I2C_ERRORS
/****************************************************************************
* Private Types
****************************************************************************/
@ -412,6 +404,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -464,6 +457,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -511,6 +505,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -560,6 +555,7 @@ static int nrf52_i2c_reset(struct i2c_master_s *dev)
static int nrf52_i2c_isr(int irq, void *context, void *arg)
{
struct nrf52_i2c_priv_s *priv = (struct nrf52_i2c_priv_s *)arg;
uint32_t regval = 0;
/* Reset I2C status */
@ -613,14 +609,26 @@ static int nrf52_i2c_isr(int irq, void *context, void *arg)
nrf52_i2c_putreg(priv, NRF52_TWIM_EVENTS_STOPPED_OFFSET, 0);
}
#ifdef CONFIG_NRF52_I2C_ERRORS
if (nrf52_i2c_getreg(priv, NRF52_TWIM_EVENTS_ERROR_OFFSET) == 1)
{
i2cerr("I2C ERROR\n");
regval = nrf52_i2c_getreg(priv, NRF52_TWIM_ERRORSRC_OFFSET) & 0x7;
i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
/* Set ERROR status */
priv->status = ERROR;
if (regval & TWIM_ERRORSRC_OVERRUN)
{
/* Overrun error */
priv->status = -EIO;
}
else
{
/* NACK */
priv->status = -ENXIO;
}
/* ERROR event */
@ -629,8 +637,8 @@ static int nrf52_i2c_isr(int irq, void *context, void *arg)
/* Clear event */
nrf52_i2c_putreg(priv, NRF52_TWIM_EVENTS_ERROR_OFFSET, 0);
nrf52_i2c_putreg(priv, NRF52_TWIM_ERRORSRC_OFFSET, 0x7);
}
#endif
return OK;
}
@ -684,12 +692,8 @@ static int nrf52_i2c_init(struct nrf52_i2c_priv_s *priv)
#ifndef CONFIG_I2C_POLLED
/* Enable I2C interrupts */
#ifdef CONFIG_NRF52_I2C_ERRORS
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
TWIM_INT_ERROR);
#else
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
#endif
nrf52_i2c_putreg(priv, NRF52_TWIM_INTEN_OFFSET, regval);
/* Attach error and event interrupts to the ISRs */

View File

@ -41,14 +41,6 @@
#include "hardware/nrf53_twi.h"
#include "hardware/nrf53_utils.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* I2C errors not functional yet */
#undef CONFIG_NRF53_I2C_ERRORS
/****************************************************************************
* Private Types
****************************************************************************/
@ -462,6 +454,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -514,6 +507,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -561,6 +555,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -609,7 +604,8 @@ static int nrf53_i2c_reset(struct i2c_master_s *dev)
#ifndef CONFIG_I2C_POLLED
static int nrf53_i2c_isr(int irq, void *context, void *arg)
{
struct nrf53_i2c_priv_s *priv = (struct nrf53_i2c_priv_s *)arg;
struct nrf53_i2c_priv_s *priv = (struct nrf53_i2c_priv_s *)arg;
uint32_t regval = 0;
/* Reset I2C status */
@ -663,14 +659,26 @@ static int nrf53_i2c_isr(int irq, void *context, void *arg)
nrf53_i2c_putreg(priv, NRF53_TWIM_EVENTS_STOPPED_OFFSET, 0);
}
#ifdef CONFIG_NRF53_I2C_ERRORS
if (nrf53_i2c_getreg(priv, NRF53_TWIM_EVENTS_ERROR_OFFSET) == 1)
{
i2cerr("I2C ERROR\n");
regval = nrf53_i2c_getreg(priv, NRF53_TWIM_ERRORSRC_OFFSET) & 0x7;
i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
/* Set ERROR status */
priv->status = ERROR;
if (regval & TWIM_ERRORSRC_OVERRUN)
{
/* Overrun error */
priv->status = -EIO;
}
else
{
/* NACK */
priv->status = -ENXIO;
}
/* ERROR event */
@ -679,8 +687,8 @@ static int nrf53_i2c_isr(int irq, void *context, void *arg)
/* Clear event */
nrf53_i2c_putreg(priv, NRF53_TWIM_EVENTS_ERROR_OFFSET, 0);
nrf53_i2c_putreg(priv, NRF53_TWIM_ERRORSRC_OFFSET, 0x7);
}
#endif
return OK;
}
@ -734,12 +742,8 @@ static int nrf53_i2c_init(struct nrf53_i2c_priv_s *priv)
#ifndef CONFIG_I2C_POLLED
/* Enable I2C interrupts */
#ifdef CONFIG_NRF53_I2C_ERRORS
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
TWIM_INT_ERROR);
#else
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
#endif
nrf53_i2c_putreg(priv, NRF53_TWIM_INTEN_OFFSET, regval);
/* Attach error and event interrupts to the ISRs */

View File

@ -41,14 +41,6 @@
#include "hardware/nrf91_twi.h"
#include "hardware/nrf91_utils.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* I2C errors not functional yet */
#undef CONFIG_NRF91_I2C_ERRORS
/****************************************************************************
* Private Types
****************************************************************************/
@ -462,6 +454,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -514,6 +507,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -561,6 +555,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
if (priv->status < 0)
{
ret = priv->status;
goto errout;
}
#endif
@ -610,6 +605,7 @@ static int nrf91_i2c_reset(struct i2c_master_s *dev)
static int nrf91_i2c_isr(int irq, void *context, void *arg)
{
struct nrf91_i2c_priv_s *priv = (struct nrf91_i2c_priv_s *)arg;
uint32_t regval = 0;
/* Reset I2C status */
@ -663,14 +659,26 @@ static int nrf91_i2c_isr(int irq, void *context, void *arg)
nrf91_i2c_putreg(priv, NRF91_TWIM_EVENTS_STOPPED_OFFSET, 0);
}
#ifdef CONFIG_NRF91_I2C_ERRORS
if (nrf91_i2c_getreg(priv, NRF91_TWIM_EVENTS_ERROR_OFFSET) == 1)
{
i2cerr("I2C ERROR\n");
regval = nrf91_i2c_getreg(priv, NRF91_TWIM_ERRORSRC_OFFSET) & 0x7;
i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
/* Set ERROR status */
priv->status = ERROR;
if (regval & TWIM_ERRORSRC_OVERRUN)
{
/* Overrun error */
priv->status = -EIO;
}
else
{
/* NACK */
priv->status = -ENXIO;
}
/* ERROR event */
@ -679,8 +687,8 @@ static int nrf91_i2c_isr(int irq, void *context, void *arg)
/* Clear event */
nrf91_i2c_putreg(priv, NRF91_TWIM_EVENTS_ERROR_OFFSET, 0);
nrf91_i2c_putreg(priv, NRF91_TWIM_ERRORSRC_OFFSET, 0x7);
}
#endif
return OK;
}
@ -734,12 +742,8 @@ static int nrf91_i2c_init(struct nrf91_i2c_priv_s *priv)
#ifndef CONFIG_I2C_POLLED
/* Enable I2C interrupts */
#ifdef CONFIG_NRF91_I2C_ERRORS
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
TWIM_INT_ERROR);
#else
regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
#endif
nrf91_i2c_putreg(priv, NRF91_TWIM_INTEN_OFFSET, regval);
/* Attach error and event interrupts to the ISRs */