From c614b182268517ea826629838a4f59a05b8eb6e3 Mon Sep 17 00:00:00 2001 From: Rocco Marco Guglielmi Date: Tue, 27 Sep 2016 21:28:26 +0000 Subject: [PATCH] Improved LPS25H driver and related demo: added multiple register read/write. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9810 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ex/ST/lps25h.c | 180 +++++++++++--------- os/ex/ST/lps25h.h | 57 +++---- testhal/STM32/STM32F4xx/I2C-LPS25H/Makefile | 2 +- testhal/STM32/STM32F4xx/I2C-LPS25H/main.c | 4 +- 4 files changed, 128 insertions(+), 115 deletions(-) diff --git a/os/ex/ST/lps25h.c b/os/ex/ST/lps25h.c index 89de543bc..47832500d 100644 --- a/os/ex/ST/lps25h.c +++ b/os/ex/ST/lps25h.c @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ /** @@ -50,21 +50,22 @@ * @brief Reads registers value using I2C. * @pre The I2C interface must be initialized and the driver started. * - * @param[in] i2cp pointer to the I2C interface - * @param[in] sad slave address without R bit - * @param[in] reg first sub-register address - * @return the read value. + * @param[in] i2cp pointer to the I2C interface + * @param[in] sad slave address without R bit + * @param[in] reg first sub-register address + * @param[out] rxbuf pointer to an output buffer + * @param[in] n number of consecutive register to read + * @return the operation status. + * @notapi */ -uint8_t lps25hI2CReadRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg, - msg_t* msgp) { - msg_t msg; - uint8_t rxbuf; - msg = i2cMasterTransmitTimeout(i2cp, sad, ®, 1, &rxbuf, 1, - TIME_INFINITE); - if(msgp != NULL){ - *msgp = msg; - } - return rxbuf; +msg_t lps25hI2CReadRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg, + uint8_t* rxbuf, size_t n) { + uint8_t txbuf = reg; + if(n > 1) + txbuf |= LPS25H_SUB_MS; + + return i2cMasterTransmitTimeout(i2cp, sad, &txbuf, 1, rxbuf, n, + TIME_INFINITE); } /** @@ -73,16 +74,19 @@ uint8_t lps25hI2CReadRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg, * * @param[in] i2cp pointer to the I2C interface * @param[in] sad slave address without R bit - * @param[in] sub sub-register address - * @param[in] value the value to be written + * @param[in] txbuf buffer containing sub-address value in first position + * and values to write + * @param[in] n size of txbuf less one (not considering the first + * element) + * @return the operation status. + * @notapi * @return the operation status. */ -msg_t lps25hI2CWriteRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg, - uint8_t value) { - uint8_t txbuf[2]; - txbuf[0] = reg; - txbuf[1] = value; - return i2cMasterTransmitTimeout(i2cp, sad, txbuf, 2, NULL, 0, TIME_INFINITE); +msg_t lps25hI2CWriteRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t* txbuf, size_t n) { + if (n > 1) + (*txbuf) |= LPS25H_SUB_MS; + return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0, + TIME_INFINITE); } #endif /* LPS25H_USE_I2C */ @@ -96,8 +100,11 @@ static size_t get_axes_number(void *ip) { } static msg_t read_raw(void *ip, int32_t* axis) { - int32_t tmp; + uint8_t buff[3]; msg_t msg = MSG_OK; + + *axis = 0; + osalDbgCheck((ip != NULL) && (axis != NULL)); osalDbgAssert((((LPS25HDriver *)ip)->state == LPS25H_READY), "read_raw(), invalid state"); @@ -110,31 +117,22 @@ static msg_t read_raw(void *ip, int32_t* axis) { i2cStart(((LPS25HDriver *)ip)->config->i2cp, ((LPS25HDriver *)ip)->config->i2ccfg); #endif /* LPS25H_SHARED_I2C */ - tmp = lps25hI2CReadRegister(((LPS25HDriver *)ip)->config->i2cp, - ((LPS25HDriver *)ip)->config->slaveaddress, - LPS25H_AD_PRESS_OUT_XL, NULL); - if (msg != MSG_OK) - return msg; - tmp += lps25hI2CReadRegister(((LPS25HDriver *)ip)->config->i2cp, - ((LPS25HDriver *)ip)->config->slaveaddress, - LPS25H_AD_PRESS_OUT_L, NULL) << 8; - if (msg != MSG_OK) - return msg; - tmp += lps25hI2CReadRegister(((LPS25HDriver *)ip)->config->i2cp, - ((LPS25HDriver *)ip)->config->slaveaddress, - LPS25H_AD_PRESS_OUT_H, NULL) << 16; - if (msg != MSG_OK) - return msg; - *axis = (int32_t)tmp; - + msg = lps25hI2CReadRegister(((LPS25HDriver *)ip)->config->i2cp, + ((LPS25HDriver *)ip)->config->slaveaddress, + LPS25H_AD_PRESS_OUT_XL, buff, 3); + #if LPS25H_SHARED_I2C i2cReleaseBus(((LPS25HDriver *)ip)->config->i2cp); #endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_USE_I2C */ - return MSG_OK; + + if(msg == MSG_OK) { + *axis = buff[0] + (buff[1] << 8) + (buff[2] << 16); + } + return msg; } - + static msg_t read_cooked(void *ip, float* axis) { int32_t raw; msg_t msg; @@ -170,7 +168,7 @@ static msg_t reset_bias(void *ip) { (((LPS25HDriver *)ip)->state == LPS25H_STOP), "reset_bias(), invalid state"); - ((LPS25HDriver *)ip)->bias = 0; + ((LPS25HDriver *)ip)->bias = 0.0f; return MSG_OK; } @@ -223,7 +221,7 @@ void lps25hObjectInit(LPS25HDriver *devp) { devp->vmt_basebarometer = &vmt_basebarometer; devp->config = NULL; devp->bias = 0; - devp->state = LPS25H_STOP; + devp->state = LPS25H_STOP; } /** @@ -235,49 +233,74 @@ void lps25hObjectInit(LPS25HDriver *devp) { * @api */ void lps25hStart(LPS25HDriver *devp, const LPS25HConfig *config) { - uint8_t cr; + uint8_t cr[2]; osalDbgCheck((devp != NULL) && (config != NULL)); osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY), - "lps25hStart(), invalid state"); + "lps25hStart(), invalid state"); devp->config = config; - #if LPS25H_USE_I2C -#if LPS25H_SHARED_I2C + /* Control register 1 configuration block.*/ + { + cr[0] = LPS25H_AD_CTRL_REG1; + cr[1] = devp->config->outputdatarate | LPS25H_CTRL_REG1_PD; +#if LPS25H_USE_ADVANCED || defined(__DOXYGEN__) + cr[1] |= devp->config->blockdataupdate; +#endif + } + +#if LPS25H_SHARED_I2C i2cAcquireBus((devp)->config->i2cp); #endif /* LPS25H_SHARED_I2C */ i2cStart((devp)->config->i2cp, (devp)->config->i2ccfg); + + lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, cr, 1); + +#if LPS25H_SHARED_I2C + i2cReleaseBus((devp)->config->i2cp); +#endif /* LPS25H_SHARED_I2C */ - /* Control register 1 configuration block.*/ + /* Resolution configuration block.*/ { - cr = devp->config->outputdatarate | LPS25H_CTRL_REG1_PD; + cr[0] = LPS25H_AD_RES_CONF; + cr[1] = 0x05; #if LPS25H_USE_ADVANCED || defined(__DOXYGEN__) - cr |= devp->config->blockdataupdate; - + cr[1] = devp->config->respressure | devp->config->restemperature; #endif - lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, - LPS25H_AD_CTRL_REG1, cr); + } - - /* Control register 1 configuration block.*/ - { - cr = 0x05; -#if LPS25H_USE_ADVANCED || defined(__DOXYGEN__) - cr = devp->config->respressure | devp->config->restemperature; - -#endif - lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, - LPS25H_AD_RES_CONF, cr); - } - -#if LPS25H_SHARED_I2C +#if LPS25H_SHARED_I2C + i2cAcquireBus((devp)->config->i2cp); + i2cStart((devp)->config->i2cp, + (devp)->config->i2ccfg); +#endif /* LPS25H_SHARED_I2C */ + + lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, + cr, 1); + +#if LPS25H_SHARED_I2C i2cReleaseBus((devp)->config->i2cp); #endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_USE_I2C */ - /* Storing sensitivity information according to full scale value */ - devp->sensitivity = LPS25H_SENS; + + if(devp->config->sensitivity == NULL) { + devp->sensitivity = LPS25H_SENS; + } + else{ + /* Taking Sensitivity from user configurations */ + devp->sensitivity = *devp->config->sensitivity; + } + + if(devp->config->bias == NULL) { + devp->bias = 0.0f; + } + else{ + /* Taking Bias from user configurations */ + devp->bias = *devp->config->bias; + } + /* This is the Barometer transient recovery time */ osalThreadSleepMilliseconds(5); @@ -292,27 +315,32 @@ void lps25hStart(LPS25HDriver *devp, const LPS25HConfig *config) { * @api */ void lps25hStop(LPS25HDriver *devp) { + uint8_t cr[2]; osalDbgCheck(devp != NULL); osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY), "lps25hStop(), invalid state"); + if (devp->state == LPS25H_READY) { #if (LPS25H_USE_I2C) - if (devp->state == LPS25H_STOP) { -#if LPS25H_SHARED_I2C +#if LPS25H_SHARED_I2C i2cAcquireBus((devp)->config->i2cp); i2cStart((devp)->config->i2cp, (devp)->config->i2ccfg); #endif /* LPS25H_SHARED_I2C */ + + cr[0] = LPS25H_AD_CTRL_REG1; + cr[1] = 0; lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, - LPS25H_AD_CTRL_REG1, 0); + cr, 1); + i2cStop((devp)->config->i2cp); -#if LPS25H_SHARED_I2C +#if LPS25H_SHARED_I2C i2cReleaseBus((devp)->config->i2cp); -#endif /* LPS25H_SHARED_I2C */ - } +#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_USE_I2C */ + } devp->state = LPS25H_STOP; } /** @} */ diff --git a/os/ex/ST/lps25h.h b/os/ex/ST/lps25h.h index d7c7fc2ee..a03e4e3bf 100644 --- a/os/ex/ST/lps25h.h +++ b/os/ex/ST/lps25h.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ /** @@ -40,7 +40,7 @@ /** * @brief LPS25H driver version string. */ -#define EX_LPS25H_VERSION "1.0.1" +#define EX_LPS25H_VERSION "1.0.2" /** * @brief LPS25H driver version major number. @@ -55,7 +55,7 @@ /** * @brief LPS25H driver version patch number. */ -#define EX_LPS25H_PATCH 1 +#define EX_LPS25H_PATCH 2 /** @} */ /** @@ -115,13 +115,13 @@ * @name LPS25H_CTRL_REG1 register bits definitions * @{ */ -#define LPS25H_CTRL_REG1_MASK 0xFF +#define LPS25H_CTRL_REG1_MASK 0xFF #define LPS25H_CTRL_REG1_SIM (1 << 0) -#define LPS25H_CTRL_REG1_RESET_AZ (1 << 1) +#define LPS25H_CTRL_REG1_RESET_AZ (1 << 1) #define LPS25H_CTRL_REG1_BDU (1 << 2) -#define LPS25H_CTRL_REG1_DIFF_EN (1 << 3) +#define LPS25H_CTRL_REG1_DIFF_EN (1 << 3) #define LPS25H_CTRL_REG1_ODR0 (1 << 4) -#define LPS25H_CTRL_REG1_ODR1 (1 << 5) +#define LPS25H_CTRL_REG1_ODR1 (1 << 5) #define LPS25H_CTRL_REG1_ODR2 (1 << 6) #define LPS25H_CTRL_REG1_PD (1 << 7) /** @} */ @@ -130,12 +130,12 @@ * @name LPS25H_CTRL_REG2 register bits definitions * @{ */ -#define LPS25H_CTRL_REG2_MASK 0xF3 +#define LPS25H_CTRL_REG2_MASK 0xF3 #define LPS25H_CTRL_REG2_ONE_SHOT (1 << 0) -#define LPS25H_CTRL_REG2_AUTO_ZERO (1 << 1) -#define LPS25H_CTRL_REG2_SWRESET (1 << 2) +#define LPS25H_CTRL_REG2_AUTO_ZERO (1 << 1) +#define LPS25H_CTRL_REG2_SWRESET (1 << 2) #define LPS25H_CTRL_REG2_FIFO_MEAN_DEC (1 << 4) -#define LPS25H_CTRL_REG2_WTM_EN (1 << 5) +#define LPS25H_CTRL_REG2_WTM_EN (1 << 5) #define LPS25H_CTRL_REG2_FIFO_EN (1 << 6) #define LPS25H_CTRL_REG2_BOOT (1 << 7) /** @} */ @@ -144,9 +144,9 @@ * @name LPS25H_CTRL_REG3 register bits definitions * @{ */ -#define LPS25H_CTRL_REG3_MASK 0xC3 +#define LPS25H_CTRL_REG3_MASK 0xC3 #define LPS25H_CTRL_REG3_INT_S1 (1 << 0) -#define LPS25H_CTRL_REG3_INT_S2 (1 << 1) +#define LPS25H_CTRL_REG3_INT_S2 (1 << 1) #define LPS25H_CTRL_REG3_PP_OD (1 << 6) #define LPS25H_CTRL_REG3_INT_H_L (1 << 7) /** @} */ @@ -155,18 +155,18 @@ * @name LPS25H_CTRL_REG4 register bits definitions * @{ */ -#define LPS25H_CTRL_REG4_MASK 0x0F +#define LPS25H_CTRL_REG4_MASK 0x0F #define LPS25H_CTRL_REG4_P1_DRDY (1 << 0) -#define LPS25H_CTRL_REG4_P1_OVERRUN (1 << 1) +#define LPS25H_CTRL_REG4_P1_OVERRUN (1 << 1) #define LPS25H_CTRL_REG4_P1_WTM (1 << 2) -#define LPS25H_CTRL_REG4_P1_EMPTY (1 << 3) +#define LPS25H_CTRL_REG4_P1_EMPTY (1 << 3) /** @} */ /** * @name LPS25H_INT1_CFG register bits definitions * @{ */ -#define LPS25H_INT1_CFG_MASK 0x07 +#define LPS25H_INT1_CFG_MASK 0x07 #define LPS25H_INT1_CFG_PH_E (1 << 0) #define LPS25H_INT1_CFG_PL_E (1 << 1) #define LPS25H_INT1_CFG_LIR (1 << 2) @@ -223,7 +223,7 @@ * on each transaction. * @note The default is @p FALSE. Requires I2C_USE_MUTUAL_EXCLUSION */ -#if !defined(LPS25H_SHARED_SPI) || defined(__DOXYGEN__) +#if !defined(LPS25H_SHARED_I2C) || defined(__DOXYGEN__) #define LPS25H_SHARED_I2C FALSE #endif /** @} */ @@ -348,12 +348,12 @@ typedef struct { /** * @brief LPS25H initial sensitivity. */ - float sensitivity; + float* sensitivity; /** * @brief LPS25H initial bias. */ - float bias; - /** + float* bias; + /** * @brief LPS25H slave address */ lps25h_sad_t slaveaddress; @@ -382,21 +382,6 @@ typedef struct { */ typedef struct LPS25HDriver LPS25HDriver; -/** - * @brief @p LPS25H specific methods. - */ -#define _lps25h_methods \ - _base_barometer_methods - -/** - * @extends BaseGyroscopeVMT - * - * @brief @p LPS25H virtual methods table. - */ -struct LPS25HVMT { - _lps25h_methods -}; - /** * @brief @p LPS25HDriver specific data. */ diff --git a/testhal/STM32/STM32F4xx/I2C-LPS25H/Makefile b/testhal/STM32/STM32F4xx/I2C-LPS25H/Makefile index 057c420fb..6593f01be 100644 --- a/testhal/STM32/STM32F4xx/I2C-LPS25H/Makefile +++ b/testhal/STM32/STM32F4xx/I2C-LPS25H/Makefile @@ -201,7 +201,7 @@ CPPWARN = -Wall -Wextra -Wundef # List all user C define here, like -D_DEBUG=1 UDEFS = -DCHPRINTF_USE_FLOAT=1 -DSHELL_CMD_TEST_ENABLED=0 \ - -DLPS25H_USE_ADVANCED=0 + -DLPS25H_USE_ADVANCED=1 -DLPS25H_SHARED_I2C=1 # Define ASM defines here UADEFS = diff --git a/testhal/STM32/STM32F4xx/I2C-LPS25H/main.c b/testhal/STM32/STM32F4xx/I2C-LPS25H/main.c index c31fef938..b708fe6d2 100644 --- a/testhal/STM32/STM32F4xx/I2C-LPS25H/main.c +++ b/testhal/STM32/STM32F4xx/I2C-LPS25H/main.c @@ -42,8 +42,8 @@ static const I2CConfig i2ccfg = { static const LPS25HConfig lps25hcfg = { &I2CD1, &i2ccfg, - 0, /* Use default sensitivity.*/ - 0, /* Use default bias.*/ + NULL, /* Use default sensitivity.*/ + NULL, /* Use default bias.*/ LPS25H_SAD_VCC, /* SA0 connected to VCC */ LPS25H_ODR_7HZ, /* Output data rate 7 Hz.*/ #if LPS25H_USE_ADVANCED || defined(__DOXYGEN__)