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
This commit is contained in:
Rocco Marco Guglielmi 2016-09-27 21:28:26 +00:00
parent b80b4fdd87
commit c614b18226
4 changed files with 128 additions and 115 deletions

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
@ -50,21 +50,22 @@
* @brief Reads registers value using I2C. * @brief Reads registers value using I2C.
* @pre The I2C interface must be initialized and the driver started. * @pre The I2C interface must be initialized and the driver started.
* *
* @param[in] i2cp pointer to the I2C interface * @param[in] i2cp pointer to the I2C interface
* @param[in] sad slave address without R bit * @param[in] sad slave address without R bit
* @param[in] reg first sub-register address * @param[in] reg first sub-register address
* @return the read value. * @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 lps25hI2CReadRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg,
msg_t* msgp) { uint8_t* rxbuf, size_t n) {
msg_t msg; uint8_t txbuf = reg;
uint8_t rxbuf; if(n > 1)
msg = i2cMasterTransmitTimeout(i2cp, sad, &reg, 1, &rxbuf, 1, txbuf |= LPS25H_SUB_MS;
TIME_INFINITE);
if(msgp != NULL){ return i2cMasterTransmitTimeout(i2cp, sad, &txbuf, 1, rxbuf, n,
*msgp = msg; TIME_INFINITE);
}
return rxbuf;
} }
/** /**
@ -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] i2cp pointer to the I2C interface
* @param[in] sad slave address without R bit * @param[in] sad slave address without R bit
* @param[in] sub sub-register address * @param[in] txbuf buffer containing sub-address value in first position
* @param[in] value the value to be written * 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. * @return the operation status.
*/ */
msg_t lps25hI2CWriteRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t reg, msg_t lps25hI2CWriteRegister(I2CDriver *i2cp, lps25h_sad_t sad, uint8_t* txbuf, size_t n) {
uint8_t value) { if (n > 1)
uint8_t txbuf[2]; (*txbuf) |= LPS25H_SUB_MS;
txbuf[0] = reg; return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0,
txbuf[1] = value; TIME_INFINITE);
return i2cMasterTransmitTimeout(i2cp, sad, txbuf, 2, NULL, 0, TIME_INFINITE);
} }
#endif /* LPS25H_USE_I2C */ #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) { static msg_t read_raw(void *ip, int32_t* axis) {
int32_t tmp; uint8_t buff[3];
msg_t msg = MSG_OK; msg_t msg = MSG_OK;
*axis = 0;
osalDbgCheck((ip != NULL) && (axis != NULL)); osalDbgCheck((ip != NULL) && (axis != NULL));
osalDbgAssert((((LPS25HDriver *)ip)->state == LPS25H_READY), osalDbgAssert((((LPS25HDriver *)ip)->state == LPS25H_READY),
"read_raw(), invalid state"); "read_raw(), invalid state");
@ -110,31 +117,22 @@ static msg_t read_raw(void *ip, int32_t* axis) {
i2cStart(((LPS25HDriver *)ip)->config->i2cp, i2cStart(((LPS25HDriver *)ip)->config->i2cp,
((LPS25HDriver *)ip)->config->i2ccfg); ((LPS25HDriver *)ip)->config->i2ccfg);
#endif /* LPS25H_SHARED_I2C */ #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 #if LPS25H_SHARED_I2C
i2cReleaseBus(((LPS25HDriver *)ip)->config->i2cp); i2cReleaseBus(((LPS25HDriver *)ip)->config->i2cp);
#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_SHARED_I2C */
#endif /* LPS25H_USE_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) { static msg_t read_cooked(void *ip, float* axis) {
int32_t raw; int32_t raw;
msg_t msg; msg_t msg;
@ -170,7 +168,7 @@ static msg_t reset_bias(void *ip) {
(((LPS25HDriver *)ip)->state == LPS25H_STOP), (((LPS25HDriver *)ip)->state == LPS25H_STOP),
"reset_bias(), invalid state"); "reset_bias(), invalid state");
((LPS25HDriver *)ip)->bias = 0; ((LPS25HDriver *)ip)->bias = 0.0f;
return MSG_OK; return MSG_OK;
} }
@ -223,7 +221,7 @@ void lps25hObjectInit(LPS25HDriver *devp) {
devp->vmt_basebarometer = &vmt_basebarometer; devp->vmt_basebarometer = &vmt_basebarometer;
devp->config = NULL; devp->config = NULL;
devp->bias = 0; devp->bias = 0;
devp->state = LPS25H_STOP; devp->state = LPS25H_STOP;
} }
/** /**
@ -235,49 +233,74 @@ void lps25hObjectInit(LPS25HDriver *devp) {
* @api * @api
*/ */
void lps25hStart(LPS25HDriver *devp, const LPS25HConfig *config) { void lps25hStart(LPS25HDriver *devp, const LPS25HConfig *config) {
uint8_t cr; uint8_t cr[2];
osalDbgCheck((devp != NULL) && (config != NULL)); osalDbgCheck((devp != NULL) && (config != NULL));
osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY), osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY),
"lps25hStart(), invalid state"); "lps25hStart(), invalid state");
devp->config = config; devp->config = config;
#if LPS25H_USE_I2C #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); i2cAcquireBus((devp)->config->i2cp);
#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_SHARED_I2C */
i2cStart((devp)->config->i2cp, i2cStart((devp)->config->i2cp,
(devp)->config->i2ccfg); (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__) #if LPS25H_USE_ADVANCED || defined(__DOXYGEN__)
cr |= devp->config->blockdataupdate; cr[1] = devp->config->respressure | devp->config->restemperature;
#endif #endif
lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
LPS25H_AD_CTRL_REG1, cr);
} }
#if LPS25H_SHARED_I2C
/* Control register 1 configuration block.*/ i2cAcquireBus((devp)->config->i2cp);
{ i2cStart((devp)->config->i2cp,
cr = 0x05; (devp)->config->i2ccfg);
#if LPS25H_USE_ADVANCED || defined(__DOXYGEN__) #endif /* LPS25H_SHARED_I2C */
cr = devp->config->respressure | devp->config->restemperature;
lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
#endif cr, 1);
lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
LPS25H_AD_RES_CONF, cr); #if LPS25H_SHARED_I2C
}
#if LPS25H_SHARED_I2C
i2cReleaseBus((devp)->config->i2cp); i2cReleaseBus((devp)->config->i2cp);
#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_SHARED_I2C */
#endif /* LPS25H_USE_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 */ /* This is the Barometer transient recovery time */
osalThreadSleepMilliseconds(5); osalThreadSleepMilliseconds(5);
@ -292,27 +315,32 @@ void lps25hStart(LPS25HDriver *devp, const LPS25HConfig *config) {
* @api * @api
*/ */
void lps25hStop(LPS25HDriver *devp) { void lps25hStop(LPS25HDriver *devp) {
uint8_t cr[2];
osalDbgCheck(devp != NULL); osalDbgCheck(devp != NULL);
osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY), osalDbgAssert((devp->state == LPS25H_STOP) || (devp->state == LPS25H_READY),
"lps25hStop(), invalid state"); "lps25hStop(), invalid state");
if (devp->state == LPS25H_READY) {
#if (LPS25H_USE_I2C) #if (LPS25H_USE_I2C)
if (devp->state == LPS25H_STOP) { #if LPS25H_SHARED_I2C
#if LPS25H_SHARED_I2C
i2cAcquireBus((devp)->config->i2cp); i2cAcquireBus((devp)->config->i2cp);
i2cStart((devp)->config->i2cp, i2cStart((devp)->config->i2cp,
(devp)->config->i2ccfg); (devp)->config->i2ccfg);
#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_SHARED_I2C */
cr[0] = LPS25H_AD_CTRL_REG1;
cr[1] = 0;
lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, lps25hI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
LPS25H_AD_CTRL_REG1, 0); cr, 1);
i2cStop((devp)->config->i2cp); i2cStop((devp)->config->i2cp);
#if LPS25H_SHARED_I2C #if LPS25H_SHARED_I2C
i2cReleaseBus((devp)->config->i2cp); i2cReleaseBus((devp)->config->i2cp);
#endif /* LPS25H_SHARED_I2C */ #endif /* LPS25H_SHARED_I2C */
}
#endif /* LPS25H_USE_I2C */ #endif /* LPS25H_USE_I2C */
}
devp->state = LPS25H_STOP; devp->state = LPS25H_STOP;
} }
/** @} */ /** @} */

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
@ -40,7 +40,7 @@
/** /**
* @brief LPS25H driver version string. * @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. * @brief LPS25H driver version major number.
@ -55,7 +55,7 @@
/** /**
* @brief LPS25H driver version patch number. * @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 * @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_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_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_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_ODR2 (1 << 6)
#define LPS25H_CTRL_REG1_PD (1 << 7) #define LPS25H_CTRL_REG1_PD (1 << 7)
/** @} */ /** @} */
@ -130,12 +130,12 @@
* @name LPS25H_CTRL_REG2 register bits definitions * @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_ONE_SHOT (1 << 0)
#define LPS25H_CTRL_REG2_AUTO_ZERO (1 << 1) #define LPS25H_CTRL_REG2_AUTO_ZERO (1 << 1)
#define LPS25H_CTRL_REG2_SWRESET (1 << 2) #define LPS25H_CTRL_REG2_SWRESET (1 << 2)
#define LPS25H_CTRL_REG2_FIFO_MEAN_DEC (1 << 4) #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_FIFO_EN (1 << 6)
#define LPS25H_CTRL_REG2_BOOT (1 << 7) #define LPS25H_CTRL_REG2_BOOT (1 << 7)
/** @} */ /** @} */
@ -144,9 +144,9 @@
* @name LPS25H_CTRL_REG3 register bits definitions * @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_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_PP_OD (1 << 6)
#define LPS25H_CTRL_REG3_INT_H_L (1 << 7) #define LPS25H_CTRL_REG3_INT_H_L (1 << 7)
/** @} */ /** @} */
@ -155,18 +155,18 @@
* @name LPS25H_CTRL_REG4 register bits definitions * @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_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_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 * @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_PH_E (1 << 0)
#define LPS25H_INT1_CFG_PL_E (1 << 1) #define LPS25H_INT1_CFG_PL_E (1 << 1)
#define LPS25H_INT1_CFG_LIR (1 << 2) #define LPS25H_INT1_CFG_LIR (1 << 2)
@ -223,7 +223,7 @@
* on each transaction. * on each transaction.
* @note The default is @p FALSE. Requires I2C_USE_MUTUAL_EXCLUSION * @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 #define LPS25H_SHARED_I2C FALSE
#endif #endif
/** @} */ /** @} */
@ -348,12 +348,12 @@ typedef struct {
/** /**
* @brief LPS25H initial sensitivity. * @brief LPS25H initial sensitivity.
*/ */
float sensitivity; float* sensitivity;
/** /**
* @brief LPS25H initial bias. * @brief LPS25H initial bias.
*/ */
float bias; float* bias;
/** /**
* @brief LPS25H slave address * @brief LPS25H slave address
*/ */
lps25h_sad_t slaveaddress; lps25h_sad_t slaveaddress;
@ -382,21 +382,6 @@ typedef struct {
*/ */
typedef struct LPS25HDriver LPS25HDriver; 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. * @brief @p LPS25HDriver specific data.
*/ */

View File

@ -201,7 +201,7 @@ CPPWARN = -Wall -Wextra -Wundef
# List all user C define here, like -D_DEBUG=1 # List all user C define here, like -D_DEBUG=1
UDEFS = -DCHPRINTF_USE_FLOAT=1 -DSHELL_CMD_TEST_ENABLED=0 \ 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 # Define ASM defines here
UADEFS = UADEFS =

View File

@ -42,8 +42,8 @@ static const I2CConfig i2ccfg = {
static const LPS25HConfig lps25hcfg = { static const LPS25HConfig lps25hcfg = {
&I2CD1, &I2CD1,
&i2ccfg, &i2ccfg,
0, /* Use default sensitivity.*/ NULL, /* Use default sensitivity.*/
0, /* Use default bias.*/ NULL, /* Use default bias.*/
LPS25H_SAD_VCC, /* SA0 connected to VCC */ LPS25H_SAD_VCC, /* SA0 connected to VCC */
LPS25H_ODR_7HZ, /* Output data rate 7 Hz.*/ LPS25H_ODR_7HZ, /* Output data rate 7 Hz.*/
#if LPS25H_USE_ADVANCED || defined(__DOXYGEN__) #if LPS25H_USE_ADVANCED || defined(__DOXYGEN__)