ioexpander/iso1i813t: add option to check errors during read

This commit adds the possibility to check for expander errors when
reading the data. This is optional if glerr_check or interr_check
fields in configuration are not zero.

If not zero, read operation also reads ISO1I813T_GLERR and
ISO1I813T_INTERR register and returns error if there is some error.
The user can control which errors he wants to check with
glerr_check and interr_check masks.

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
This commit is contained in:
Michal Lenc
2026-03-18 14:11:05 +01:00
committed by Alan C. Assis
parent cacfb7ebda
commit 600d0e413a
2 changed files with 93 additions and 13 deletions

View File

@@ -302,7 +302,8 @@ static int iso1i813t_readpin(FAR struct ioexpander_dev_s *dev, uint8_t pin,
FAR bool *value)
{
FAR struct iso1i813t_dev_s *priv = (FAR struct iso1i813t_dev_s *)dev;
uint8_t buff;
uint8_t txbuff[2];
uint8_t rxbuff[2];
int ret;
if (pin > 7)
@@ -322,13 +323,48 @@ static int iso1i813t_readpin(FAR struct ioexpander_dev_s *dev, uint8_t pin,
return ret;
}
iso1i813t_select(priv->spi, priv->config, 8);
SPI_RECVBLOCK(priv->spi, &buff, 1);
iso1i813t_deselect(priv->spi, priv->config);
if (priv->config->glerr_check == 0 && priv->config->interr_check == 0)
{
iso1i813t_select(priv->spi, priv->config, 8);
SPI_RECVBLOCK(priv->spi, rxbuff, 1);
iso1i813t_deselect(priv->spi, priv->config);
}
else
{
if (priv->config->glerr_check != 0)
{
txbuff[0] = ISO1I813T_GLERR;
txbuff[1] = 0;
iso1i813t_select(priv->spi, priv->config, 8);
SPI_EXCHANGE(priv->spi, txbuff, rxbuff, 2);
iso1i813t_deselect(priv->spi, priv->config);
if ((rxbuff[1] & priv->config->glerr_check) != 0)
{
gpioerr("ERROR: Global Error Register is 0x%x\n", rxbuff[1]);
nxmutex_unlock(&priv->lock);
return -EIO;
}
}
if (priv->config->interr_check != 0)
{
txbuff[0] = ISO1I813T_INTERR;
txbuff[1] = 0;
iso1i813t_select(priv->spi, priv->config, 8);
SPI_EXCHANGE(priv->spi, txbuff, rxbuff, 2);
iso1i813t_deselect(priv->spi, priv->config);
if ((rxbuff[1] & priv->config->interr_check) != 0)
{
gpioerr("ERROR: Internal Error Register is 0x%x\n", rxbuff[1]);
nxmutex_unlock(&priv->lock);
return -EIO;
}
}
}
nxmutex_unlock(&priv->lock);
*value = (bool)((buff >> (pin & 0x7)) & 1);
*value = (bool)((rxbuff[0] >> (pin & 0x7)) & 1);
return ret;
}
@@ -381,7 +417,8 @@ static int iso1i813t_multireadpin(FAR struct ioexpander_dev_s *dev,
int count)
{
FAR struct iso1i813t_dev_s *priv = (FAR struct iso1i813t_dev_s *)dev;
uint8_t buff;
uint8_t txbuff[2];
uint8_t rxbuff[2];
int pin;
int i;
int ret;
@@ -394,9 +431,44 @@ static int iso1i813t_multireadpin(FAR struct ioexpander_dev_s *dev,
return ret;
}
iso1i813t_select(priv->spi, priv->config, 8);
SPI_RECVBLOCK(priv->spi, &buff, 1);
iso1i813t_deselect(priv->spi, priv->config);
if (priv->config->glerr_check == 0 && priv->config->interr_check == 0)
{
iso1i813t_select(priv->spi, priv->config, 8);
SPI_RECVBLOCK(priv->spi, rxbuff, 1);
iso1i813t_deselect(priv->spi, priv->config);
}
else
{
if (priv->config->glerr_check != 0)
{
txbuff[0] = ISO1I813T_GLERR;
txbuff[1] = 0;
iso1i813t_select(priv->spi, priv->config, 8);
SPI_EXCHANGE(priv->spi, txbuff, rxbuff, 2);
iso1i813t_deselect(priv->spi, priv->config);
if ((rxbuff[1] & priv->config->glerr_check) != 0)
{
gpioerr("ERROR: Global Error Register is 0x%x\n", rxbuff[1]);
nxmutex_unlock(&priv->lock);
return -EIO;
}
}
if (priv->config->interr_check != 0)
{
txbuff[0] = ISO1I813T_INTERR;
txbuff[1] = 0;
iso1i813t_select(priv->spi, priv->config, 8);
SPI_EXCHANGE(priv->spi, txbuff, rxbuff, 2);
iso1i813t_deselect(priv->spi, priv->config);
if ((rxbuff[1] & priv->config->interr_check) != 0)
{
gpioerr("ERROR: Internal Error Register is 0x%x\n", rxbuff[1]);
nxmutex_unlock(&priv->lock);
return -EIO;
}
}
}
for (i = 0; i < count; i++)
{
@@ -407,7 +479,7 @@ static int iso1i813t_multireadpin(FAR struct ioexpander_dev_s *dev,
return -ENXIO;
}
values[i] = (bool)((buff >> (pin & 0x7)) & 1);
values[i] = (bool)((rxbuff[0] >> (pin & 0x7)) & 1);
}
nxmutex_unlock(&priv->lock);

View File

@@ -49,9 +49,17 @@ struct iso1i813t_config_s
{
/* Device characterization */
uint8_t id; /* ID if multiple devices used to select correct CS */
uint8_t mode; /* SPI mode */
uint32_t frequency; /* SPI frequency */
uint8_t id; /* ID if multiple devices used to select correct CS */
uint8_t mode; /* SPI mode */
uint8_t glerr_check; /* Bits that are check in global error register
* during read - read operation fails if these are
* not zero.
*/
uint8_t interr_check; /* Bits that are check in internal error register
* during read - read operation fails if these are
* not zero.
*/
uint32_t frequency; /* SPI frequency */
};
/****************************************************************************