diff --git a/drivers/include/si70xx.h b/drivers/include/si70xx.h index 9d19286e0d..5fbbd6ffec 100644 --- a/drivers/include/si70xx.h +++ b/drivers/include/si70xx.h @@ -7,10 +7,19 @@ */ /** - * @defgroup drivers_si70xx Si7006/13/20/21 temperature and humidity sensors + * @defgroup drivers_si70xx Si7006/13/20/21/5x temperature and humidity sensors * @ingroup drivers_sensors * @ingroup drivers_saul - * @brief Driver for the Si7006/13/20/21 temperature and humidity sensor + * @brief Driver for the Si7006/13/20/21/5x temperature and humidity sensor + * + * The Si70xx driver supports a range of similar temperature and humidity + * sensors from Silicon Labs. + * + * The Si7006/13/20/21 sensors support both temperature and relative humidity + * reading, while the Si7050/1/3/4/5 sensors only provide a temperature reading + * varying in accuracy between +/- 0.1 C to +/- 1.0 C depending on the model. + * + * For any of the Si705x models, use the pseudo module @p si705x. * * This driver provides @ref drivers_saul capabilities. * @{ @@ -30,6 +39,17 @@ extern "C" { #endif +/** + * @brief Compile time macro telling whether the chip has a humidity sensor. + */ +#if MODULE_SI7050 || MODULE_SI7051 || MODULE_SI7053 || MODULE_SI7054 || \ + MODULE_SI7055 +/* Si705x sensors don't have a humidity sensor hardware, only temperature. */ +#define SI70XX_HAS_HUMIDITY_SENSOR 0 +#else +#define SI70XX_HAS_HUMIDITY_SENSOR 1 +#endif + /** * @brief Driver return codes */ @@ -67,13 +87,17 @@ typedef struct { */ int si70xx_init(si70xx_t *dev, const si70xx_params_t *params); +#if SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN /** * @brief Read the relative humidity from the sensor. Uses clock stretching. * + * This function is only available in models that have a humidity sensor. + * * @param[in] dev device descriptor * @return relative humidity in centi-percent (times 100) */ uint16_t si70xx_get_relative_humidity(const si70xx_t *dev); +#endif /* SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN */ /** * @brief Read the current temperature from the sensor. Uses clock stretching. @@ -84,15 +108,19 @@ uint16_t si70xx_get_relative_humidity(const si70xx_t *dev); */ int16_t si70xx_get_temperature(const si70xx_t *dev); +#if SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN /** * @brief Read the relative humidity and temperature from the sensor. Uses * clock stretching. * + * This function is only available in models that have a humidity sensor. + * * @param[in] dev device descriptor * @param[out] humidity pointer to relative humidity (in centi-percent) * @param[out] temperature pointer to temperature (in centi-degrees Celsius) */ void si70xx_get_both(const si70xx_t *dev, uint16_t *humidity, int16_t *temperature); +#endif /* SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN */ /** * @brief Read the sensor serial number. diff --git a/drivers/saul/init_devs/auto_init_si70xx.c b/drivers/saul/init_devs/auto_init_si70xx.c index 67d4c7cfc7..099eaccc96 100644 --- a/drivers/saul/init_devs/auto_init_si70xx.c +++ b/drivers/saul/init_devs/auto_init_si70xx.c @@ -29,6 +29,15 @@ */ #define SI70XX_NUM ARRAY_SIZE(si70xx_params) +/** + * @brief Define the number of SAUL registry entries + */ +#if SI70XX_HAS_HUMIDITY_SENSOR +#define SI70XX_SAUL_ENTRIES_NUM 2 +#else +#define SI70XX_SAUL_ENTRIES_NUM 1 +#endif + /** * @brief Allocation of memory for device descriptors */ @@ -37,7 +46,7 @@ static si70xx_t si70xx_devs[SI70XX_NUM]; /** * @brief Memory for the SAUL registry entries */ -static saul_reg_t saul_entries[SI70XX_NUM * 2]; +static saul_reg_t saul_entries[SI70XX_NUM * SI70XX_SAUL_ENTRIES_NUM]; /** * @brief Define the number of saul info @@ -56,6 +65,7 @@ void auto_init_si70xx(void) { assert(SI70XX_INFO_NUM == SI70XX_NUM); + unsigned entry = 0; for (unsigned i = 0; i < SI70XX_NUM; i++) { LOG_DEBUG("[auto_init_saul] initializing SI70xx #%u\n", i); @@ -65,17 +75,17 @@ void auto_init_si70xx(void) } /* temperature */ - saul_entries[i * 2].dev = &si70xx_devs[i]; - saul_entries[i * 2].name = si70xx_saul_info[i].name; - saul_entries[i * 2].driver = &si70xx_temperature_saul_driver; + saul_entries[entry].dev = &si70xx_devs[i]; + saul_entries[entry].name = si70xx_saul_info[i].name; + saul_entries[entry].driver = &si70xx_temperature_saul_driver; + saul_reg_add(&saul_entries[entry++]); +#if SI70XX_HAS_HUMIDITY_SENSOR /* relative humidity */ - saul_entries[(i * 2) + 1].dev = &si70xx_devs[i]; - saul_entries[(i * 2) + 1].name = si70xx_saul_info[i].name; - saul_entries[(i * 2) + 1].driver = \ - &si70xx_relative_humidity_saul_driver; - - saul_reg_add(&saul_entries[i * 2]); - saul_reg_add(&saul_entries[(i * 2) + 1]); + saul_entries[entry].dev = &si70xx_devs[i]; + saul_entries[entry].name = si70xx_saul_info[i].name; + saul_entries[entry].driver = &si70xx_relative_humidity_saul_driver; + saul_reg_add(&saul_entries[entry++]); +#endif /* SI70XX_HAS_HUMIDITY_SENSOR */ } } diff --git a/drivers/si70xx/include/si70xx_internals.h b/drivers/si70xx/include/si70xx_internals.h index 621ae87fbb..beefcf868b 100644 --- a/drivers/si70xx/include/si70xx_internals.h +++ b/drivers/si70xx/include/si70xx_internals.h @@ -55,15 +55,25 @@ extern "C" { * @{ */ #if defined(MODULE_SI7006) -#define SI70XX_ID (0x06) +#define SI70XX_ID (6) #elif defined(MODULE_SI7013) -#define SI70XX_ID (0x0D) +#define SI70XX_ID (13) #elif defined(MODULE_SI7020) -#define SI70XX_ID (0x14) +#define SI70XX_ID (20) #elif defined(MODULE_SI7021) -#define SI70XX_ID (0x15) +#define SI70XX_ID (21) +#elif defined(MODULE_SI7050) +#define SI70XX_ID (50) +#elif defined(MODULE_SI7051) +#define SI70XX_ID (51) +#elif defined(MODULE_SI7053) +#define SI70XX_ID (53) +#elif defined(MODULE_SI7054) +#define SI70XX_ID (54) +#elif defined(MODULE_SI7055) +#define SI70XX_ID (55) #else -#error "Please provide a valid Si70xx variant (Si7006/13/20/21)" +#error "Please provide a valid Si70xx variant (Si7006/13/20/21/5X)" #endif #define SI70XX_REVISION_1 (0xFF) diff --git a/drivers/si70xx/si70xx.c b/drivers/si70xx/si70xx.c index bc74ca39f2..0dbd830b15 100644 --- a/drivers/si70xx/si70xx.c +++ b/drivers/si70xx/si70xx.c @@ -53,10 +53,7 @@ static uint16_t _do_measure(const si70xx_t *dev, uint8_t command) return ((uint16_t)result[0] << 8) + (result[1] & 0xfc); } -/** - * @brief Internal helper function that reads the device serial number. - */ -static uint64_t _get_serial(const si70xx_t *dev) +uint64_t si70xx_get_serial(const si70xx_t *dev) { uint8_t out[2]; uint8_t in_first[8] = { 0 }; @@ -95,18 +92,12 @@ static uint64_t _get_serial(const si70xx_t *dev) return (((uint64_t) id_first) << 32) + id_second; } -/** - * @brief Internal helper function that reads the device identifier. - */ -static uint8_t _get_id(const si70xx_t *dev) +uint8_t si70xx_get_id(const si70xx_t *dev) { - return (_get_serial(dev) >> 24) & 0xff; + return (si70xx_get_serial(dev) >> 24) & 0xff; } -/** - * @brief Internal helper function that reads the device serial revision. - */ -static uint8_t _get_revision(const si70xx_t *dev) +uint8_t si70xx_get_revision(const si70xx_t *dev) { uint8_t out[2]; uint8_t in = 0; @@ -128,17 +119,19 @@ static uint8_t _get_revision(const si70xx_t *dev) static int _test_device(const si70xx_t *dev) { - uint8_t revision = _get_revision(dev); + uint8_t revision = si70xx_get_revision(dev); if (revision != SI70XX_REVISION_1 && revision != SI70XX_REVISION_2) { DEBUG("[ERROR] Bad device revision (%d).\n", revision); return -SI70XX_ERR_NODEV; } - uint8_t id = _get_id(dev); + uint8_t id = si70xx_get_id(dev); - if (id != SI70XX_ID) { - DEBUG("[ERROR] Not a valid Si7006/13/20/21 device\n"); + const bool valid_id = (id == SI70XX_ID); + if (!valid_id) { + DEBUG("[ERROR] Not a valid Si7006/13/20/21/5x device: %u\n", + (unsigned)id); return -SI70XX_ERR_NODEV;; } diff --git a/drivers/si70xx/si70xx_saul.c b/drivers/si70xx/si70xx_saul.c index 8ab680a4ce..8eafd93825 100644 --- a/drivers/si70xx/si70xx_saul.c +++ b/drivers/si70xx/si70xx_saul.c @@ -31,6 +31,7 @@ static int read_temperature(const void *dev, phydat_t *res) return 1; } +#if SI70XX_HAS_HUMIDITY_SENSOR static int read_relative_humidity(const void *dev, phydat_t *res) { res->val[0] = (int32_t) si70xx_get_relative_humidity((const si70xx_t *)dev); @@ -39,6 +40,7 @@ static int read_relative_humidity(const void *dev, phydat_t *res) return 1; } +#endif /* SI70XX_HAS_HUMIDITY_SENSOR */ const saul_driver_t si70xx_temperature_saul_driver = { .read = read_temperature, @@ -46,8 +48,10 @@ const saul_driver_t si70xx_temperature_saul_driver = { .type = SAUL_SENSE_TEMP }; +#if SI70XX_HAS_HUMIDITY_SENSOR const saul_driver_t si70xx_relative_humidity_saul_driver = { .read = read_relative_humidity, .write = saul_notsup, .type = SAUL_SENSE_HUM }; +#endif /* SI70XX_HAS_HUMIDITY_SENSOR */ diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index e2f3d8c248..0f8b37cf5d 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -262,6 +262,11 @@ PSEUDOMODULES += si7006 PSEUDOMODULES += si7013 PSEUDOMODULES += si7020 PSEUDOMODULES += si7021 +PSEUDOMODULES += si7050 +PSEUDOMODULES += si7051 +PSEUDOMODULES += si7053 +PSEUDOMODULES += si7054 +PSEUDOMODULES += si7055 #include variants of tmp00x drivers as pseudo modules PSEUDOMODULES += tmp006 diff --git a/tests/driver_si70xx/Makefile b/tests/driver_si70xx/Makefile index 862de8b58e..e80b4b1bac 100644 --- a/tests/driver_si70xx/Makefile +++ b/tests/driver_si70xx/Makefile @@ -1,6 +1,8 @@ include ../Makefile.tests_common -# This test should also work with Si7006, Si7013 and Si7020 variants. -USEMODULE += si7021 +# This test should also work with si7006, si7013, si7020 and si705x variants. +SI70XX_VARIANT ?= si7021 + +USEMODULE += $(SI70XX_VARIANT) include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_si70xx/main.c b/tests/driver_si70xx/main.c index 56c8d26333..f148401cc1 100644 --- a/tests/driver_si70xx/main.c +++ b/tests/driver_si70xx/main.c @@ -29,10 +29,10 @@ int main(void) { si70xx_t dev; - puts("SI7021 temperature and humidity sensor test application"); + puts("SI70XX temperature and humidity sensor test application"); /* initialize the sensor */ - printf("Initializing sensor... "); + puts("Initializing sensor... "); if (si70xx_init(&dev, &si70xx_params[0]) == 0) { puts("[OK]"); @@ -42,13 +42,17 @@ int main(void) return 1; } + printf("Found SI70%02d sensor, revision %d\n", si70xx_get_id(&dev), + si70xx_get_revision(&dev)); + /* read temperature and humidity every 1 seconds */ bool both = false; - int16_t temperature; - uint16_t humidity; - while (1) { + int16_t temperature; +#if SI70XX_HAS_HUMIDITY_SENSOR + uint16_t humidity; + /* rotate the way of getting the data */ if (both) { si70xx_get_both(&dev, &humidity, &temperature); @@ -57,12 +61,17 @@ int main(void) temperature = si70xx_get_temperature(&dev); humidity = si70xx_get_relative_humidity(&dev); } - +#else /* SI70XX_HAS_HUMIDITY_SENSOR */ + temperature = si70xx_get_temperature(&dev); +#endif /* SI70XX_HAS_HUMIDITY_SENSOR */ both = !both; /* display results */ +#if SI70XX_HAS_HUMIDITY_SENSOR printf("relative humidity: %d.%02d\n", humidity / 100, humidity % 100); - printf("temperature: %d.%02d C\n", temperature / 100, temperature % 100); +#endif /* SI70XX_HAS_HUMIDITY_SENSOR */ + printf("temperature: %d.%02d C\n", temperature / 100, + temperature % 100); /* sleep between measurements */ xtimer_msleep(1000);