diff --git a/README.md b/README.md index 9fef5e7..a365066 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ This package contains the Bosch Sensortec's BMI160 sensor driver (sensor API) The sensor driver package includes bmi160.h, bmi160.c and bmi160_defs.h files ## Version -File | Version | Date ------|---------|----- -bmi160.c | 3.5.0 | 13 Apr 2017 -bmi160.h | 3.5.0 | 13 Apr 2017 -bmi160_defs.h | 3.5.0 | 13 Apr 2017 +File | Version | Date +--------------|---------|--------------- +bmi160.c | 3.6.0 | 04 Aug 2017 +bmi160.h | 3.6.0 | 04 Aug 2017 +bmi160_defs.h | 3.6.0 | 04 Aug 2017 ## Integration details * Integrate bmi160.h, bmi160_defs.h and bmi160.c file in to your project. @@ -518,4 +518,130 @@ int8_t fifo_gyro_header_time_data(struct bmi160_dev *dev) } ``` +## FOC and offset compensation +> FOC shouldnot be used in Low-power mode +#### Example for configuring FOC for accel and gyro +``` +/* An example for configuring FOC for accel and gyro data */ +int8_t start_foc(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + /* FOC configuration structure */ + struct bmi160_foc_conf foc_conf; + /* Structure to store the offsets */ + struct bmi160_offsets offsets; + + /* Enable FOC for accel with target values of z = 1g ; x,y as 0g */ + foc_conf.acc_off_en = BMI160_ENABLE; + foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; + foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; + foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; + + /* Enable FOC for gyro */ + foc_conf.foc_gyr_en = BMI160_ENABLE; + foc_conf.gyro_off_en = BMI160_ENABLE; + + rslt = bmi160_start_foc(&foc_conf, &offsets, sen); + + if (rslt == BMI160_OK) { + printf("\n FOC DONE SUCCESSFULLY "); + printf("\n OFFSET VALUES AFTER FOC : "); + printf("\n OFFSET VALUES ACCEL X : %d ",offsets.off_acc_x); + printf("\n OFFSET VALUES ACCEL Y : %d ",offsets.off_acc_y); + printf("\n OFFSET VALUES ACCEL Z : %d ",offsets.off_acc_z); + printf("\n OFFSET VALUES GYRO X : %d ",offsets.off_gyro_x); + printf("\n OFFSET VALUES GYRO Y : %d ",offsets.off_gyro_y); + printf("\n OFFSET VALUES GYRO Z : %d ",offsets.off_gyro_z); + } + + /* After start of FOC offsets will be updated automatically and + * the data will be very much close to the target values of measurement */ + + return rslt; +} +``` + +#### Example for updating the offsets manually +> The offsets set by this method will be reset on soft-reset/POR +``` +/* An example for updating manual offsets to sensor */ +int8_t write_offsets(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + /* FOC configuration structure */ + struct bmi160_foc_conf foc_conf; + /* Structure to store the offsets */ + struct bmi160_offsets offsets; + + /* Enable offset update for accel */ + foc_conf.acc_off_en = BMI160_ENABLE; + + /* Enable offset update for gyro */ + foc_conf.gyro_off_en = BMI160_ENABLE; + + /* offset values set by user */ + offsets.off_acc_x = 0x10; + offsets.off_acc_y = 0x10; + offsets.off_acc_z = 0x10; + offsets.off_gyro_x = 0x10; + offsets.off_gyro_y = 0x10; + offsets.off_gyro_z = 0x10; + + rslt = bmi160_set_offsets(&foc_conf, &offsets, sen); + + /* After offset setting the data read from the + * sensor will have the corresponding offset */ + + return rslt; +} +``` + +#### Example for updating the offsets into NVM +> The offsets set by this method will be present in NVM and will be +> restored on POR/soft-reset +``` +/* An example for updating manual offsets to sensor */ +int8_t write_offsets_nvm(struct bmi160_dev *dev) +{ + int8_t rslt = 0; + /* FOC configuration structure */ + struct bmi160_foc_conf foc_conf; + /* Structure to store the offsets */ + struct bmi160_offsets offsets; + + /* Enable offset update for accel */ + foc_conf.acc_off_en = BMI160_ENABLE; + + /* Enable offset update for gyro */ + foc_conf.gyro_off_en = BMI160_ENABLE; + + /* offset values set by user as per their reference + * Resolution of accel = 3.9mg/LSB + * Resolution of gyro = (0.061degrees/second)/LSB */ + offsets.off_acc_x = 10; + offsets.off_acc_y = -15; + offsets.off_acc_z = 20; + offsets.off_gyro_x = 30; + offsets.off_gyro_y = -35; + offsets.off_gyro_z = -40; + + rslt = bmi160_set_offsets(&foc_conf, &offsets, sen); + + if (rslt == BMI160_OK) { + /* Update the NVM */ + rslt = bmi160_update_nvm(dev); + } + + /* After this procedure the offsets are written to + * NVM and restored on POR/soft-reset + * The set values can be removed to ideal case by + * invoking the following APIs + * - bmi160_start_foc() + * - bmi160_update_nvm() + */ + + return rslt; +} +``` + ## Copyright (C) 2016 - 2017 Bosch Sensortec GmbH \ No newline at end of file diff --git a/bmi160.c b/bmi160.c index 643e97e..f5a5208 100644 --- a/bmi160.c +++ b/bmi160.c @@ -40,8 +40,8 @@ * patent rights of the copyright holder. * * @file bmi160.c - * @date 13 Apr 2017 - * @version 3.5.0 + * @date 04 Aug 2017 + * @version 3.6.0 * @brief * */ @@ -1298,8 +1298,8 @@ static void move_next_frame(uint16_t *data_index, uint8_t current_frame_length, * FIFO data in the structure instance dev. * * @param[in,out] data_index : Index of the FIFO data which - * has the sensor time. - * @param[in] dev : Structure instance of bma4_dev. + * has the sensor time. + * @param[in] dev : Structure instance of bmi160_dev. * * @return Result of API execution status * @retval zero -> Success / -ve value -> Error @@ -1310,15 +1310,50 @@ static void unpack_sensortime_frame(uint16_t *data_index, const struct bmi160_de * @brief This API is used to parse and store the skipped_frame_count from * the FIFO data in the structure instance dev. * - * @param[in,out] data_index : Index of the FIFO data which + * @param[in,out] data_index : Index of the FIFO data which * has the skipped frame count. - * @param[in] dev : Structure instance of bma4_dev. + * @param[in] dev : Structure instance of bmi160_dev. * * @return Result of API execution status * @retval zero -> Success / -ve value -> Error */ static void unpack_skipped_frame(uint16_t *data_index, const struct bmi160_dev *dev); +/*! + * @brief This API is used to get the FOC status from the sensor + * + * @param[in,out] foc_status : Result of FOC status. + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t get_foc_status(uint8_t *foc_status, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + * + * @param[in,out] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC and offset configurations + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t configure_offset_enable(const struct bmi160_foc_conf *foc_conf, struct bmi160_dev const *dev); + +/*! + * @brief This API is used to trigger the FOC in the sensor + * + * @param[in,out] offset : Structure instance of bmi160_offsets which + * reads and stores the offset values after FOC + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval zero -> Success / -ve value -> Error + */ +static int8_t trigger_foc(struct bmi160_offsets *offset, struct bmi160_dev const *dev); + /*********************** User function definitions ****************************/ /*! @@ -1911,7 +1946,7 @@ int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev) uint8_t addr = BMI160_FIFO_DATA_ADDR; /* check the bmi160 structure as NULL*/ - if (dev == NULL || dev->fifo->data == NULL) { + if ((dev == NULL) || (dev->fifo->data == NULL)) { rslt = BMI160_E_NULL_PTR; } else { reset_fifo_data_structure(dev); @@ -1925,7 +1960,8 @@ int8_t bmi160_get_fifo_data(struct bmi160_dev const *dev) dev->fifo->length = bytes_to_read; } - if ((dev->fifo->fifo_time_enable == BMI160_FIFO_TIME_ENABLE) && (bytes_to_read + 4 <= user_fifo_len)) { + if ((dev->fifo->fifo_time_enable == BMI160_FIFO_TIME_ENABLE) + && (bytes_to_read + 4 <= user_fifo_len)) { /* Handling case of sensor time availability */ dev->fifo->length = dev->fifo->length + 4; } @@ -2130,6 +2166,193 @@ int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_l return rslt; } +/*! + * @brief This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + */ +int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, struct bmi160_offsets *offset, + struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + if (rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Set the offset enable bits */ + rslt = configure_offset_enable(foc_conf, dev); + if (rslt == BMI160_OK) { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + + /* Set the FOC config for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_FOC_EN, foc_conf->foc_gyr_en); + + /* Set the FOC config for accel xyz axes */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_X_CONF, foc_conf->foc_acc_x); + data = BMI160_SET_BITS(data, BMI160_ACCEL_FOC_Y_CONF, foc_conf->foc_acc_y); + data = BMI160_SET_BITS_POS_0(data, BMI160_ACCEL_FOC_Z_CONF, foc_conf->foc_acc_z); + + if (rslt == BMI160_OK) { + /* Set the FOC config in the sensor */ + rslt = bmi160_set_regs(BMI160_FOC_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) { + /* Procedure to trigger + * FOC and check status */ + rslt = trigger_foc(offset, dev); + } + } + } + } + + return rslt; +} + +/*! + * @brief This API reads and stores the offset values of accel and gyro + */ +int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev) +{ + int8_t rslt; + uint8_t data[7]; + uint8_t lsb, msb; + int16_t offset_msb, offset_lsb; + int16_t offset_data; + + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + if (rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_ADDR, data, 7, dev); + + /* Accel offsets */ + offset->off_acc_x = (int8_t)data[0]; + offset->off_acc_y = (int8_t)data[1]; + offset->off_acc_z = (int8_t)data[2]; + + /* Gyro x-axis offset */ + lsb = data[3]; + msb = BMI160_GET_BITS_POS_0(data[6], BMI160_GYRO_OFFSET_X); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_x = (int16_t)(offset_data / 64); + + /* Gyro y-axis offset */ + lsb = data[4]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Y); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_y = (int16_t)(offset_data / 64); + + /* Gyro z-axis offset */ + lsb = data[5]; + msb = BMI160_GET_BITS(data[6], BMI160_GYRO_OFFSET_Z); + offset_msb = (int16_t)(msb << 14); + offset_lsb = lsb << 6; + offset_data = offset_msb | offset_lsb; + /* Divide by 64 to get the Right shift by 6 value */ + offset->off_gyro_z = (int16_t)(offset_data / 64); + } + + return rslt; +} + +/*! + * @brief This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + */ +int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, const struct bmi160_offsets *offset, + struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data[7]; + uint8_t x_msb, y_msb, z_msb; + + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + if (rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Update the accel offset */ + data[0] = (uint8_t)offset->off_acc_x; + data[1] = (uint8_t)offset->off_acc_y; + data[2] = (uint8_t)offset->off_acc_z; + + /* Update the LSB of gyro offset */ + data[3] = BMI160_GET_LSB(offset->off_gyro_x); + data[4] = BMI160_GET_LSB(offset->off_gyro_y); + data[5] = BMI160_GET_LSB(offset->off_gyro_z); + + /* Update the MSB of gyro offset */ + x_msb = BMI160_GET_BITS(offset->off_gyro_x, BMI160_GYRO_OFFSET); + y_msb = BMI160_GET_BITS(offset->off_gyro_y, BMI160_GYRO_OFFSET); + z_msb = BMI160_GET_BITS(offset->off_gyro_z, BMI160_GYRO_OFFSET); + data[6] = (uint8_t)(z_msb << 4 | y_msb << 2 | x_msb); + + /* Set the offset enable/disable for gyro and accel */ + data[6] = BMI160_SET_BITS(data[6], BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + data[6] = BMI160_SET_BITS(data[6], BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config and values in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_ADDR, data, 7, dev); + } + + return rslt; +} + +/*! + * @brief This API writes the image registers values to NVM which is + * stored even after POR or soft reset + */ +int8_t bmi160_update_nvm(struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + uint8_t cmd = BMI160_NVM_BACKUP_EN; + + /* Read the nvm_prog_en configuration */ + rslt = bmi160_get_regs(BMI160_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) { + data = BMI160_SET_BITS(data, BMI160_NVM_UPDATE, 1); + /* Set the nvm_prog_en bit in the sensor */ + rslt = bmi160_set_regs(BMI160_CONF_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) { + /* Update NVM */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if (rslt == BMI160_OK) { + /* Check for NVM ready status */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) { + data = BMI160_GET_BITS(data, BMI160_NVM_STATUS); + if (data != BMI160_ENABLE) { + /* Delay to update NVM */ + dev->delay_ms(25); + } + } + } + } + } + + return rslt; +} + /*********************** Local function definitions ***************************/ /*! @@ -2776,7 +2999,7 @@ static int8_t set_accel_pwr(struct bmi160_dev *dev) if (dev->accel_cfg.power != dev->prev_accel_cfg.power) { rslt = process_under_sampling(&data, dev); if (rslt == BMI160_OK) { - /* Write accel power */ + /* Write accel power */ rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &dev->accel_cfg.power, 1, dev); /* Add delay of 5 ms */ if (dev->prev_accel_cfg.power == BMI160_ACCEL_SUSPEND_MODE) @@ -5272,4 +5495,97 @@ static void unpack_skipped_frame(uint16_t *data_index, const struct bmi160_dev * } } +/*! + * @brief This API is used to get the FOC status from the sensor + */ +static int8_t get_foc_status(uint8_t *foc_status, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Read the FOC status from sensor */ + rslt = bmi160_get_regs(BMI160_STATUS_ADDR, &data, 1, dev); + if (rslt == BMI160_OK) { + /* Get the foc_status bit */ + *foc_status = BMI160_GET_BITS(data, BMI160_FOC_STATUS); + } + + return rslt; +} + +/*! + * @brief This API is used to configure the offset enable bits in the sensor + */ +static int8_t configure_offset_enable(const struct bmi160_foc_conf *foc_conf, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t data; + + /* Null-pointer check */ + rslt = null_ptr_check(dev); + + if (rslt != BMI160_OK) { + rslt = BMI160_E_NULL_PTR; + } else { + /* Read the FOC config from the sensor */ + rslt = bmi160_get_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + + if (rslt == BMI160_OK) { + /* Set the offset enable/disable for gyro */ + data = BMI160_SET_BITS(data, BMI160_GYRO_OFFSET_EN, foc_conf->gyro_off_en); + + /* Set the offset enable/disable for accel */ + data = BMI160_SET_BITS(data, BMI160_ACCEL_OFFSET_EN, foc_conf->acc_off_en); + + /* Set the offset config in the sensor */ + rslt = bmi160_set_regs(BMI160_OFFSET_CONF_ADDR, &data, 1, dev); + } + } + + return rslt; +} + +static int8_t trigger_foc(struct bmi160_offsets *offset, struct bmi160_dev const *dev) +{ + int8_t rslt; + uint8_t foc_status; + uint8_t cmd = BMI160_START_FOC_CMD; + uint8_t timeout = 0; + uint8_t data_array[20]; + + /* Start the FOC process */ + rslt = bmi160_set_regs(BMI160_COMMAND_REG_ADDR, &cmd, 1, dev); + if (rslt == BMI160_OK) { + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + if ((rslt != BMI160_OK) || (foc_status != BMI160_ENABLE)) { + while ((foc_status != BMI160_ENABLE) && (timeout < 11)) { + /* Maximum time of 250ms is given in 10 + * steps of 25ms each */ + dev->delay_ms(25); + /* Check the FOC status*/ + rslt = get_foc_status(&foc_status, dev); + timeout++; + } + + if ((rslt == BMI160_OK) && (foc_status == BMI160_ENABLE)) { + /* Get offset values from sensor */ + rslt = bmi160_get_offsets(offset, dev); + } else { + /* FOC failure case */ + rslt = BMI160_FOC_FAILURE; + } + } + + if (rslt == BMI160_OK) { + /* Read registers 0x04-0x17 */ + rslt = bmi160_get_regs(BMI160_GYRO_DATA_ADDR, + data_array, 20, dev); + } + } + + + return rslt; +} + /** @}*/ diff --git a/bmi160.h b/bmi160.h index ba076e6..cec6038 100644 --- a/bmi160.h +++ b/bmi160.h @@ -40,8 +40,8 @@ * patent rights of the copyright holder. * * @file bmi160.h - * @date 13 Apr 2017 - * @version 3.5.0 + * @date 04 Aug 2017 + * @version 3.6.0 * @brief * */ @@ -516,6 +516,99 @@ int8_t bmi160_extract_accel(struct bmi160_sensor_data *accel_data, uint8_t *acce */ int8_t bmi160_extract_gyro(struct bmi160_sensor_data *gyro_data, uint8_t *gyro_length, struct bmi160_dev const *dev); +/*! + * @brief This API starts the FOC of accel and gyro + * + * @note FOC should not be used in low-power mode of sensor + * + * @note Accel FOC targets values of +1g , 0g , -1g + * Gyro FOC always targets value of 0 dps + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in,out] offset : Structure instance to store Offset + * values read from sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Pre-requisites for triggering FOC in accel , Set the following, + * Enable the acc_off_en + * Ex : foc_conf.acc_off_en = BMI160_ENABLE; + * + * Set the desired target values of FOC to each axes (x,y,z) by using the + * following macros + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + * + * Ex : foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; + * foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; + * + * @note Pre-requisites for triggering FOC in gyro , + * Set the following parameters, + * + * Ex : foc_conf.foc_gyr_en = BMI160_ENABLE; + * foc_conf.gyro_off_en = BMI160_ENABLE; + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_start_foc(const struct bmi160_foc_conf *foc_conf, struct bmi160_offsets *offset, + struct bmi160_dev const *dev); + +/*! + * @brief This API reads and stores the offset values of accel and gyro + * + * @param[in,out] offset : Structure instance of bmi160_offsets in which + * the offset values are read and stored + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_get_offsets(struct bmi160_offsets *offset, const struct bmi160_dev *dev); + +/*! + * @brief This API writes the offset values of accel and gyro to + * the sensor but these values will be reset on POR or soft reset. + * + * @param[in] foc_conf : Structure instance of bmi160_foc_conf which + * has the FOC configuration + * @param[in] offset : Structure instance in which user updates offset + * values which are to be written in the sensor + * @param[in] dev : Structure instance of bmi160_dev. + * + * @note Offsets can be set by user like offset->off_acc_x = 10; + * where 1LSB = 3.9mg and for gyro 1LSB = 0.061degrees/second + * + * @note BMI160 offset values for xyz axes of accel should be within range of + * BMI160_ACCEL_MIN_OFFSET (-128) to BMI160_ACCEL_MAX_OFFSET (127) + * + * @note BMI160 offset values for xyz axes of gyro should be within range of + * BMI160_GYRO_MIN_OFFSET (-512) to BMI160_GYRO_MAX_OFFSET (511) + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_set_offsets(const struct bmi160_foc_conf *foc_conf, const struct bmi160_offsets *offset, + struct bmi160_dev const *dev); + +/*! + * @brief This API writes the image registers values to NVM which is + * stored even after POR or soft reset + * + * @param[in] dev : Structure instance of bmi160_dev. + * + * @return Result of API execution status + * @retval 0 -> Success + * @retval Any non zero value -> Fail + */ +int8_t bmi160_update_nvm(struct bmi160_dev const *dev); + #ifdef __cplusplus } #endif diff --git a/bmi160_defs.h b/bmi160_defs.h index a9188cf..2e3ab21 100644 --- a/bmi160_defs.h +++ b/bmi160_defs.h @@ -40,8 +40,8 @@ * patent rights of the copyright holder. * * @file bmi160_defs.h - * @date 13 Apr 2017 - * @version 3.5.0 + * @date 04 Aug 2017 + * @version 3.6.0 * @brief * */ @@ -57,6 +57,7 @@ /*************************** C types headers *****************************/ #ifdef __KERNEL__ #include +#include #else #include #include @@ -69,11 +70,13 @@ extern "C" #endif /*************************** Common macros *****************************/ +#ifdef __KERNEL__ #if (LONG_MAX) > 0x7fffffff #define __have_long64 1 #elif (LONG_MAX) == 0x7fffffff #define __have_long32 1 #endif +#endif #if !defined(UINT8_C) #define INT8_C(x) x @@ -302,7 +305,6 @@ extern "C" #define BMI160_AUX_IF_2_ADDR UINT8_C(0x4D) #define BMI160_AUX_IF_3_ADDR UINT8_C(0x4E) #define BMI160_AUX_IF_4_ADDR UINT8_C(0x4F) - #define BMI160_INT_ENABLE_0_ADDR UINT8_C(0x50) #define BMI160_INT_ENABLE_1_ADDR UINT8_C(0x51) #define BMI160_INT_ENABLE_2_ADDR UINT8_C(0x52) @@ -328,8 +330,13 @@ extern "C" #define BMI160_INT_ORIENT_1_ADDR UINT8_C(0x66) #define BMI160_INT_FLAT_0_ADDR UINT8_C(0x67) #define BMI160_INT_FLAT_1_ADDR UINT8_C(0x68) +#define BMI160_FOC_CONF_ADDR UINT8_C(0x69) +#define BMI160_CONF_ADDR UINT8_C(0x6A) + #define BMI160_IF_CONF_ADDR UINT8_C(0x6B) #define BMI160_SELF_TEST_ADDR UINT8_C(0x6D) +#define BMI160_OFFSET_ADDR UINT8_C(0x71) +#define BMI160_OFFSET_CONF_ADDR UINT8_C(0x77) #define BMI160_INT_STEP_CNT_0_ADDR UINT8_C(0x78) #define BMI160_INT_STEP_CONFIG_0_ADDR UINT8_C(0x7A) #define BMI160_INT_STEP_CONFIG_1_ADDR UINT8_C(0x7B) @@ -349,6 +356,7 @@ extern "C" #define BMI160_E_LWP_PRE_FLTR_INT_INVALID INT8_C(-8) #define BMI160_E_LWP_PRE_FLTR_INVALID INT8_C(-9) #define BMI160_E_AUX_NOT_FOUND INT8_C(-10) +#define BMI160_FOC_FAILURE INT8_C(-11) /**\name API warning codes */ #define BMI160_W_GYRO_SELF_TEST_FAIL INT8_C(1) @@ -360,6 +368,10 @@ extern "C" /** Soft reset command */ #define BMI160_SOFT_RESET_CMD UINT8_C(0xb6) #define BMI160_SOFT_RESET_DELAY_MS UINT8_C(15) +/** Start FOC command */ +#define BMI160_START_FOC_CMD UINT8_C(0x03) +/** NVM backup enabling command */ +#define BMI160_NVM_BACKUP_EN UINT8_C(0xA0) /* Delay in ms settings */ #define BMI160_ACCEL_DELAY_MS UINT8_C(5) @@ -547,6 +559,12 @@ extern "C" #define FIFO_CONFIG_MSB_CHECK UINT8_C(0x80) #define FIFO_CONFIG_LSB_CHECK UINT8_C(0x00) +/*! BMI160 accel FOC configurations */ +#define BMI160_FOC_ACCEL_DISABLED UINT8_C(0x00) +#define BMI160_FOC_ACCEL_POSITIVE_G UINT8_C(0x01) +#define BMI160_FOC_ACCEL_NEGATIVE_G UINT8_C(0x02) +#define BMI160_FOC_ACCEL_0G UINT8_C(0x03) + /** Array Parameter DefinItions */ #define BMI160_SENSOR_TIME_LSB_BYTE UINT8_C(0) #define BMI160_SENSOR_TIME_XLSB_BYTE UINT8_C(1) @@ -589,6 +607,14 @@ extern "C" /** BMI160 fifo flush Command */ #define BMI160_FIFO_FLUSH_VALUE UINT8_C(0xB0) +/** BMI160 offset values for xyz axes of accel */ +#define BMI160_ACCEL_MIN_OFFSET INT8_C(-128) +#define BMI160_ACCEL_MAX_OFFSET INT8_C(127) + +/** BMI160 offset values for xyz axes of gyro */ +#define BMI160_GYRO_MIN_OFFSET INT16_C(-512) +#define BMI160_GYRO_MAX_OFFSET INT16_C(511) + /** BMI160 fifo full interrupt position and mask */ #define BMI160_FIFO_FULL_INT_POS UINT8_C(5) #define BMI160_FIFO_FULL_INT_MSK UINT8_C(0x20) @@ -615,6 +641,43 @@ extern "C" #define BMI160_GYRO_SELF_TEST_STATUS_POS UINT8_C(1) #define BMI160_GYRO_SELF_TEST_STATUS_MSK UINT8_C(0x02) +#define BMI160_GYRO_FOC_EN_POS UINT8_C(6) +#define BMI160_GYRO_FOC_EN_MSK UINT8_C(0x40) + +#define BMI160_ACCEL_FOC_X_CONF_POS UINT8_C(4) +#define BMI160_ACCEL_FOC_X_CONF_MSK UINT8_C(0x30) + +#define BMI160_ACCEL_FOC_Y_CONF_POS UINT8_C(2) +#define BMI160_ACCEL_FOC_Y_CONF_MSK UINT8_C(0x0C) + +#define BMI160_ACCEL_FOC_Z_CONF_MSK UINT8_C(0x03) + +#define BMI160_FOC_STATUS_POS UINT8_C(3) +#define BMI160_FOC_STATUS_MSK UINT8_C(0x08) + +#define BMI160_GYRO_OFFSET_X_MSK UINT8_C(0x03) + +#define BMI160_GYRO_OFFSET_Y_POS UINT8_C(2) +#define BMI160_GYRO_OFFSET_Y_MSK UINT8_C(0x0C) + +#define BMI160_GYRO_OFFSET_Z_POS UINT8_C(4) +#define BMI160_GYRO_OFFSET_Z_MSK UINT8_C(0x30) + +#define BMI160_GYRO_OFFSET_EN_POS UINT8_C(7) +#define BMI160_GYRO_OFFSET_EN_MSK UINT8_C(0x80) + +#define BMI160_ACCEL_OFFSET_EN_POS UINT8_C(6) +#define BMI160_ACCEL_OFFSET_EN_MSK UINT8_C(0x40) + + +#define BMI160_GYRO_OFFSET_POS UINT16_C(8) +#define BMI160_GYRO_OFFSET_MSK UINT16_C(0x0300) + +#define BMI160_NVM_UPDATE_POS UINT8_C(1) +#define BMI160_NVM_UPDATE_MSK UINT8_C(0x02) + +#define BMI160_NVM_STATUS_POS UINT8_C(4) +#define BMI160_NVM_STATUS_MSK UINT8_C(0x10) /* BIT SLICE GET AND SET FUNCTIONS */ #define BMI160_GET_BITS(regvar, bitname)\ @@ -629,6 +692,13 @@ extern "C" #define BMI160_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) +/**\name UTILITY MACROS */ +#define BMI160_SET_LOW_BYTE UINT16_C(0x00FF) +#define BMI160_SET_HIGH_BYTE UINT16_C(0xFF00) + +#define BMI160_GET_LSB(var) (uint8_t)(var & BMI160_SET_LOW_BYTE) +#define BMI160_GET_MSB(var) (uint8_t)((var & BMI160_SET_HIGH_BYTE) >> 8) + /*****************************************************************************/ /* type definitions */ typedef int8_t (*bmi160_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, @@ -652,6 +722,61 @@ struct bmi160_sensor_data { uint32_t sensortime; }; +/*! + * @brief bmi160 FOC configuration structure + */ +struct bmi160_foc_conf { + /*! Enabling FOC in gyro + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t foc_gyr_en; + + /*! Accel FOC configurations + * Assignable macros : + * - BMI160_FOC_ACCEL_DISABLED + * - BMI160_FOC_ACCEL_POSITIVE_G + * - BMI160_FOC_ACCEL_NEGATIVE_G + * - BMI160_FOC_ACCEL_0G + */ + uint8_t foc_acc_x; + uint8_t foc_acc_y; + uint8_t foc_acc_z; + + /*! Enabling offset compensation for accel in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t acc_off_en; + + /*! Enabling offset compensation for gyro in data registers + * Assignable macros : + * - BMI160_ENABLE + * - BMI160_DISABLE + */ + uint8_t gyro_off_en; +}; + +/*! + * @brief bmi160 accel gyro offsets + */ +struct bmi160_offsets { + /*! Accel offset for x axis */ + int8_t off_acc_x; + /*! Accel offset for y axis */ + int8_t off_acc_y; + /*! Accel offset for z axis */ + int8_t off_acc_z; + /*! Gyro offset for x axis */ + int16_t off_gyro_x; + /*! Gyro offset for y axis */ + int16_t off_gyro_y; + /*! Gyro offset for z axis */ + int16_t off_gyro_z; +}; + /*! * @brief FIFO aux. sensor data structure */ diff --git a/changelog.md b/changelog.md index edb7de2..44874dd 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,14 @@ # Change Log All notable changes to bmi160 Sensor API will be documented in this file. +## v3.6.0, 04 Aug 2017 + +#### Added +* Added interfaces for the following features + - FOC + - Manual Offset compensation + - Offset compenation value update to NVM + ## v3.5.0, 13 Apr 2017 #### Added