From 7c285eb18685814af50712cd9d61a2b0c885e542 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Wed, 2 Jan 2019 16:59:53 +0100 Subject: [PATCH] drivers/lpsxxx: add support for lps22hb --- drivers/Makefile.dep | 2 +- drivers/include/lpsxxx.h | 27 ++++++++++--- drivers/lpsxxx/include/lpsxxx_internal.h | 49 +++++++++++++++++++++++- drivers/lpsxxx/include/lpsxxx_params.h | 4 +- drivers/lpsxxx/lpsxxx.c | 38 ++++++++++++++++++ drivers/lpsxxx/lpsxxx_saul.c | 2 +- makefiles/pseudomodules.inc.mk | 1 + 7 files changed, 114 insertions(+), 9 deletions(-) diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 8d784c1aa6..70aa14b905 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -268,7 +268,7 @@ ifneq (,$(filter lpd8808,$(USEMODULE))) FEATURES_REQUIRED += periph_gpio endif -ifneq (,$(filter lps331ap lps25hb,$(USEMODULE))) +ifneq (,$(filter lps331ap lps2%hb,$(USEMODULE))) USEMODULE += lpsxxx endif diff --git a/drivers/include/lpsxxx.h b/drivers/include/lpsxxx.h index 27e67e4c12..9736302e25 100644 --- a/drivers/include/lpsxxx.h +++ b/drivers/include/lpsxxx.h @@ -8,10 +8,10 @@ */ /** - * @defgroup drivers_lpsxxx LPS331AP/LPS25HB Pressure Sensors Driver + * @defgroup drivers_lpsxxx LPS331AP/LPS25HB/LPS22HB Pressure Sensors Driver * @ingroup drivers_sensors * @ingroup drivers_saul - * @brief Device driver for the LPSXXX pressure sensor family + * @brief Device driver for the LPSXXX pressure sensor family (LPS331AP/LPS25HB/LPS22HB) * * This driver provides @ref drivers_saul capabilities. * @@ -36,9 +36,12 @@ extern "C" { #include #include "periph/i2c.h" - /** - * @brief The sensors default I2C address - */ +/** + * @brief The sensors default I2C address + * + * Default address corresponds to SDO/SA0 pad connected to ground. If SDO/SA0 + * pad is connected to power supply, I2C address is 0x5C. + */ #define LPSXXX_DEFAULT_ADDRESS (0x5d) /** @@ -63,9 +66,23 @@ typedef enum { LPSXXX_RATE_7HZ = 2, /**< sample with 7Hz, default */ LPSXXX_RATE_12HZ5 = 3, /**< sample with 12.5Hz */ LPSXXX_RATE_25HZ = 4 /**< sample with 25Hz */ +#elif MODULE_LPS22HB + LPSXXX_RATE_10HZ = 2, /**< sample with 10Hz */ + LPSXXX_RATE_25HZ = 3, /**< sample with 25Hz, default */ + LPSXXX_RATE_50HZ = 4, /**< sample with 50Hz */ + LPSXXX_RATE_75HZ = 5 /**< sample with 75Hz */ #endif } lpsxxx_rate_t; +/** + * @brief The sensors default output data rate (ODR) + */ +#if MODULE_LPS331AP || MODULE_LPS25HB +#define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_7HZ) +#else /* MODULE_LPS22HB */ +#define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_25HZ) +#endif + /** * @brief Struct holding all parameters needed for device initialization */ diff --git a/drivers/lpsxxx/include/lpsxxx_internal.h b/drivers/lpsxxx/include/lpsxxx_internal.h index 038465b3f1..8aa3df662e 100644 --- a/drivers/lpsxxx/include/lpsxxx_internal.h +++ b/drivers/lpsxxx/include/lpsxxx_internal.h @@ -121,7 +121,54 @@ extern "C" { */ #define LPSXXX_WHO_AM_I (0xbd) -#endif /* MODULE_LPS25HB */ +#elif MODULE_LPS22HB + +/** + * @name LPS22HB registers + * @{ + */ +#define LPSXXX_REG_INT_CFG (0x0b) +#define LPSXXX_REG_THS_P_L (0x0c) +#define LPSXXX_REG_THS_P_H (0x0d) +#define LPSXXX_REG_REF_P_XL (0x15) +#define LPSXXX_REG_RES_CONF (0x1a) +#define LPSXXX_REG_CTRL_REG1 (0x10) +#define LPSXXX_REG_CTRL_REG2 (0x11) +#define LPSXXX_REG_CTRL_REG3 (0x13) +#define LPSXXX_REG_FIFO_CTRL (0x2e) +#define LPSXXX_REG_REF_P_XL (0x15) +#define LPSXXX_REG_REF_P_L (0x16) +#define LPSXXX_REG_REF_P_H (0x17) +#define LPSXXX_REG_RPDS_L (0x18) +#define LPSXXX_REG_RPDS_H (0x19) +#define LPSXXX_REG_RES_CONF (0x1a) +#define LPSXXX_REG_INT_SOURCE (0x25) +#define LPSXXX_REG_FIFO_STATUS (0x26) +#define LPSXXX_REG_LPFP_RES (0x33) +/** @} */ + +/** + * @name LPS22HB CTRL_REG1 bitfields + * @{ + */ +#define LPSXXX_CTRL_REG1_EN_LPFP (0x08) +#define LPSXXX_CTRL_REG1_LPFP_CFG (0x04) +#define LPSXXX_CTRL_REG1_BDU (0x02) +/** @} */ + +/** + * @name LPS22HB CTRL_REG2 bitfields + * @{ + */ +#define LPSXXX_CTRL_REG2_ID_ADD_INC (0x10) +/** @} */ + +/** + * @brief LPS22HB WHO_AM_I register value + */ +#define LPSXXX_WHO_AM_I (0xb1) + +#endif /* MODULE_LPS22HB */ #ifdef __cplusplus } diff --git a/drivers/lpsxxx/include/lpsxxx_params.h b/drivers/lpsxxx/include/lpsxxx_params.h index 665597fbf5..3c3f3fe4e2 100644 --- a/drivers/lpsxxx/include/lpsxxx_params.h +++ b/drivers/lpsxxx/include/lpsxxx_params.h @@ -40,7 +40,7 @@ extern "C" { #define LPSXXX_PARAM_ADDR (LPSXXX_DEFAULT_ADDRESS) #endif #ifndef LPSXXX_PARAM_RATE -#define LPSXXX_PARAM_RATE (LPSXXX_RATE_7HZ) +#define LPSXXX_PARAM_RATE (LPSXXX_DEFAULT_RATE) #endif #ifndef LPSXXX_PARAMS @@ -53,6 +53,8 @@ extern "C" { #define LPSXXX_SAUL_NAME "lps331ap" #elif MODULE_LPS25HB #define LPSXXX_SAUL_NAME "lps25hb" +#elif MODULE_LPS22HB +#define LPSXXX_SAUL_NAME "lps22hb" #endif #ifndef LPSXXX_SAUL_INFO #define LPSXXX_SAUL_INFO { .name = LPSXXX_SAUL_NAME } diff --git a/drivers/lpsxxx/lpsxxx.c b/drivers/lpsxxx/lpsxxx.c index f05837c334..d40f70ef2a 100644 --- a/drivers/lpsxxx/lpsxxx.c +++ b/drivers/lpsxxx/lpsxxx.c @@ -42,8 +42,13 @@ /** * @brief temperature base value and divider for norming temperature output */ +#if MODULE_LPS331AP || MODULE_LPS25HB #define TEMP_BASE (42.5f) #define TEMP_DIVIDER (480U) +#else +#define TEMP_BASE (0.0f) +#define TEMP_DIVIDER (100U) +#endif #define DEV_I2C (dev->params.i2c) #define DEV_ADDR (dev->params.addr) @@ -71,6 +76,26 @@ int lpsxxx_init(lpsxxx_t *dev, const lpsxxx_params_t * params) uint8_t tmp; +#if MODULE_LPS22HB + if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG2, &tmp, 0) < 0) { + i2c_release(DEV_I2C); + DEBUG("[lpsxxx] init: cannot read LPSXXX_REG_CTRL_REG2 register\n"); + return -LPSXXX_ERR_I2C; + } + + /* Disable automatic increment of register address during byte access + (recommanded in datasheet (section 9.6 CTRL_REG2) */ + tmp &= ~LPSXXX_CTRL_REG2_ID_ADD_INC; + + DEBUG("[lpsxxx] init: update reg2, %02X\n", tmp); + + if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG2, tmp, 0) < 0) { + i2c_release(DEV_I2C); + DEBUG("[lpsxxx] init: cannot write in CTRL_REG2 register\n"); + return -LPSXXX_ERR_I2C; + } +#endif + /* configure device, for simple operation only CTRL_REG1 needs to be touched */ #if MODULE_LPS331AP tmp = LPSXXX_CTRL_REG1_DBDU | LPSXXX_CTRL_REG1_PD | @@ -78,6 +103,9 @@ int lpsxxx_init(lpsxxx_t *dev, const lpsxxx_params_t * params) #elif MODULE_LPS25HB tmp = LPSXXX_CTRL_REG1_BDU | LPSXXX_CTRL_REG1_PD | (DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS); +#elif MODULE_LPS22HB + tmp = LPSXXX_CTRL_REG1_EN_LPFP | /* Low-pass filter configuration: ODR/9 */ + LPSXXX_CTRL_REG1_BDU | (DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS); #endif DEBUG("[lpsxxx] init: update reg1, value: %02X\n", tmp); @@ -179,7 +207,13 @@ int lpsxxx_enable(const lpsxxx_t *dev) DEBUG("[lpsxxx] enable: cannot read CTRL_REG1 register\n"); return -LPSXXX_ERR_I2C; } +#if MODULE_LPS331AP || MODULE_LPS25HB tmp |= LPSXXX_CTRL_REG1_PD; +#else + tmp |= LPSXXX_CTRL_REG1_EN_LPFP | /* Low-pass filter configuration: ODR/9 */ + LPSXXX_CTRL_REG1_BDU | (DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS); +#endif + DEBUG("[lpsxxx] enable: update reg1 with %02X\n", tmp); @@ -203,7 +237,11 @@ int lpsxxx_disable(const lpsxxx_t *dev) DEBUG("[lpsxxx] disable: cannot read CTRL_REG1 register\n"); return -LPSXXX_ERR_I2C; } +#if MODULE_LPS331AP || MODULE_LPS25HB + tmp &= ~LPSXXX_CTRL_REG1_PD; +#else tmp &= ~(7 << LPSXXX_CTRL_REG1_ODR_POS); +#endif DEBUG("[lpsxxx] disable: update reg1 with %02X\n", tmp); diff --git a/drivers/lpsxxx/lpsxxx_saul.c b/drivers/lpsxxx/lpsxxx_saul.c index 67e406899d..30d200e14d 100644 --- a/drivers/lpsxxx/lpsxxx_saul.c +++ b/drivers/lpsxxx/lpsxxx_saul.c @@ -12,7 +12,7 @@ * @{ * * @file - * @brief LPSXXX (LPS331ap/LPS25HB) adaption to SAUL interface + * @brief LPSXXX (LPS331ap/LPS25HB/LPS22HB) adaption to SAUL interface * * @author Hauke Petersen * @author Alexandre Abadie diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 283a222f8d..cb1840de24 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -120,6 +120,7 @@ PSEUDOMODULES += vcnl4040 # include variants of lpsxxx drivers as pseudo modules PSEUDOMODULES += lps331ap +PSEUDOMODULES += lps22hb PSEUDOMODULES += lps25hb # add all pseudo random number generator variants as pseudomodules