From 148ff32a423e4ed31abd431c6201d6c1b0c54f67 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Fri, 12 May 2017 11:57:26 +0200 Subject: [PATCH 1/2] saul: include errno.h from saul.h --- drivers/include/saul.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/include/saul.h b/drivers/include/saul.h index 1e2bb18ee4..bb7cffb378 100644 --- a/drivers/include/saul.h +++ b/drivers/include/saul.h @@ -45,6 +45,7 @@ #define SAUL_H #include +#include #include "phydat.h" From 48f2a9226271315de4e25ce5c4c7750658533143 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Fri, 12 May 2017 11:57:43 +0200 Subject: [PATCH 2/2] drivers/hdc1000: (re)add error checks for I2C acces --- drivers/hdc1000/hdc1000.c | 43 ++++++++++++++++++++++------------ drivers/hdc1000/hdc1000_saul.c | 8 +++++-- drivers/include/hdc1000.h | 22 ++++++++++++----- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/drivers/hdc1000/hdc1000.c b/drivers/hdc1000/hdc1000.c index c4c2f277c9..e0eae26a78 100644 --- a/drivers/hdc1000/hdc1000.c +++ b/drivers/hdc1000/hdc1000.c @@ -76,8 +76,9 @@ int hdc1000_init(hdc1000_t *dev, const hdc1000_params_t *params) return HDC1000_OK; } -void hdc1000_trigger_conversion(hdc1000_t *dev) +int hdc1000_trigger_conversion(hdc1000_t *dev) { + int status = HDC1000_OK; assert(dev); i2c_acquire(dev->p.i2c); @@ -86,36 +87,48 @@ void hdc1000_trigger_conversion(hdc1000_t *dev) * to the address 0x00 (HDC1000_TEMPERATURE). * Conversion Time is 6.50ms for each value for 14 bit resolution. */ - i2c_write_byte(dev->p.i2c, dev->p.addr, HDC1000_TEMPERATURE); + if (i2c_write_byte(dev->p.i2c, dev->p.addr, HDC1000_TEMPERATURE) != 1) { + status = HDC1000_BUSERR; + } i2c_release(dev->p.i2c); + return status; } -void hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum) +int hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum) { + int status = HDC1000_OK; assert(dev); uint8_t buf[4]; /* first we read the RAW results from the device */ i2c_acquire(dev->p.i2c); - i2c_read_bytes(dev->p.i2c, dev->p.addr, buf, 4); + if (i2c_read_bytes(dev->p.i2c, dev->p.addr, buf, 4) != 4) { + status = HDC1000_BUSERR; + } i2c_release(dev->p.i2c); - /* and finally we convert the values to their physical representation */ - if (temp) { - uint16_t traw = ((uint16_t)buf[0] << 8) | buf[1]; - *temp = (int16_t)((((int32_t)traw * 16500) >> 16) - 4000); - } - if (hum) { - uint16_t hraw = ((uint16_t)buf[2] << 8) | buf[3]; - *hum = (int16_t)(((int32_t)hraw * 10000) >> 16); + if (status == HDC1000_OK) { + /* if all ok, we convert the values to their physical representation */ + if (temp) { + uint16_t traw = ((uint16_t)buf[0] << 8) | buf[1]; + *temp = (int16_t)((((int32_t)traw * 16500) >> 16) - 4000); + } + if (hum) { + uint16_t hraw = ((uint16_t)buf[2] << 8) | buf[3]; + *hum = (int16_t)(((int32_t)hraw * 10000) >> 16); + } } + + return status; } -void hdc1000_read(hdc1000_t *dev, int16_t *temp, int16_t *hum) +int hdc1000_read(hdc1000_t *dev, int16_t *temp, int16_t *hum) { - hdc1000_trigger_conversion(dev); + if (hdc1000_trigger_conversion(dev) != HDC1000_OK) { + return HDC1000_BUSERR; + } xtimer_usleep(HDC1000_CONVERSION_TIME); - hdc1000_get_results(dev, temp, hum); + return hdc1000_get_results(dev, temp, hum); } diff --git a/drivers/hdc1000/hdc1000_saul.c b/drivers/hdc1000/hdc1000_saul.c index 691b464d4d..691408fd80 100644 --- a/drivers/hdc1000/hdc1000_saul.c +++ b/drivers/hdc1000/hdc1000_saul.c @@ -27,7 +27,9 @@ static int read_temp(void *dev, phydat_t *res) { hdc1000_t *d = (hdc1000_t *)dev; - hdc1000_read(d, &(res->val[0]), NULL); + if (hdc1000_read(d, &(res->val[0]), NULL) != HDC1000_OK) { + return -ECANCELED; + } memset(&(res->val[1]), 0, 2 * sizeof(int16_t)); res->unit = UNIT_TEMP_C; res->scale = -2; @@ -39,7 +41,9 @@ static int read_hum(void *dev, phydat_t *res) { hdc1000_t *d = (hdc1000_t *)dev; - hdc1000_read(d, NULL, &(res->val[0])); + if (hdc1000_read(d, NULL, &(res->val[0])) != HDC1000_OK) { + return -ECANCELED; + } memset(&(res->val[1]), 0, 2 * sizeof(int16_t)); res->unit = UNIT_PERCENT; res->scale = -2; diff --git a/drivers/include/hdc1000.h b/drivers/include/hdc1000.h index e912ea2d06..61af2fe1d4 100644 --- a/drivers/include/hdc1000.h +++ b/drivers/include/hdc1000.h @@ -70,9 +70,10 @@ extern "C" * @brief HDC1000 specific return values */ enum { - HDC1000_OK = 0, /**< everything went as expected */ - HDC1000_NODEV = -1, /**< no HDC1000 device found on the bus */ - HDC1000_NOBUS = -2, /**< errors while initializing the I2C bus */ + HDC1000_OK = 0, /**< everything went as expected */ + HDC1000_NODEV = -1, /**< no HDC1000 device found on the bus */ + HDC1000_NOBUS = -2, /**< errors while initializing the I2C bus */ + HDC1000_BUSERR = -3 /**< error during I2C communication */ }; /** @@ -119,8 +120,11 @@ int hdc1000_init(hdc1000_t *dev, const hdc1000_params_t *params); * @ref hdc1000_get_results(). * * @param[in] dev device descriptor of sensor + * + * @return HDC1000_OK on success + * @return HDC1000_BUSERR on I2C communication failures */ -void hdc1000_trigger_conversion(hdc1000_t *dev); +int hdc1000_trigger_conversion(hdc1000_t *dev); /** * @brief Read conversion results for temperature and humidity @@ -128,8 +132,11 @@ void hdc1000_trigger_conversion(hdc1000_t *dev); * @param[in] dev device descriptor of sensor * @param[out] temp temperature [in 100 * degree centigrade] * @param[out] hum humidity [in 100 * percent relative] + * + * @return HDC1000_OK on success + * @return HDC1000_BUSERR on I2C communication failures */ -void hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum); +int hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum); /** * @brief Convenience function for reading temperature and humidity @@ -140,8 +147,11 @@ void hdc1000_get_results(hdc1000_t *dev, int16_t *temp, int16_t *hum); * @param[in] dev device descriptor of sensor * @param[out] temp temperature [in 100 * degree centigrade] * @param[out] hum humidity [in 100 * percent relative] + * + * @return HDC1000_OK on success + * @return HDC1000_BUSERR on I2C communication failures */ -void hdc1000_read(hdc1000_t *dev, int16_t *temp, int16_t *hum); +int hdc1000_read(hdc1000_t *dev, int16_t *temp, int16_t *hum); #ifdef __cplusplus }