diff --git a/drivers/ioexpander/iso1i813t.c b/drivers/ioexpander/iso1i813t.c index 8e831c6c936..64d1d0e2b9f 100644 --- a/drivers/ioexpander/iso1i813t.c +++ b/drivers/ioexpander/iso1i813t.c @@ -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); diff --git a/include/nuttx/ioexpander/iso1i813t.h b/include/nuttx/ioexpander/iso1i813t.h index e6efd1d5c40..00e8a50bd58 100644 --- a/include/nuttx/ioexpander/iso1i813t.h +++ b/include/nuttx/ioexpander/iso1i813t.h @@ -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 */ }; /****************************************************************************