Updated LIS3DSH driver and demos

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11690 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
Rocco Marco Guglielmi 2018-03-10 23:02:03 +00:00
parent 1d00f3853b
commit a271d810c1
6 changed files with 665 additions and 470 deletions

View File

@ -1,5 +1,5 @@
/* /*
ChibiOS - Copyright (C) 2016 Rocco Marco Guglielmi ChibiOS - Copyright (C) 2016-2018 Rocco Marco Guglielmi
This file is part of ChibiOS. This file is part of ChibiOS.
@ -57,7 +57,7 @@
* @param[in] n number of adjacent registers to write * @param[in] n number of adjacent registers to write
* @param[in] b pointer to a buffer. * @param[in] b pointer to a buffer.
*/ */
static void lis3dshSPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n, static void lis3dshSPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n,
uint8_t* b) { uint8_t* b) {
uint8_t cmd; uint8_t cmd;
cmd = reg | LIS3DSH_RW; cmd = reg | LIS3DSH_RW;
@ -88,177 +88,313 @@ static void lis3dshSPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n,
} }
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
/* /**
* Interface implementation. * @brief Return the number of axes of the BaseAccelerometer.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
*
* @return the number of axes.
*/ */
static size_t get_axes_number(void *ip) { static size_t acc_get_axes_number(void *ip) {
(void)ip;
osalDbgCheck(ip != NULL);
return LIS3DSH_NUMBER_OF_AXES; return LIS3DSH_ACC_NUMBER_OF_AXES;
} }
static msg_t read_raw(void *ip, int32_t axes[LIS3DSH_NUMBER_OF_AXES]) { /**
uint8_t buff [LIS3DSH_NUMBER_OF_AXES * 2], i; * @brief Retrieves raw data from the BaseAccelerometer.
* @note This data is retrieved from MEMS register without any algebraical
* manipulation.
* @note The axes array must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
* @param[out] axes a buffer which would be filled with raw data.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET if one or more I2C errors occurred, the errors can
* be retrieved using @p i2cGetErrors().
* @retval MSG_TIMEOUT if a timeout occurred before operation end.
*/
static msg_t acc_read_raw(void *ip, int32_t axes[]) {
LIS3DSHDriver* devp;
uint8_t buff [LIS3DSH_ACC_NUMBER_OF_AXES * 2], i;
int16_t tmp; int16_t tmp;
osalDbgCheck((ip != NULL) && (axes != NULL)); msg_t msg = MSG_OK;
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY), osalDbgCheck((ip != NULL) && (axes != NULL));
"read_raw(), invalid state");
/* Getting parent instance pointer.*/
devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
osalDbgAssert((devp->state == LIS3DSH_READY),
"acc_read_raw(), invalid state");
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
osalDbgAssert((((LIS3DSHDriver *)ip)->config->spip->state == SPI_READY),
"read_raw(), channel not ready");
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus(((LIS3DSHDriver *)ip)->config->spip); osalDbgAssert((devp->config->spip->state == SPI_READY),
spiStart(((LIS3DSHDriver *)ip)->config->spip, "acc_read_raw(), channel not ready");
((LIS3DSHDriver *)ip)->config->spicfg);
spiAcquireBus(devp->config->spip);
spiStart(devp->config->spip,
devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
lis3dshSPIReadRegister(((LIS3DSHDriver *)ip)->config->spip, LIS3DSH_AD_OUT_X_L, lis3dshSPIReadRegister(devp->config->spip, LIS3DSH_AD_OUT_X_L,
LIS3DSH_NUMBER_OF_AXES * 2, buff); LIS3DSH_ACC_NUMBER_OF_AXES * 2, buff);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus(((LIS3DSHDriver *)ip)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) {
tmp = buff[2*i] + (buff[2*i+1] << 8); for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
axes[i] = (int32_t)tmp; axes[i] = (int32_t)tmp;
} }
return MSG_OK;
}
static msg_t read_cooked(void *ip, float axes[]) {
uint32_t i;
int32_t raw[LIS3DSH_NUMBER_OF_AXES];
msg_t msg;
osalDbgCheck((ip != NULL) && (axes != NULL));
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY),
"read_cooked(), invalid state");
msg = read_raw(ip, raw);
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES ; i++){
axes[i] = (raw[i] * ((LIS3DSHDriver *)ip)->sensitivity[i]);
axes[i] -= ((LIS3DSHDriver *)ip)->bias[i];
}
return msg; return msg;
} }
static msg_t set_bias(void *ip, float *bp) { /**
* @brief Retrieves cooked data from the BaseAccelerometer.
* @note This data is manipulated according to the formula
* cooked = (raw * sensitivity) - bias.
* @note Final data is expressed as milli-G.
* @note The axes array must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
* @param[out] axes a buffer which would be filled with cooked data.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET if one or more I2C errors occurred, the errors can
* be retrieved using @p i2cGetErrors().
* @retval MSG_TIMEOUT if a timeout occurred before operation end.
*/
static msg_t acc_read_cooked(void *ip, float axes[]) {
LIS3DSHDriver* devp;
uint32_t i; uint32_t i;
int32_t raw[LIS3DSH_ACC_NUMBER_OF_AXES];
osalDbgCheck((ip != NULL) && (bp !=NULL)); msg_t msg;
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY) || osalDbgCheck((ip != NULL) && (axes != NULL));
(((LIS3DSHDriver *)ip)->state == LIS3DSH_STOP),
"set_bias(), invalid state"); /* Getting parent instance pointer.*/
devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) {
((LIS3DSHDriver *)ip)->bias[i] = bp[i]; osalDbgAssert((devp->state == LIS3DSH_READY),
"acc_read_cooked(), invalid state");
msg = acc_read_raw(ip, raw);
for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
axes[i] = (raw[i] * devp->accsensitivity[i]) - devp->accbias[i];
} }
return MSG_OK; return msg;
} }
static msg_t reset_bias(void *ip) { /**
* @brief Set bias values for the BaseAccelerometer.
* @note Bias must be expressed as milli-G.
* @note The bias buffer must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
* @param[in] bp a buffer which contains biases.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*/
static msg_t acc_set_bias(void *ip, float *bp) {
LIS3DSHDriver* devp;
uint32_t i; uint32_t i;
msg_t msg = MSG_OK;
osalDbgCheck((ip != NULL) && (bp != NULL));
/* Getting parent instance pointer.*/
devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
osalDbgAssert((devp->state == LIS3DSH_READY),
"acc_set_bias(), invalid state");
for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
devp->accbias[i] = bp[i];
}
return msg;
}
/**
* @brief Reset bias values for the BaseAccelerometer.
* @note Default biases value are obtained from device datasheet when
* available otherwise they are considered zero.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*/
static msg_t acc_reset_bias(void *ip) {
LIS3DSHDriver* devp;
uint32_t i;
msg_t msg = MSG_OK;
osalDbgCheck(ip != NULL); osalDbgCheck(ip != NULL);
/* Getting parent instance pointer.*/
devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY) || osalDbgAssert((devp->state == LIS3DSH_READY),
(((LIS3DSHDriver *)ip)->state == LIS3DSH_STOP), "acc_reset_bias(), invalid state");
"reset_bias(), invalid state");
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->bias[i] = 0; devp->accbias[i] = LIS3DSH_ACC_BIAS;
return MSG_OK; return msg;
} }
static msg_t set_sensivity(void *ip, float *sp) { /**
* @brief Set sensitivity values for the BaseAccelerometer.
* @note Sensitivity must be expressed as milli-G/LSB.
* @note The sensitivity buffer must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
* @param[in] sp a buffer which contains sensitivities.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*/
static msg_t acc_set_sensivity(void *ip, float *sp) {
LIS3DSHDriver* devp;
uint32_t i; uint32_t i;
msg_t msg = MSG_OK;
osalDbgCheck((ip != NULL) && (sp !=NULL));
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY), /* Getting parent instance pointer.*/
"set_sensivity(), invalid state"); devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) { osalDbgCheck((ip != NULL) && (sp != NULL));
((LIS3DSHDriver *)ip)->sensitivity[i] = sp[i];
osalDbgAssert((devp->state == LIS3DSH_READY),
"acc_set_sensivity(), invalid state");
for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
devp->accsensitivity[i] = sp[i];
} }
return MSG_OK; return msg;
} }
static msg_t reset_sensivity(void *ip) { /**
* @brief Reset sensitivity values for the BaseAccelerometer.
* @note Default sensitivities value are obtained from device datasheet.
*
* @param[in] ip pointer to @p BaseAccelerometer interface.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET otherwise.
*/
static msg_t acc_reset_sensivity(void *ip) {
LIS3DSHDriver* devp;
uint32_t i; uint32_t i;
msg_t msg = MSG_OK;
osalDbgCheck(ip != NULL); osalDbgCheck(ip != NULL);
/* Getting parent instance pointer.*/
devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip);
osalDbgAssert((((LIS3DSHDriver *)ip)->state == LIS3DSH_READY), osalDbgAssert((devp->state == LIS3DSH_READY),
"reset_sensivity(), invalid state"); "acc_reset_sensivity(), invalid state");
if(((LIS3DSHDriver *)ip)->config->fullscale == LIS3DSH_FS_2G) if(devp->config->accfullscale == LIS3DSH_ACC_FS_2G)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->sensitivity[i] = LIS3DSH_SENS_2G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_2G;
else if(((LIS3DSHDriver *)ip)->config->fullscale == LIS3DSH_FS_4G) else if(devp->config->accfullscale == LIS3DSH_ACC_FS_4G)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->sensitivity[i] = LIS3DSH_SENS_4G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_4G;
else if(((LIS3DSHDriver *)ip)->config->fullscale == LIS3DSH_FS_6G) else if(devp->config->accfullscale == LIS3DSH_ACC_FS_6G)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->sensitivity[i] = LIS3DSH_SENS_6G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_6G;
else if(((LIS3DSHDriver *)ip)->config->fullscale == LIS3DSH_FS_8G) else if(devp->config->accfullscale == LIS3DSH_ACC_FS_8G)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->sensitivity[i] = LIS3DSH_SENS_8G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_8G;
else if(((LIS3DSHDriver *)ip)->config->fullscale == LIS3DSH_FS_16G) else if(devp->config->accfullscale == LIS3DSH_ACC_FS_16G)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
((LIS3DSHDriver *)ip)->sensitivity[i] = LIS3DSH_SENS_16G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_16G;
else { else {
osalDbgAssert(FALSE, "reset_sensivity(), accelerometer full scale issue"); osalDbgAssert(FALSE,
"acc_reset_sensivity(), accelerometer full scale issue");
return MSG_RESET; return MSG_RESET;
} }
return MSG_OK; return msg;
} }
static msg_t set_full_scale(void *ip, lis3dsh_fs_t fs) { /**
* @brief Changes the LIS3DSHDriver accelerometer fullscale value.
* @note This function also rescale sensitivities and biases based on
* previous and next fullscale value.
* @note A recalibration is highly suggested after calling this function.
*
* @param[in] ip pointer to @p LIS3DSHDriver interface.
* @param[in] fs new fullscale value.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET otherwise.
*/
static msg_t acc_set_full_scale(LIS3DSHDriver *devp,
lis3dsh_acc_fs_t fs) {
float newfs, scale; float newfs, scale;
uint8_t i, cr; uint8_t i, cr;
msg_t msg;
if(fs == LIS3DSH_FS_2G) { osalDbgCheck(devp != NULL);
newfs = LIS3DSH_2G;
osalDbgAssert((devp->state == LIS3DSH_READY),
"acc_set_full_scale(), invalid state");
osalDbgAssert((devp->config->spip->state == SPI_READY),
"acc_set_full_scale(), channel not ready");
/* Computing new fullscale value.*/
if(fs == LIS3DSH_ACC_FS_2G) {
newfs = LIS3DSH_ACC_2G;
} }
else if(fs == LIS3DSH_FS_4G) { else if(fs == LIS3DSH_ACC_FS_4G) {
newfs = LIS3DSH_4G; newfs = LIS3DSH_ACC_4G;
} }
else if(fs == LIS3DSH_FS_6G) { else if(fs == LIS3DSH_ACC_FS_6G) {
newfs = LIS3DSH_6G; newfs = LIS3DSH_ACC_6G;
} }
else if(fs == LIS3DSH_FS_8G) { else if(fs == LIS3DSH_ACC_FS_8G) {
newfs = LIS3DSH_8G; newfs = LIS3DSH_ACC_8G;
} }
else if(fs == LIS3DSH_FS_16G) { else if(fs == LIS3DSH_ACC_FS_16G) {
newfs = LIS3DSH_16G; newfs = LIS3DSH_ACC_16G;
} }
else { else {
return MSG_RESET; msg = MSG_RESET;
return msg;
} }
if(newfs != ((LIS3DSHDriver *)ip)->fullscale) { if(newfs != devp->accfullscale) {
scale = newfs / ((LIS3DSHDriver *)ip)->fullscale; /* Computing scale value.*/
((LIS3DSHDriver *)ip)->fullscale = newfs; scale = newfs / devp->accfullscale;
devp->accfullscale = newfs;
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus(((LIS3DSHDriver *)ip)->config->spip); spiAcquireBus(devp->config->spip);
spiStart(((LIS3DSHDriver *)ip)->config->spip, spiStart(devp->config->spip,
((LIS3DSHDriver *)ip)->config->spicfg); devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
lis3dshSPIReadRegister(((LIS3DSHDriver *)ip)->config->spip,
LIS3DSH_AD_CTRL_REG5, 1, &cr); /* Getting data from register.*/
lis3dshSPIReadRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus(((LIS3DSHDriver *)ip)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
@ -267,34 +403,37 @@ static msg_t set_full_scale(void *ip, lis3dsh_fs_t fs) {
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus(((LIS3DSHDriver *)ip)->config->spip); spiAcquireBus(devp->config->spip);
spiStart(((LIS3DSHDriver *)ip)->config->spip, spiStart(devp->config->spip,
((LIS3DSHDriver *)ip)->config->spicfg); devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
lis3dshSPIWriteRegister(((LIS3DSHDriver *)ip)->config->spip,
LIS3DSH_AD_CTRL_REG5, 1, &cr); /* Getting data from register.*/
lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus(((LIS3DSHDriver *)ip)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
/* Scaling sensitivity and bias. Re-calibration is suggested anyway. */ /* Scaling sensitivity and bias. Re-calibration is suggested anyway. */
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) { for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
((LIS3DSHDriver *)ip)->sensitivity[i] *= scale; devp->accsensitivity[i] *= scale;
((LIS3DSHDriver *)ip)->bias[i] *= scale; devp->accbias[i] *= scale;
} }
} }
return MSG_OK; return msg;
} }
static const struct BaseSensorVMT vmt_sensor = { static const struct LIS3DSHVMT vmt_device = {
get_axes_number, read_raw, read_cooked (size_t)0,
acc_set_full_scale
}; };
static const struct LIS3DSHVMT vmt_accelerometer = { static const struct BaseAccelerometerVMT vmt_accelerometer = {
get_axes_number, read_raw, read_cooked, sizeof(struct LIS3DSHVMT*),
set_bias, reset_bias, set_sensivity, reset_sensivity, acc_get_axes_number, acc_read_raw, acc_read_cooked,
set_full_scale acc_set_bias, acc_reset_bias, acc_set_sensivity, acc_reset_sensivity
}; };
/*===========================================================================*/ /*===========================================================================*/
@ -309,13 +448,14 @@ static const struct LIS3DSHVMT vmt_accelerometer = {
* @init * @init
*/ */
void lis3dshObjectInit(LIS3DSHDriver *devp) { void lis3dshObjectInit(LIS3DSHDriver *devp) {
uint32_t i; devp->vmt = &vmt_device;
devp->vmt_sensor = &vmt_sensor; devp->acc_if.vmt = &vmt_accelerometer;
devp->vmt_accelerometer = &vmt_accelerometer;
devp->config = NULL; devp->config = NULL;
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++)
devp->bias[i] = 0.0f; devp->accaxes = LIS3DSH_ACC_NUMBER_OF_AXES;
devp->state = LIS3DSH_STOP;
devp->state = LIS3DSH_STOP;
} }
/** /**
@ -328,55 +468,55 @@ void lis3dshObjectInit(LIS3DSHDriver *devp) {
*/ */
void lis3dshStart(LIS3DSHDriver *devp, const LIS3DSHConfig *config) { void lis3dshStart(LIS3DSHDriver *devp, const LIS3DSHConfig *config) {
uint32_t i; uint32_t i;
osalDbgCheck((devp != NULL) && (config != NULL));
uint8_t cr; uint8_t cr;
osalDbgAssert((devp->state == LIS3DSH_STOP) || (devp->state == LIS3DSH_READY), osalDbgCheck((devp != NULL) && (config != NULL));
"lis3dshStart(), invalid state");
osalDbgAssert((devp->state == LIS3DSH_STOP) ||
(devp->state == LIS3DSH_READY),
"lis3dshStart(), invalid state");
devp->config = config; devp->config = config;
/* Control register 4 configuration block.*/ /* Control register 4 configuration block.*/
{ {
cr = LIS3DSH_CTRL_REG4_XEN | LIS3DSH_CTRL_REG4_YEN | LIS3DSH_CTRL_REG4_ZEN | cr = LIS3DSH_CTRL_REG4_XEN | LIS3DSH_CTRL_REG4_YEN | LIS3DSH_CTRL_REG4_ZEN |
devp->config->outputdatarate; devp->config->accoutputdatarate;
#if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__) #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
cr |= devp->config->blockdataupdate; cr |= devp->config->accblockdataupdate;
#endif #endif
} }
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus((devp)->config->spip); spiAcquireBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
spiStart((devp)->config->spip, (devp)->config->spicfg); spiStart(devp->config->spip, devp->config->spicfg);
lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4, lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4, 1, &cr);
1, &cr);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus((devp)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
/* Control register 5 configuration block.*/ /* Control register 5 configuration block.*/
{ {
cr = devp->config->fullscale; cr = devp->config->accfullscale;
#if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__) #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
cr |= devp->config->antialiasing; cr |= devp->config->accantialiasing;
#endif #endif
} }
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus((devp)->config->spip); spiAcquireBus(devp->config->spip);
spiStart((devp)->config->spip, (devp)->config->spicfg); spiStart(devp->config->spip, devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
1, &cr);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus((devp)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
@ -384,79 +524,81 @@ void lis3dshStart(LIS3DSHDriver *devp, const LIS3DSHConfig *config) {
{ {
cr = LIS3DSH_CTRL_REG6_ADD_INC; cr = LIS3DSH_CTRL_REG6_ADD_INC;
#if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__) #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
cr |= devp->config->blockdataupdate; cr |= devp->config->accblockdataupdate;
#endif #endif
} }
#if LIS3DSH_USE_SPI #if LIS3DSH_USE_SPI
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus((devp)->config->spip); spiAcquireBus(devp->config->spip);
spiStart((devp)->config->spip, (devp)->config->spicfg); spiStart(devp->config->spip, devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG6, lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG6, 1, &cr);
1, &cr);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus((devp)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
/* Storing sensitivity information according to user setting */ /* Storing sensitivity information according to user setting */
if(devp->config->fullscale == LIS3DSH_FS_2G) { if(devp->config->accfullscale == LIS3DSH_ACC_FS_2G) {
devp->fullscale = LIS3DSH_2G; devp->accfullscale = LIS3DSH_ACC_2G;
if(devp->config->sensitivity == NULL) if(devp->config->accsensitivity == NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = LIS3DSH_SENS_2G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_2G;
else else
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = devp->config->sensitivity[i]; devp->accsensitivity[i] = devp->config->accsensitivity[i];
} }
else if(devp->config->fullscale == LIS3DSH_FS_4G) { else if(devp->config->accfullscale == LIS3DSH_ACC_FS_4G) {
devp->fullscale = LIS3DSH_4G; devp->accfullscale = LIS3DSH_ACC_4G;
if(devp->config->sensitivity == NULL) if(devp->config->accsensitivity == NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = LIS3DSH_SENS_4G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_4G;
else else
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = devp->config->sensitivity[i]; devp->accsensitivity[i] = devp->config->accsensitivity[i];
} }
else if(devp->config->fullscale == LIS3DSH_FS_6G) { else if(devp->config->accfullscale == LIS3DSH_ACC_FS_6G) {
devp->fullscale = LIS3DSH_6G; devp->accfullscale = LIS3DSH_ACC_6G;
if(devp->config->sensitivity == NULL) if(devp->config->accsensitivity == NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = LIS3DSH_SENS_6G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_6G;
else else
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = devp->config->sensitivity[i]; devp->accsensitivity[i] = devp->config->accsensitivity[i];
} }
else if(devp->config->fullscale == LIS3DSH_FS_8G) { else if(devp->config->accfullscale == LIS3DSH_ACC_FS_8G) {
devp->fullscale = LIS3DSH_8G; devp->accfullscale = LIS3DSH_ACC_8G;
if(devp->config->sensitivity == NULL) if(devp->config->accsensitivity == NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = LIS3DSH_SENS_8G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_8G;
else else
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = devp->config->sensitivity[i]; devp->accsensitivity[i] = devp->config->accsensitivity[i];
} }
else if(devp->config->fullscale == LIS3DSH_FS_16G) { else if(devp->config->accfullscale == LIS3DSH_ACC_FS_16G) {
devp->fullscale = LIS3DSH_16G; devp->accfullscale = LIS3DSH_ACC_16G;
if(devp->config->sensitivity == NULL) if(devp->config->accsensitivity == NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = LIS3DSH_SENS_16G; devp->accsensitivity[i] = LIS3DSH_ACC_SENS_16G;
else else
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->sensitivity[i] = devp->config->sensitivity[i]; devp->accsensitivity[i] = devp->config->accsensitivity[i];
} }
else { else {
osalDbgAssert(FALSE, "lis3dshStart(), accelerometer full scale issue"); osalDbgAssert(FALSE, "lis3dshStart(), accelerometer full scale issue");
} }
/* Storing bias information according to user setting */ /* Storing bias information according to user setting */
if(devp->config->bias != NULL) if(devp->config->accbias != NULL)
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->bias[i] = devp->config->bias[i]; devp->accbias[i] = devp->config->accbias[i];
else
for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
devp->accbias[i] = LIS3DSH_ACC_BIAS;
/* This is the Accelerometer transient recovery time */ /* This is the Accelerometer transient recovery time */
osalThreadSleepMilliseconds(10); osalThreadSleepMilliseconds(10);
@ -474,23 +616,25 @@ void lis3dshStop(LIS3DSHDriver *devp) {
uint8_t cr4; uint8_t cr4;
osalDbgCheck(devp != NULL); osalDbgCheck(devp != NULL);
osalDbgAssert((devp->state == LIS3DSH_STOP) || (devp->state == LIS3DSH_READY), osalDbgAssert((devp->state == LIS3DSH_STOP) ||
(devp->state == LIS3DSH_READY),
"lis3dshStop(), invalid state"); "lis3dshStop(), invalid state");
if (devp->state == LIS3DSH_READY) { if (devp->state == LIS3DSH_READY) {
#if (LIS3DSH_USE_SPI) #if (LIS3DSH_USE_SPI)
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiAcquireBus((devp)->config->spip); spiAcquireBus(devp->config->spip);
spiStart((devp)->config->spip, spiStart(devp->config->spip,
(devp)->config->spicfg); devp->config->spicfg);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
/* Disabling all axes and enabling power down mode.*/ /* Disabling all axes and enabling power down mode.*/
cr4 = 0; cr4 = 0;
lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4, lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4,
1, &cr4); 1, &cr4);
spiStop((devp)->config->spip);
spiStop(devp->config->spip);
#if LIS3DSH_SHARED_SPI #if LIS3DSH_SHARED_SPI
spiReleaseBus((devp)->config->spip); spiReleaseBus(devp->config->spip);
#endif /* LIS3DSH_SHARED_SPI */ #endif /* LIS3DSH_SHARED_SPI */
#endif /* LIS3DSH_USE_SPI */ #endif /* LIS3DSH_USE_SPI */
} }

View File

@ -1,5 +1,5 @@
/* /*
ChibiOS - Copyright (C) 2016 Rocco Marco Guglielmi ChibiOS - Copyright (C) 2016-2018 Rocco Marco Guglielmi
This file is part of ChibiOS. This file is part of ChibiOS.
@ -43,7 +43,7 @@
/** /**
* @brief LIS3DSH driver version string. * @brief LIS3DSH driver version string.
*/ */
#define EX_LIS3DSH_VERSION "1.0.3" #define EX_LIS3DSH_VERSION "1.0.4"
/** /**
* @brief LIS3DSH driver version major number. * @brief LIS3DSH driver version major number.
@ -58,27 +58,32 @@
/** /**
* @brief LIS3DSH driver version patch number. * @brief LIS3DSH driver version patch number.
*/ */
#define EX_LIS3DSH_PATCH 3 #define EX_LIS3DSH_PATCH 4
/** @} */ /** @} */
/** /**
* @brief LIS3DSH characteristics. * @brief LIS3DSH accelerometer subsystem characteristics.
* @note Sensitivity is expressed as milli-G/LSB whereas
* 1 milli-G = 0.00980665 m/s^2.
* @note Bias is expressed as milli-G.
* *
* @{ * @{
*/ */
#define LIS3DSH_NUMBER_OF_AXES 3U #define LIS3DSH_ACC_NUMBER_OF_AXES 3U
#define LIS3DSH_2G 2.0f #define LIS3DSH_ACC_2G 2.0f
#define LIS3DSH_4G 4.0f #define LIS3DSH_ACC_4G 4.0f
#define LIS3DSH_6G 6.0f #define LIS3DSH_ACC_6G 6.0f
#define LIS3DSH_8G 8.0f #define LIS3DSH_ACC_8G 8.0f
#define LIS3DSH_16G 16.0f #define LIS3DSH_ACC_16G 16.0f
#define LIS3DSH_SENS_2G 0.06f #define LIS3DSH_ACC_SENS_2G 0.06f
#define LIS3DSH_SENS_4G 0.12f #define LIS3DSH_ACC_SENS_4G 0.12f
#define LIS3DSH_SENS_6G 0.18f #define LIS3DSH_ACC_SENS_6G 0.18f
#define LIS3DSH_SENS_8G 0.24f #define LIS3DSH_ACC_SENS_8G 0.24f
#define LIS3DSH_SENS_16G 0.73f #define LIS3DSH_ACC_SENS_16G 0.73f
#define LIS3DSH_ACC_BIAS 0.0f
/** @} */ /** @} */
/** /**
@ -201,84 +206,84 @@
* @name LIS3DSH_CTRL_REG1 register bits definitions * @name LIS3DSH_CTRL_REG1 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG1_MASK 0xE9 /**< LIS3DSH_CTRL_REG1 mask */ #define LIS3DSH_CTRL_REG1_MASK 0xE9
#define LIS3DSH_CTRL_REG1_SM1_EN (1 << 0) /**< SM1 enabled */ #define LIS3DSH_CTRL_REG1_SM1_EN (1 << 0)
#define LIS3DSH_CTRL_REG1_SM1_PIN (1 << 3) /**< SM1 pin */ #define LIS3DSH_CTRL_REG1_SM1_PIN (1 << 3)
#define LIS3DSH_CTRL_REG1_HYST0_1 (1 << 5) /**< Hysteresis 1 bit 0 */ #define LIS3DSH_CTRL_REG1_HYST0_1 (1 << 5)
#define LIS3DSH_CTRL_REG1_HYST1_1 (1 << 6) /**< Hysteresis 1 bit 1 */ #define LIS3DSH_CTRL_REG1_HYST1_1 (1 << 6)
#define LIS3DSH_CTRL_REG1_HYST2_1 (1 << 7) /**< Hysteresis 1 bit 2 */ #define LIS3DSH_CTRL_REG1_HYST2_1 (1 << 7)
/** @} */ /** @} */
/** /**
* @name LIS3DSH_CTRL_REG2 register bits definitions * @name LIS3DSH_CTRL_REG2 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG2_MASK 0xE9 /**< LIS3DSH_CTRL_REG2 mask */ #define LIS3DSH_CTRL_REG2_MASK 0xE9
#define LIS3DSH_CTRL_REG2_SM2_EN (1 << 0) /**< SM2 enabled */ #define LIS3DSH_CTRL_REG2_SM2_EN (1 << 0)
#define LIS3DSH_CTRL_REG2_SM2_PIN (1 << 3) /**< SM2 pin */ #define LIS3DSH_CTRL_REG2_SM2_PIN (1 << 3)
#define LIS3DSH_CTRL_REG2_HYST0_2 (1 << 5) /**< Hysteresis 2 bit 0 */ #define LIS3DSH_CTRL_REG2_HYST0_2 (1 << 5)
#define LIS3DSH_CTRL_REG2_HYST1_2 (1 << 6) /**< Hysteresis 2 bit 1 */ #define LIS3DSH_CTRL_REG2_HYST1_2 (1 << 6)
#define LIS3DSH_CTRL_REG2_HYST2_2 (1 << 7) /**< Hysteresis 2 bit 2 */ #define LIS3DSH_CTRL_REG2_HYST2_2 (1 << 7)
/** @} */ /** @} */
/** /**
* @name LIS3DSH_CTRL_REG3 register bits definitions * @name LIS3DSH_CTRL_REG3 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG3_MASK 0xFF /**< LIS3DSH_CTRL_REG3 mask */ #define LIS3DSH_CTRL_REG3_MASK 0xFF
#define LIS3DSH_CTRL_REG3_STRT (1 << 0) /**< Soft reset bit */ #define LIS3DSH_CTRL_REG3_STRT (1 << 0)
#define LIS3DSH_CTRL_REG3_VFILT (1 << 2) /**< Vector filter */ #define LIS3DSH_CTRL_REG3_VFILT (1 << 2)
#define LIS3DSH_CTRL_REG3_INT1_EN (1 << 3) /**< Interrupt 1 enable */ #define LIS3DSH_CTRL_REG3_INT1_EN (1 << 3)
#define LIS3DSH_CTRL_REG3_INT2_EN (1 << 4) /**< Interrupt 2 enable */ #define LIS3DSH_CTRL_REG3_INT2_EN (1 << 4)
#define LIS3DSH_CTRL_REG3_IEL (1 << 5) /**< Interrupt latching */ #define LIS3DSH_CTRL_REG3_IEL (1 << 5)
#define LIS3DSH_CTRL_REG3_IEA (1 << 6) /**< Interurpt polarity */ #define LIS3DSH_CTRL_REG3_IEA (1 << 6)
#define LIS3DSH_CTRL_REG3_DR_EN (1 << 7) /**< Data ready signal */ #define LIS3DSH_CTRL_REG3_DR_EN (1 << 7)
/** @} */ /** @} */
/** /**
* @name LIS3DSH_CTRL_REG4 register bits definitions * @name LIS3DSH_CTRL_REG4 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG4_MASK 0xFF /**< LIS3DSH_CTRL_REG4 mask */ #define LIS3DSH_CTRL_REG4_MASK 0xFF
#define LIS3DSH_CTRL_REG4_XEN (1 << 0) /**< X axis enable */ #define LIS3DSH_CTRL_REG4_XEN (1 << 0)
#define LIS3DSH_CTRL_REG4_YEN (1 << 1) /**< Y axis enable */ #define LIS3DSH_CTRL_REG4_YEN (1 << 1)
#define LIS3DSH_CTRL_REG4_ZEN (1 << 2) /**< Z axis enable */ #define LIS3DSH_CTRL_REG4_ZEN (1 << 2)
#define LIS3DSH_CTRL_REG4_BDU (1 << 3) /**< Block data update */ #define LIS3DSH_CTRL_REG4_BDU (1 << 3)
#define LIS3DSH_CTRL_REG4_ODR_0 (1 << 4) /**< Output data rate bit 0 */ #define LIS3DSH_CTRL_REG4_ODR_0 (1 << 4)
#define LIS3DSH_CTRL_REG4_ODR_1 (1 << 5) /**< Output data rate bit 1 */ #define LIS3DSH_CTRL_REG4_ODR_1 (1 << 5)
#define LIS3DSH_CTRL_REG4_ODR_2 (1 << 6) /**< Output data rate bit 2 */ #define LIS3DSH_CTRL_REG4_ODR_2 (1 << 6)
#define LIS3DSH_CTRL_REG4_ODR_3 (1 << 7) /**< Output data rate bit 3 */ #define LIS3DSH_CTRL_REG4_ODR_3 (1 << 7)
/** @} */ /** @} */
/** /**
* @name LIS3DSH_CTRL_REG5 register bits definitions * @name LIS3DSH_CTRL_REG5 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG5_MASK 0xFF /**< LIS3DSH_CTRL_REG5 mask */ #define LIS3DSH_CTRL_REG5_MASK 0xFF
#define LIS3DSH_CTRL_REG5_SIM (1 << 0) /**< SPI interface mode */ #define LIS3DSH_CTRL_REG5_SIM (1 << 0)
#define LIS3DSH_CTRL_REG5_ST1 (1 << 1) /**< Self test bit 1 */ #define LIS3DSH_CTRL_REG5_ST1 (1 << 1)
#define LIS3DSH_CTRL_REG5_ST2 (1 << 2) /**< Self test bit 2 */ #define LIS3DSH_CTRL_REG5_ST2 (1 << 2)
#define LIS3DSH_CTRL_REG5_FS_MASK 0x38 /**< Full scale field mask */ #define LIS3DSH_CTRL_REG5_FS_MASK 0x38
#define LIS3DSH_CTRL_REG5_FS0 (1 << 3) /**< Full scale bit 0 */ #define LIS3DSH_CTRL_REG5_FS0 (1 << 3)
#define LIS3DSH_CTRL_REG5_FS1 (1 << 4) /**< Full scale bit 1 */ #define LIS3DSH_CTRL_REG5_FS1 (1 << 4)
#define LIS3DSH_CTRL_REG5_FS2 (1 << 5) /**< Full scale bit 2 */ #define LIS3DSH_CTRL_REG5_FS2 (1 << 5)
#define LIS3DSH_CTRL_REG5_BW1 (1 << 6) /**< Bandwidth bit 1 */ #define LIS3DSH_CTRL_REG5_BW1 (1 << 6)
#define LIS3DSH_CTRL_REG5_BW2 (1 << 7) /**< Bandwidth bit 2 */ #define LIS3DSH_CTRL_REG5_BW2 (1 << 7)
/** @} */ /** @} */
/** /**
* @name LIS3DSH_CTRL_REG6 register bits definitions * @name LIS3DSH_CTRL_REG6 register bits definitions
* @{ * @{
*/ */
#define LIS3DSH_CTRL_REG6_MASK 0xFF /**< LIS3DSH_CTRL_REG6 mask */ #define LIS3DSH_CTRL_REG6_MASK 0xFF
#define LIS3DSH_CTRL_REG6_P2_BOOT (1 << 0) /**< Boot on Interrupt 2 */ #define LIS3DSH_CTRL_REG6_P2_BOOT (1 << 0)
#define LIS3DSH_CTRL_REG6_P1_OVRUN (1 << 1) /**< FIFO overrun on Int 1 */ #define LIS3DSH_CTRL_REG6_P1_OVRUN (1 << 1)
#define LIS3DSH_CTRL_REG6_P1_WTM (1 << 2) /**< FIFO watermark on Int 1 */ #define LIS3DSH_CTRL_REG6_P1_WTM (1 << 2)
#define LIS3DSH_CTRL_REG6_P1_EMPTY (1 << 3) /**< FIFO empty on Int 1 */ #define LIS3DSH_CTRL_REG6_P1_EMPTY (1 << 3)
#define LIS3DSH_CTRL_REG6_ADD_INC (1 << 4) /**< Register address incr. */ #define LIS3DSH_CTRL_REG6_ADD_INC (1 << 4)
#define LIS3DSH_CTRL_REG6_WTM_EN (1 << 5) /**< Enable FIFO watermark */ #define LIS3DSH_CTRL_REG6_WTM_EN (1 << 5)
#define LIS3DSH_CTRL_REG6_FIFO_EN (1 << 6) /**< Enable FIFO */ #define LIS3DSH_CTRL_REG6_FIFO_EN (1 << 6)
#define LIS3DSH_CTRL_REG6_BOOT (1 << 7) /**< Force reboot */ #define LIS3DSH_CTRL_REG6_BOOT (1 << 7)
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -308,12 +313,12 @@
#endif #endif
/** /**
* @brief LIS3DSH advanced configurations switch. * @brief LIS3DSH accelerometer subsystem advanced configurations switch.
* @details If set to @p TRUE more configurations are available. * @details If set to @p TRUE more configurations are available.
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#if !defined(LIS3DSH_USE_ADVANCED) || defined(__DOXYGEN__) #if !defined(LIS3DSH_ACC_USE_ADVANCED) || defined(__DOXYGEN__)
#define LIS3DSH_USE_ADVANCED FALSE #define LIS3DSH_ACC_USE_ADVANCED FALSE
#endif #endif
/** /**
@ -347,6 +352,10 @@
#error "LIS3DSH_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION" #error "LIS3DSH_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
#endif #endif
#if LIS3DSH_USE_I2C
#error "LIS3DSH's I2C support is not supported."
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
@ -355,50 +364,55 @@
* @name LIS3DSH data structures and types * @name LIS3DSH data structures and types
* @{ * @{
*/ */
/**
* @brief Structure representing a LIS3DSH driver.
*/
typedef struct LIS3DSHDriver LIS3DSHDriver;
/** /**
* @brief LIS3DSH full scale. * @brief LIS3DSH full scale.
*/ */
typedef enum { typedef enum {
LIS3DSH_FS_2G = 0x00, /**< Full scale ±2g. */ LIS3DSH_ACC_FS_2G = 0x00, /**< Full scale ±2g. */
LIS3DSH_FS_4G = 0x08, /**< Full scale ±4g. */ LIS3DSH_ACC_FS_4G = 0x08, /**< Full scale ±4g. */
LIS3DSH_FS_6G = 0x10, /**< Full scale ±6g. */ LIS3DSH_ACC_FS_6G = 0x10, /**< Full scale ±6g. */
LIS3DSH_FS_8G = 0x18, /**< Full scale ±8g. */ LIS3DSH_ACC_FS_8G = 0x18, /**< Full scale ±8g. */
LIS3DSH_FS_16G = 0x20 /**< Full scale ±16g. */ LIS3DSH_ACC_FS_16G = 0x20 /**< Full scale ±16g. */
}lis3dsh_fs_t; }lis3dsh_acc_fs_t;
/** /**
* @brief LIS3DSH output data rate. * @brief LIS3DSH output data rate.
*/ */
typedef enum { typedef enum {
LIS3DSH_ODR_PD = 0x00, /**< ODR 100 Hz. */ LIS3DSH_ACC_ODR_PD = 0x00, /**< ODR 100 Hz. */
LIS3DSH_ODR_3_125HZ = 0x10, /**< ODR 3.125 Hz. */ LIS3DSH_ACC_ODR_3_125HZ = 0x10, /**< ODR 3.125 Hz. */
LIS3DSH_ODR_6_25HZ = 0x20, /**< ODR 6.25 Hz. */ LIS3DSH_ACC_ODR_6_25HZ = 0x20, /**< ODR 6.25 Hz. */
LIS3DSH_ODR_12_5HZ = 0x30, /**< ODR 12.5 Hz. */ LIS3DSH_ACC_ODR_12_5HZ = 0x30, /**< ODR 12.5 Hz. */
LIS3DSH_ODR_25HZ = 0x40, /**< ODR 25 Hz. */ LIS3DSH_ACC_ODR_25HZ = 0x40, /**< ODR 25 Hz. */
LIS3DSH_ODR_50HZ = 0x50, /**< ODR 50 Hz. */ LIS3DSH_ACC_ODR_50HZ = 0x50, /**< ODR 50 Hz. */
LIS3DSH_ODR_100HZ = 0x60, /**< ODR 100 Hz. */ LIS3DSH_ACC_ODR_100HZ = 0x60, /**< ODR 100 Hz. */
LIS3DSH_ODR_400HZ = 0x70, /**< ODR 400 Hz. */ LIS3DSH_ACC_ODR_400HZ = 0x70, /**< ODR 400 Hz. */
LIS3DSH_ODR_800HZ = 0x80, /**< ODR 800 Hz. */ LIS3DSH_ACC_ODR_800HZ = 0x80, /**< ODR 800 Hz. */
LIS3DSH_ODR_1600HZ = 0x90 /**< ODR 1600 Hz. */ LIS3DSH_ACC_ODR_1600HZ = 0x90 /**< ODR 1600 Hz. */
}lis3dsh_odr_t; }lis3dsh_acc_odr_t;
/** /**
* @brief LIS3DSH anti-aliasing bandwidth. * @brief LIS3DSH anti-aliasing bandwidth.
*/ */
typedef enum { typedef enum {
LIS3DSH_BW_800HZ = 0x00, /**< AA filter BW 800Hz. */ LIS3DSH_ACC_BW_800HZ = 0x00, /**< AA filter BW 800Hz. */
LIS3DSH_BW_200HZ = 0x40, /**< AA filter BW 200Hz. */ LIS3DSH_ACC_BW_200HZ = 0x40, /**< AA filter BW 200Hz. */
LIS3DSH_BW_400HZ = 0x80, /**< AA filter BW 400Hz. */ LIS3DSH_ACC_BW_400HZ = 0x80, /**< AA filter BW 400Hz. */
LIS3DSH_BW_50HZ = 0xC0 /**< AA filter BW 50Hz. */ LIS3DSH_ACC_BW_50HZ = 0xC0 /**< AA filter BW 50Hz. */
}lis3dsh_bw_t; }lis3dsh_acc_bw_t;
/** /**
* @brief LIS3DSH block data update. * @brief LIS3DSH block data update.
*/ */
typedef enum { typedef enum {
LIS3DSH_BDU_CONTINUOUS = 0x00, /**< Block data continuously updated. */ LIS3DSH_ACC_BDU_CONTINUOUS = 0x00,/**< Block data continuously updated. */
LIS3DSH_BDU_BLOCKED = 0x80 /**< Block data updated after reading. */ LIS3DSH_ACC_BDU_BLOCKED = 0x80 /**< Block data updated after reading. */
} lis3dsh_bdu_t; } lis3dsh_acc_bdu_t;
/** /**
* @brief Driver state machine possible states. * @brief Driver state machine possible states.
@ -435,94 +449,86 @@ typedef struct {
const I2CConfig *i2ccfg; const I2CConfig *i2ccfg;
#endif /* LIS3DSH_USE_I2C */ #endif /* LIS3DSH_USE_I2C */
/** /**
* @brief LIS3DSH initial sensitivity. * @brief LIS3DSH accelerometer subsystem initial sensitivity.
*/ */
float *sensitivity; float *accsensitivity;
/** /**
* @brief LIS3DSH initial bias. * @brief LIS3DSH accelerometer subsystem initial bias.
*/ */
float *bias; float *accbias;
/** /**
* @brief LIS3DSH full scale value. * @brief LIS3DSH accelerometer subsystem initial full scale.
*/ */
lis3dsh_fs_t fullscale; lis3dsh_acc_fs_t accfullscale;
/** /**
* @brief LIS3DSH output data rate selection. * @brief LIS3DSH output data rate selection.
*/ */
lis3dsh_odr_t outputdatarate; lis3dsh_acc_odr_t accoutputdatarate;
#if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__) #if LIS3DSH_ACC_USE_ADVANCED || defined(__DOXYGEN__)
/** /**
* @brief LIS3DSH anti-aliasing bandwidth. * @brief LIS3DSH anti-aliasing bandwidth.
*/ */
lis3dsh_bw_t antialiasing; lis3dsh_acc_bw_t accantialiasing;
/** /**
* @brief LIS3DSH block data update. * @brief LIS3DSH block data update.
*/ */
lis3dsh_bdu_t blockdataupdate; lis3dsh_acc_bdu_t accblockdataupdate;
#endif #endif
} LIS3DSHConfig; } LIS3DSHConfig;
/** /**
* @brief @p LIS3DSH accelerometer subsystem specific methods. * @brief @p LIS3DSH specific methods.
*/ */
#define _lis3dsh_accelerometer_methods_alone \ #define _lis3dsh_methods_alone \
/* Change full scale value of LIS3DSH accelerometer subsystem .*/ \ /* Change full scale value of LIS3DSH accelerometer subsystem.*/ \
msg_t (*set_full_scale)(void *instance, lis3dsh_fs_t fs); msg_t (*acc_set_full_scale)(LIS3DSHDriver *instance, lis3dsh_acc_fs_t fs);
/** /**
* @brief @p LIS3DSH accelerometer subsystems specific methods with inherited * @brief @p LIS3DSH specific methods with inherited
* ones. * ones.
*/ */
#define _lis3dsh_accelerometer_methods \ #define _lis3dsh_methods \
_base_accelerometer_methods \ _base_object_methods \
_lis3dsh_accelerometer_methods_alone _lis3dsh_methods_alone
/** /**
* @extends BaseAccelerometerVMT * @extends BaseObjectVMT
* *
* @brief @p LIS3DSH accelerometer virtual methods table. * @brief @p LIS3DSH virtual methods table.
*/ */
struct LIS3DSHAccelerometerVMT { struct LIS3DSHVMT {
_lis3dsh_accelerometer_methods _lis3dsh_methods
}; };
/** /**
* @brief @p LIS3DSHDriver specific data. * @brief @p LIS3DSHDriver specific data.
*/ */
#define _lis3dsh_data \ #define _lis3dsh_data \
_base_sensor_data \
/* Driver state.*/ \ /* Driver state.*/ \
lis3dsh_state_t state; \ lis3dsh_state_t state; \
/* Current configuration data.*/ \ /* Current configuration data.*/ \
const LIS3DSHConfig *config; \ const LIS3DSHConfig *config; \
/* Current sensitivity.*/ \ /* Accelerometer subsystem axes number.*/ \
float sensitivity[LIS3DSH_NUMBER_OF_AXES]; \ size_t accaxes; \
/* Bias data.*/ \ /* Accelerometer subsystem current sensitivity.*/ \
int32_t bias[LIS3DSH_NUMBER_OF_AXES]; \ float accsensitivity[LIS3DSH_ACC_NUMBER_OF_AXES]; \
/* Current full scale value.*/ \ /* Accelerometer subsystem current bias .*/ \
float fullscale; float accbias[LIS3DSH_ACC_NUMBER_OF_AXES]; \
/* Accelerometer subsystem current full scale value.*/ \
float accfullscale;
/** /**
* @extends BaseAccelerometer
*
* @brief LIS3DSH 3-axis accelerometer class. * @brief LIS3DSH 3-axis accelerometer class.
* @details This class extends @p BaseAccelerometer by adding physical
* driver implementation.
*/ */
struct LIS3DSHDriver { struct LIS3DSHDriver {
/** @brief BaseSensor Virtual Methods Table. */ /** @brief Virtual Methods Table.*/
const struct BaseSensorVMT *vmt_sensor; const struct LIS3DSHVMT *vmt;
_base_sensor_data /** @brief Base accelerometer interface.*/
/** @brief LIS3DSH Accelerometer Virtual Methods Table. */ BaseAccelerometer acc_if;
const struct LIS3DSHAccelerometerVMT *vmt_accelerometer;
_base_accelerometer_data
_lis3dsh_data _lis3dsh_data
}; };
/**
* @brief Structure representing a LIS3DSH driver.
*/
typedef struct LIS3DSHDriver LIS3DSHDriver;
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -530,18 +536,141 @@ typedef struct LIS3DSHDriver LIS3DSHDriver;
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief Change accelerometer fullscale value. * @brief Return the number of axes of the BaseAccelerometer.
* *
* @param[in] ip pointer to a @p LIS3DSHDriver class. * @param[in] devp pointer to @p LIS3DSHDriver.
* @param[in] fs the new full scale value. *
* @return the number of axes.
*
* @api
*/
#define lis3dshAccelerometerGetAxesNumber(devp) \
accelerometerGetAxesNumber(&((devp)->acc_if))
/**
* @brief Retrieves raw data from the BaseAccelerometer.
* @note This data is retrieved from MEMS register without any algebraical
* manipulation.
* @note The axes array must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
* @param[out] axes a buffer which would be filled with raw data.
* *
* @return The operation status. * @return The operation status.
* @retval MSG_OK if the function succeeded. * @retval MSG_OK if the function succeeded.
* @retval MSG_RESET if one or more errors occurred. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
* be retrieved using @p i2cGetErrors().
* @retval MSG_TIMEOUT if a timeout occurred before operation end.
*
* @api * @api
*/ */
#define accelerometerSetFullScale(ip, fs) \ #define lis3dshAccelerometerReadRaw(devp, axes) \
(ip)->vmt_accelerometer->set_full_scale(ip, fs) accelerometerReadRaw(&((devp)->acc_if), axes)
/**
* @brief Retrieves cooked data from the BaseAccelerometer.
* @note This data is manipulated according to the formula
* cooked = (raw * sensitivity) - bias.
* @note Final data is expressed as milli-G.
* @note The axes array must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
* @param[out] axes a buffer which would be filled with cooked data.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET if one or more I2C errors occurred, the errors can
* be retrieved using @p i2cGetErrors().
* @retval MSG_TIMEOUT if a timeout occurred before operation end.
*
* @api
*/
#define lis3dshAccelerometerReadCooked(devp, axes) \
accelerometerReadCooked(&((devp)->acc_if), axes)
/**
* @brief Set bias values for the BaseAccelerometer.
* @note Bias must be expressed as milli-G.
* @note The bias buffer must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
* @param[in] bp a buffer which contains biases.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*
* @api
*/
#define lis3dshAccelerometerSetBias(devp, bp) \
accelerometerSetBias(&((devp)->acc_if), bp)
/**
* @brief Reset bias values for the BaseAccelerometer.
* @note Default biases value are obtained from device datasheet when
* available otherwise they are considered zero.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*
* @api
*/
#define lis3dshAccelerometerResetBias(devp) \
accelerometerResetBias(&((devp)->acc_if))
/**
* @brief Set sensitivity values for the BaseAccelerometer.
* @note Sensitivity must be expressed as milli-G/LSB.
* @note The sensitivity buffer must be at least the same size of the
* BaseAccelerometer axes number.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
* @param[in] sp a buffer which contains sensitivities.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
*
* @api
*/
#define lis3dshAccelerometerSetSensitivity(devp, sp) \
accelerometerSetSensitivity(&((devp)->acc_if), sp)
/**
* @brief Reset sensitivity values for the BaseAccelerometer.
* @note Default sensitivities value are obtained from device datasheet.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET otherwise.
*
* @api
*/
#define lis3dshAccelerometerResetSensitivity(devp) \
accelerometerResetSensitivity(&((devp)->acc_if))
/**
* @brief Changes the LIS3DSHDriver accelerometer fullscale value.
* @note This function also rescale sensitivities and biases based on
* previous and next fullscale value.
* @note A recalibration is highly suggested after calling this function.
*
* @param[in] devp pointer to @p LIS3DSHDriver.
* @param[in] fs new fullscale value.
*
* @return The operation status.
* @retval MSG_OK if the function succeeded.
* @retval MSG_RESET otherwise.
*
* @api
*/
#define lis3dshAccelerometerSetFullScale(devp, fs) \
(devp)->vmt->acc_set_full_scale(devp, fs)
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -87,6 +87,9 @@ PROJECT = ch
# Imported source files and paths # Imported source files and paths
CHIBIOS = ../../../.. CHIBIOS = ../../../..
# Licensing files.
include $(CHIBIOS)/os/license/license.mk
# Startup files. # Startup files.
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
# HAL-OSAL files (optional). # HAL-OSAL files (optional).
@ -97,10 +100,10 @@ include $(CHIBIOS)/os/hal/osal/rt/osal.mk
# RTOS files (optional). # RTOS files (optional).
include $(CHIBIOS)/os/rt/rt.mk include $(CHIBIOS)/os/rt/rt.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
# Other files (optional). # EX files (optional)..
include $(CHIBIOS)/os/ex/ST/lis3dsh.mk include $(CHIBIOS)/os/ex/ST/lis3dsh.mk
# Other files (optional).
include $(CHIBIOS)/os/hal/lib/streams/streams.mk include $(CHIBIOS)/os/hal/lib/streams/streams.mk
include $(CHIBIOS)/os/various/shell/shell.mk
# Define linker script file here # Define linker script file here
LDSCRIPT= $(STARTUPLD)/STM32F407xG.ld LDSCRIPT= $(STARTUPLD)/STM32F407xG.ld
@ -119,9 +122,15 @@ CSRC = $(STARTUPSRC) \
$(SHELLSRC) \ $(SHELLSRC) \
usbcfg.c main.c usbcfg.c main.c
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(ALLCSRC) \
$(TESTSRC) \
usbcfg.c main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global # C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting. # setting.
CPPSRC = CPPSRC = $(ALLCPPSRC)
# C sources to be compiled in ARM mode regardless of the global setting. # C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
@ -147,10 +156,7 @@ TCPPSRC =
ASMSRC = ASMSRC =
ASMXSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) ASMXSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
INCDIR = $(CHIBIOS)/os/license \ INCDIR = $(ALLINC) $(TESTINC)
$(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
$(HALINC) $(PLATFORMINC) $(BOARDINC) $(LIS3DSHINC) \
$(STREAMSINC) $(SHELLINC)
# #
# Project, sources and paths # Project, sources and paths
@ -200,7 +206,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 \
-DLIS3DSH_USE_ADVANCED=0 -DLIS3DSH_SHARED_SPI=0 -DLIS3DSH_USE_ADVANCED=0 -DLIS3DSH_SHARED_SPI=0
# Define ASM defines here # Define ASM defines here

View File

@ -33,7 +33,7 @@
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/> <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/> <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;null-lis3dshStart-(format)&quot; val=&quot;2&quot;/&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/> <stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;null-lis3dshStart-(format)&quot; val=&quot;2&quot;/&gt;&lt;/contentList&gt;"/>
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/> <stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/> <stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/> <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>

View File

@ -18,12 +18,11 @@
#include "hal.h" #include "hal.h"
#include "usbcfg.h" #include "usbcfg.h"
#include "string.h"
#include "shell.h"
#include "chprintf.h" #include "chprintf.h"
#include "lis3dsh.h" #include "lis3dsh.h"
#define cls(chp) chprintf(chp, "\033[2J\033[1;1H")
/*===========================================================================*/ /*===========================================================================*/
/* LIS3DSH related. */ /* LIS3DSH related. */
/*===========================================================================*/ /*===========================================================================*/
@ -31,10 +30,11 @@
/* LIS3DSH Driver: This object represent an LIS3DSH instance */ /* LIS3DSH Driver: This object represent an LIS3DSH instance */
static LIS3DSHDriver LIS3DSHD1; static LIS3DSHDriver LIS3DSHD1;
static int32_t rawdata[LIS3DSH_NUMBER_OF_AXES]; static int32_t accraw[LIS3DSH_ACC_NUMBER_OF_AXES];
static float cookeddata[LIS3DSH_NUMBER_OF_AXES];
static char axisID[LIS3DSH_NUMBER_OF_AXES] = {'X', 'Y', 'Z'}; static float acccooked[LIS3DSH_ACC_NUMBER_OF_AXES];
static char axisID[LIS3DSH_ACC_NUMBER_OF_AXES] = {'X', 'Y', 'Z'};
static uint32_t i; static uint32_t i;
static const SPIConfig spicfg = { static const SPIConfig spicfg = {
@ -51,108 +51,19 @@ static LIS3DSHConfig lis3dshcfg = {
&spicfg, &spicfg,
NULL, NULL,
NULL, NULL,
LIS3DSH_FS_2G, LIS3DSH_ACC_FS_2G,
LIS3DSH_ODR_100HZ, LIS3DSH_ACC_ODR_100HZ,
#if LIS3DSH_USE_ADVANCED #if LIS3DSH_USE_ADVANCED
LIS3DSH_BW_400HZ, LIS3DSH_ACC_BW_400HZ,
LIS3DSH_BDU_CONTINUOUS, LIS3DSH_ACC_BDU_CONTINUOUS,
#endif #endif
}; };
/*===========================================================================*/ /*===========================================================================*/
/* Command line related. */ /* Generic code. */
/*===========================================================================*/
/* Enable use of special ANSI escape sequences.*/
#define CHPRINTF_USE_ANSI_CODE TRUE
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048)
static void cmd_read(BaseSequentialStream *chp, int argc, char *argv[]) {
(void)argv;
if (argc != 1) {
chprintf(chp, "Usage: read [raw|cooked]\r\n");
return;
}
while (chnGetTimeout((BaseChannel *)chp, 150) == Q_TIMEOUT) {
if (!strcmp (argv[0], "raw")) {
#if CHPRINTF_USE_ANSI_CODE
chprintf(chp, "\033[2J\033[1;1H");
#endif
accelerometerReadRaw(&LIS3DSHD1, rawdata);
chprintf(chp, "LIS3DSH Accelerometer raw data...\r\n");
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) {
chprintf(chp, "%c-axis: %d\r\n", axisID[i], rawdata[i]);
}
}
else if (!strcmp (argv[0], "cooked")) {
#if CHPRINTF_USE_ANSI_CODE
chprintf(chp, "\033[2J\033[1;1H");
#endif
accelerometerReadCooked(&LIS3DSHD1, cookeddata);
chprintf(chp, "LIS3DSH Accelerometer cooked data...\r\n");
for(i = 0; i < LIS3DSH_NUMBER_OF_AXES; i++) {
chprintf(chp, "%c-axis: %.4f mg\r\n", axisID[i], cookeddata[i]);
}
}
else {
chprintf(chp, "Usage: read [raw|cooked]\r\n");
return;
}
}
chprintf(chp, "Stopped\r\n");
}
static void cmd_fullscale(BaseSequentialStream *chp, int argc, char *argv[]) {
(void)argv;
if (argc != 1) {
chprintf(chp, "Usage: fullscale [2G|4G|6G|8G|16G]\r\n");
return;
}
#if CHPRINTF_USE_ANSI_CODE
chprintf(chp, "\033[2J\033[1;1H");
#endif
if(!strcmp (argv[0], "2G")) {
accelerometerSetFullScale(&LIS3DSHD1, LIS3DSH_FS_2G);
chprintf(chp, "LIS3DSH Accelerometer full scale set to 2G...\r\n");
}
else if(!strcmp (argv[0], "4G")) {
accelerometerSetFullScale(&LIS3DSHD1, LIS3DSH_FS_4G);
chprintf(chp, "LIS3DSH Accelerometer full scale set to 4G...\r\n");
}
else if(!strcmp (argv[0], "6G")) {
accelerometerSetFullScale(&LIS3DSHD1, LIS3DSH_FS_6G);
chprintf(chp, "LIS3DSH Accelerometer full scale set to 6G...\r\n");
}
else if(!strcmp (argv[0], "8G")) {
accelerometerSetFullScale(&LIS3DSHD1, LIS3DSH_FS_8G);
chprintf(chp, "LIS3DSH Accelerometer full scale set to 8G...\r\n");
}
else if(!strcmp (argv[0], "16G")) {
accelerometerSetFullScale(&LIS3DSHD1, LIS3DSH_FS_16G);
chprintf(chp, "LIS3DSH Accelerometer full scale set to 16G...\r\n");
}
else {
chprintf(chp, "Usage: fullscale [2G|4G|6G|8G|16G]\r\n");
return;
}
}
static const ShellCommand commands[] = {
{"read", cmd_read},
{"fullscale", cmd_fullscale},
{NULL, NULL}
};
static const ShellConfig shell_cfg1 = {
(BaseSequentialStream *)&SDU1,
commands
};
/*===========================================================================*/
/* Main code. */
/*===========================================================================*/ /*===========================================================================*/
static BaseSequentialStream* chp = (BaseSequentialStream*)&SDU1;
/* /*
* LED blinker thread, times are in milliseconds. * LED blinker thread, times are in milliseconds.
*/ */
@ -165,9 +76,7 @@ static THD_FUNCTION(Thread1, arg) {
systime_t time; systime_t time;
time = serusbcfg.usbp->state == USB_ACTIVE ? 250 : 500; time = serusbcfg.usbp->state == USB_ACTIVE ? 250 : 500;
palClearLine(LINE_LED6); palToggleLine(LINE_LED6);
chThdSleepMilliseconds(time);
palSetLine(LINE_LED6);
chThdSleepMilliseconds(time); chThdSleepMilliseconds(time);
} }
} }
@ -210,18 +119,21 @@ int main(void) {
/* Activates the LIS3DSH driver.*/ /* Activates the LIS3DSH driver.*/
lis3dshStart(&LIS3DSHD1, &lis3dshcfg); lis3dshStart(&LIS3DSHD1, &lis3dshcfg);
/* Shell manager initialization.*/ /* Normal main() thread activity, printing MEMS data on the SDU1.*/
shellInit(); while (true) {
lis3dshAccelerometerReadRaw(&LIS3DSHD1, accraw);
while(TRUE) { chprintf(chp, "LIS3DSH Accelerometer raw data...\r\n");
if (SDU1.config->usbp->state == USB_ACTIVE) { for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, chprintf(chp, "%c-axis: %d\r\n", axisID[i], accraw[i]);
"shell", NORMALPRIO + 1,
shellThread, (void *)&shell_cfg1);
chThdWait(shelltp); /* Waiting termination. */
} }
chThdSleepMilliseconds(1000);
lis3dshAccelerometerReadCooked(&LIS3DSHD1, acccooked);
chprintf(chp, "LIS3DSH Accelerometer cooked data...\r\n");
for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
chprintf(chp, "%c-axis: %.3f\r\n", axisID[i], acccooked[i]);
}
chThdSleepMilliseconds(100);
cls(chp);
} }
lis3dshStop(&LIS3DSHD1); lis3dshStop(&LIS3DSHD1);
return 0;
} }

View File

@ -1,15 +1,19 @@
***************************************************************************** *****************************************************************************
** ChibiOS/HAL - USB-CDC driver demo for STM32. ** ** ChibiOS/HAL + ChibiOS/EX - SPI + LIS3DSH demo for STM32F4xx. **
***************************************************************************** *****************************************************************************
** TARGET ** ** TARGET **
The demo runs on both Olimex STM32-E407 or STM32F4-Discovery boards, just The demo runs on an STM32F407 Discovery board REV C or later.
change the board reference in the Makefile.
** The Demo ** ** The Demo **
The application demonstrates the use of the STM32 USB (OTG) driver. The application demonstrates the use of the STM32F4xx SPI driver in order
to acquire data from LIS3DSH using ChibiOS/EX.
** Board Setup **
None required.
** Build Procedure ** ** Build Procedure **
@ -24,4 +28,4 @@ ST Microelectronics and are licensed under a different license.
Also note that not all the files present in the ST library are distributed Also note that not all the files present in the ST library are distributed
with ChibiOS/RT, you can find the whole library on the ST web site: with ChibiOS/RT, you can find the whole library on the ST web site:
http://www.st.com http://www.st.com