mirror of
https://github.com/apache/nuttx.git
synced 2026-03-23 04:43:16 +08:00
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:
committed by
Alan C. Assis
parent
cacfb7ebda
commit
600d0e413a
@@ -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;
|
||||
}
|
||||
|
||||
if (priv->config->glerr_check == 0 && priv->config->interr_check == 0)
|
||||
{
|
||||
iso1i813t_select(priv->spi, priv->config, 8);
|
||||
SPI_RECVBLOCK(priv->spi, &buff, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
if (priv->config->glerr_check == 0 && priv->config->interr_check == 0)
|
||||
{
|
||||
iso1i813t_select(priv->spi, priv->config, 8);
|
||||
SPI_RECVBLOCK(priv->spi, &buff, 1);
|
||||
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);
|
||||
|
||||
@@ -51,6 +51,14 @@ struct iso1i813t_config_s
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user