From f3c4d22123820684b96cceddf4d79e445c365dab Mon Sep 17 00:00:00 2001 From: Pedro Machado Date: Sat, 21 Oct 2023 12:47:52 +0100 Subject: [PATCH] drivers: sensors: bmi270: Extend public API for bmi270 CRT. Fixes: #62514 This commit extends the public API for bmi270, exposing the sensors attributes for the CRT feature. Also, it moves the CRT test results data to the device driver data structure in order to work with multiple instances of the sensor. Signed-off-by: Pedro Machado --- drivers/sensor/bmi270/Kconfig | 3 +- drivers/sensor/bmi270/bmi270.h | 10 +- drivers/sensor/bmi270/bmi270_crt.c | 135 ++++++++----------------- include/zephyr/drivers/sensor/bmi270.h | 109 ++++++++++++++++++++ 4 files changed, 156 insertions(+), 101 deletions(-) create mode 100644 include/zephyr/drivers/sensor/bmi270.h diff --git a/drivers/sensor/bmi270/Kconfig b/drivers/sensor/bmi270/Kconfig index 25b3dbd223f1e3b..50a2f2f358f4162 100644 --- a/drivers/sensor/bmi270/Kconfig +++ b/drivers/sensor/bmi270/Kconfig @@ -64,8 +64,7 @@ config BMI270_THREAD_STACK_SIZE config BMI270_CRT bool "CRT feature support for bmi270" - default n help - Gyro CRT calibration feature support for bmi270 + BMI270 Gyro Component Re-Trimming(CRT) calibration feature support. endif # BMI270 diff --git a/drivers/sensor/bmi270/bmi270.h b/drivers/sensor/bmi270/bmi270.h index 5bfedb8fa0bfd5f..d2330f5e8154d8c 100644 --- a/drivers/sensor/bmi270/bmi270.h +++ b/drivers/sensor/bmi270/bmi270.h @@ -18,6 +18,7 @@ #include #include #include +#include #define BMI270_REG_CHIP_ID 0x00 #define BMI270_REG_ERROR 0x02 @@ -132,7 +133,6 @@ #define BMI270_GYR_USR_GAIN_MASK 0x7F #define BMI270_GYR_GAIN_EN_MSK BIT(7) #define BMI270_GYR_GAIN_EN_POS 7 -#define BMI270_GYR_GAIN_EN 0x01 #define BMI270_GYR_GAIN_STATUS_SAT_X_POS 0 #define BMI270_GYR_GAIN_STATUS_SAT_X_MASK BIT(0) #define BMI270_GYR_GAIN_STATUS_SAT_Y_POS 1 @@ -146,9 +146,6 @@ #define BMI270_GYR_CRT_CONF_RUNNING_POS 0x02 #define BMI270_GYR_CRT_CONF_RUNNING_EN 0x01 #define BMI270_GYR_CRT_CONF_RUNNING_DIS 0x00 -/* Sensor specific attributes */ -#define BMI270_SENSOR_ATTR_NVM_PROG (SENSOR_ATTR_PRIV_START) -#define BMI270_SENSOR_ATTR_GAIN_COMP (SENSOR_ATTR_PRIV_START + 1) /* Applies to INT1_MAP_FEAT, INT2_MAP_FEAT, INT_STATUS_0 */ #define BMI270_INT_MAP_SIG_MOTION BIT(0) @@ -332,6 +329,11 @@ struct bmi270_data { struct k_work trig_work; #endif #endif /* CONFIG_BMI270_TRIGGER */ +#ifdef CONFIG_BMI270_CRT + /* CRT test results */ + struct bmi2_gyr_user_gain_status crt_result_sts; + struct bmi2_gyro_user_gain_data crt_gain; +#endif /* CONFIG_BMI270_CRT */ }; struct bmi270_feature_reg { diff --git a/drivers/sensor/bmi270/bmi270_crt.c b/drivers/sensor/bmi270/bmi270_crt.c index 8d59804c40fb182..609b7307f3825bc 100644 --- a/drivers/sensor/bmi270/bmi270_crt.c +++ b/drivers/sensor/bmi270/bmi270_crt.c @@ -18,67 +18,6 @@ LOG_MODULE_DECLARE(bmi270, CONFIG_SENSOR_LOG_LEVEL); #define BMI270_NVM_STATUS_CHECK_RETRIES 100 #define BMI270_STATUS_CHECK_POLL_PERIOD_US 10000 -/** @name Enum to define status of gyroscope trigger G_TRIGGER */ -typedef enum { - /*Command is valid*/ - BMI270_CRT_TRIGGER_STAT_SUCCESS = 0x00, - /*Command is aborted due to incomplete pre-conditions*/ - BMI270_CRT_TRIGGER_STAT_PRECON_ERR = 0x01, - /*Command is aborted due to unsuccessful download*/ - BMI270_CRT_TRIGGER_STAT_DL_ERR = 0x02, - /*Command is aborted by host or due to motion detection*/ - BMI270_CRT_TRIGGER_STAT_ABORT_ERR = 0x03 -} GTriggerStatus; - -/** @name Structure to define gyroscope saturation status of user gain - * Describes the saturation status for the gyroscope gain - * update and G_TRIGGER command status - */ -struct bmi2_gyr_user_gain_status { - /* Status in x-axis - * This bit will be 1 if the updated gain - * results to saturated value based on the - * ratio provided for x axis, otherwise it will be 0 - */ - uint8_t sat_x; - - /* Status in y-axis - * This bit will be 1 if the updated gain - * results to saturated value based on the - * ratio provided for y axis, otherwise it will be 0 - */ - uint8_t sat_y; - - /* Status in z-axis - * This bit will be 1 if the updated gain - * results to saturated value based on the - * ratio provided for z axis, otherwise it will be 0 - */ - uint8_t sat_z; - - /* G trigger status - * Status of gyroscope trigger G_TRIGGER command. - * These bits are updated at the end of feature execution . - */ - GTriggerStatus g_trigger_status; -}; - -/** @name Structure to store the compensated user-gain data of gyroscope */ -struct bmi2_gyro_user_gain_data { - /** x-axis */ - int8_t x; - - /** y-axis */ - int8_t y; - - /** z-axis */ - int8_t z; -}; - -/* Global structures to store the CRT test results */ -struct bmi2_gyr_user_gain_status crt_result_sts = {0}; -struct bmi2_gyro_user_gain_data crt_gain = {0}; - /** * @brief This function verifies if advanced power saving mode is enabled * If it enabled, it disables it. @@ -256,7 +195,7 @@ static inline int bmi270_g_trig_1_select_crt(const struct device *dev) } /** @brief Helper method to LOG CRT cmd status */ -static void crt_error_log(GTriggerStatus status) +static void crt_error_log(gtrigger_status status) { switch (status) { case BMI270_CRT_TRIGGER_STAT_SUCCESS: @@ -282,18 +221,16 @@ static void crt_error_log(GTriggerStatus status) * gain update. * * @param[in] dev : Structure instance of bmi270 device - * @param[out] bmi2_gyr_user_gain_status : Structure that stores gyro gain - * CRT test results * * @return Result of select crt enable execution * @retval 0 -> Success * @retval < 0 -> Fail */ -static int bmi270_get_gyro_gain_update_status(const struct device *dev, - struct bmi2_gyr_user_gain_status *result_sts) +static int bmi270_get_gyro_gain_update_status(const struct device *dev) { int ret; const struct bmi270_config *cfg = dev->config; + struct bmi270_data *data = dev->data; const uint8_t result_sts_page = cfg->feature->gyr_gain_status->page; uint16_t status_value; @@ -329,21 +266,26 @@ static int bmi270_get_gyro_gain_update_status(const struct device *dev, LOG_DBG("Read feature reg[0x%02x]@%d = 0x%04x", cfg->feature->gyr_gain_status->addr, result_sts_page, status_value); + /* Get the saturation status for x-axis */ - result_sts->sat_x = (status_value & BMI270_GYR_GAIN_STATUS_SAT_X_MASK) >> + data->crt_result_sts.sat_x = (status_value & BMI270_GYR_GAIN_STATUS_SAT_X_MASK) >> BMI270_GYR_GAIN_STATUS_SAT_X_POS; /* Get the saturation status for y-axis */ - result_sts->sat_y = (status_value & BMI270_GYR_GAIN_STATUS_SAT_Y_MASK) >> + data->crt_result_sts.sat_y = (status_value & BMI270_GYR_GAIN_STATUS_SAT_Y_MASK) >> BMI270_GYR_GAIN_STATUS_SAT_Y_POS; /* Get the saturation status for z-axis */ - result_sts->sat_z = (status_value & BMI270_GYR_GAIN_STATUS_SAT_Z_MASK) >> + data->crt_result_sts.sat_z = (status_value & BMI270_GYR_GAIN_STATUS_SAT_Z_MASK) >> BMI270_GYR_GAIN_STATUS_SAT_Z_POS; /* Get g trigger status */ - result_sts->g_trigger_status = - (GTriggerStatus)((status_value & BMI270_GYR_GAIN_STATUS_G_TRIG_MASK) >> + data->crt_result_sts.g_trigger_status = + (gtrigger_status)((status_value & BMI270_GYR_GAIN_STATUS_G_TRIG_MASK) >> BMI270_GYR_GAIN_STATUS_G_TRIG_POS); - LOG_DBG("Status in x-axis: %d y-axis: %d z-axis %d, gtrigger: %d", result_sts->sat_x, - result_sts->sat_y, result_sts->sat_z, result_sts->g_trigger_status); + + LOG_DBG("Status in x-axis: %d y-axis: %d z-axis %d, gtrigger: %d", + data->crt_result_sts.sat_x, + data->crt_result_sts.sat_y, + data->crt_result_sts.sat_z, + data->crt_result_sts.g_trigger_status); return 0; } @@ -353,19 +295,17 @@ static int bmi270_get_gyro_gain_update_status(const struct device *dev, * gain update. * * @param[in] dev : Structure instance of bmi270 device - * @param[out] bmi2_gyr_user_gain_status : Structure that stores the compensated - * user-gain data of gyroscope * * @return Result of read compensated user-gain data execution * @retval 0 -> Success * @retval < 0 -> Fail */ -static int bmi270_read_gyro_user_gain(const struct device *dev, - struct bmi2_gyro_user_gain_data *gyr_usr_gain) +static int bmi270_read_gyro_user_gain(const struct device *dev) { int ret; /* Variable to define register data */ uint8_t reg_data[3] = {0}; + struct bmi270_data *data = dev->data; /* Get the gyroscope compensated gain values */ ret = bmi270_reg_read(dev, BMI270_GYR_USR_GAIN_0, reg_data, 3); @@ -375,16 +315,16 @@ static int bmi270_read_gyro_user_gain(const struct device *dev, } /* Gyroscope user gain correction X-axis */ - gyr_usr_gain->x = (int8_t)(reg_data[0] & BMI270_GYR_USR_GAIN_MASK); + data->crt_gain.x = (int8_t)(reg_data[0] & BMI270_GYR_USR_GAIN_MASK); /* Gyroscope user gain correction Y-axis */ - gyr_usr_gain->y = (int8_t)(reg_data[1] & BMI270_GYR_USR_GAIN_MASK); + data->crt_gain.y = (int8_t)(reg_data[1] & BMI270_GYR_USR_GAIN_MASK); /* Gyroscope user gain correction z-axis */ - gyr_usr_gain->z = (int8_t)(reg_data[2] & BMI270_GYR_USR_GAIN_MASK); + data->crt_gain.z = (int8_t)(reg_data[2] & BMI270_GYR_USR_GAIN_MASK); - LOG_INF("Gyroscope user gain correction, X: %d Y: %d Z: %d", gyr_usr_gain->x, - gyr_usr_gain->y, gyr_usr_gain->z); + LOG_INF("Gyroscope user gain correction, X: %d Y: %d Z: %d", + data->crt_gain.x, data->crt_gain.y, data->crt_gain.z); return ret; } @@ -408,17 +348,17 @@ static int bmi270_read_gyro_user_gain(const struct device *dev, int bmi270_get_gyro_user_gain(const struct device *dev, struct sensor_value *gain) { int ret; - struct bmi2_gyro_user_gain_data gyr_usr_gain = {0}; + struct bmi270_data *data = dev->data; /* Read user-gain data of gyroscope */ - ret = bmi270_read_gyro_user_gain(dev, &gyr_usr_gain); + ret = bmi270_read_gyro_user_gain(dev); if (ret != 0) { LOG_ERR("Failed in bmi270_read_gyro_user_gain: Error code %d", ret); return ret; } /* Unchanged user-gain data means CRT has not been performed yet */ - if ((gyr_usr_gain.x == 0) && (gyr_usr_gain.y == 0) && (gyr_usr_gain.z == 0)) { + if ((data->crt_gain.x == 0) && (data->crt_gain.y == 0) && (data->crt_gain.z == 0)) { LOG_ERR("CRT has not yet been performed"); return -EAGAIN; } @@ -430,9 +370,9 @@ int bmi270_get_gyro_user_gain(const struct device *dev, struct sensor_value *gai /* Convert compensated user-gain data * into sensor_value type */ - gain->val1 |= gyr_usr_gain.x; - gain->val1 |= (uint32_t)gyr_usr_gain.y << 8; - gain->val1 |= (uint32_t)gyr_usr_gain.z << 16; + gain->val1 |= data->crt_gain.x; + gain->val1 |= (uint32_t)data->crt_gain.y << 8; + gain->val1 |= (uint32_t)data->crt_gain.z << 16; return ret; } @@ -668,14 +608,18 @@ int bmi270_gyro_crt(const struct device *dev) uint8_t tries; const uint8_t g_trigger_cmd = BMI270_CMD_G_TRIGGER; struct bmi2_gyro_user_gain_data before_crt_gain = {0}; + struct bmi270_data *data = dev->data; - /* Initial user gain state */ - ret = bmi270_read_gyro_user_gain(dev, &before_crt_gain); + /* Get initial user gain state */ + ret = bmi270_read_gyro_user_gain(dev); if (ret != 0) { LOG_ERR("Failed in bmi270_read_gyro_user_gain: Error code %d", ret); return ret; } + /* Save initial user gain state */ + memcpy(&before_crt_gain, &(data->crt_gain), sizeof(before_crt_gain)); + /* Disable advanced power save mode */ ret = bmi270_set_aps(BMI270_PWR_CONF_ADV_PWR_SAVE_DIS, dev); if (ret != 0) { @@ -759,28 +703,29 @@ int bmi270_gyro_crt(const struct device *dev) } /* Get CRT results */ - ret = bmi270_get_gyro_gain_update_status(dev, &crt_result_sts); + ret = bmi270_get_gyro_gain_update_status(dev); if (ret != 0) { LOG_ERR("Failed in get_bmi270_crt_results: Error code %d", ret); return ret; } /* Print CRT result status */ - crt_error_log(crt_result_sts.g_trigger_status); + crt_error_log(data->crt_result_sts.g_trigger_status); /* Wait for the gyro gain data to be updated */ k_sleep(K_MSEC(350)); /* Get the gyroscope gain update data */ - ret = bmi270_read_gyro_user_gain(dev, &crt_gain); + ret = bmi270_read_gyro_user_gain(dev); if (ret != 0) { LOG_ERR("Failed in bmi270_read_gyro_user_gain: Error code %d", ret); return ret; } /* Check if new gain values are different */ - if ((before_crt_gain.x == crt_gain.x) && (before_crt_gain.y == crt_gain.y) && - (before_crt_gain.z == crt_gain.z)) { + if ((before_crt_gain.x == data->crt_gain.x) && + (before_crt_gain.y == data->crt_gain.y) && + (before_crt_gain.z == data->crt_gain.z)) { LOG_WRN("CRT new user-gyro gains remained the same"); } diff --git a/include/zephyr/drivers/sensor/bmi270.h b/include/zephyr/drivers/sensor/bmi270.h new file mode 100644 index 000000000000000..bcaf9f014e9f7ef --- /dev/null +++ b/include/zephyr/drivers/sensor/bmi270.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Extended public API for Bosch BMI270 sensor + * + * This exposes an API to the sensor's CRT feature which + * is specific to the application/environment and cannot + * be expressed within the sensor driver abstraction. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_BMI270_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_BMI270_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Sensor specific attributes */ +enum sensor_attribute_bmi270 { + /* Programs the non volatile memory(nvm) of bmi270 */ + BMI270_SENSOR_ATTR_NVM_PROG = SENSOR_ATTR_PRIV_START, + /* Set BMI270 user gain compensation */ + BMI270_SENSOR_ATTR_GAIN_COMP +}; + +/* Macros for setting gyro gain compensation */ +#define BMI270_GYR_GAIN_EN 0x01 +#define BMI270_GYR_GAIN_DIS 0x00 + +/* Helper Macros for setting gyro gain compensation */ +#define SENSOR_VALUE_WITH_GAIN(var_name, gain_value) \ + struct sensor_value var_name = {.val1 = gain_value, .val2 = 0} + +#define SENSOR_ATTR_SET_GAIN_COMPENSATION(dev, gain_value) \ + do { \ + SENSOR_VALUE_WITH_GAIN(_gain_compensation_var, gain_value); \ + sensor_attr_set(dev, SENSOR_CHAN_GYRO_XYZ, \ + BMI270_SENSOR_ATTR_GAIN_COMP, &_gain_compensation_var); \ + } while (0) + +/** @name Enum to define status of gyroscope trigger G_TRIGGER */ +typedef enum { + /*Command is valid*/ + BMI270_CRT_TRIGGER_STAT_SUCCESS = 0x00, + /*Command is aborted due to incomplete pre-conditions*/ + BMI270_CRT_TRIGGER_STAT_PRECON_ERR = 0x01, + /*Command is aborted due to unsuccessful download*/ + BMI270_CRT_TRIGGER_STAT_DL_ERR = 0x02, + /*Command is aborted by host or due to motion detection*/ + BMI270_CRT_TRIGGER_STAT_ABORT_ERR = 0x03 +} gtrigger_status; + +/** @name Structure to define gyroscope saturation status of user gain + * Describes the saturation status for the gyroscope gain + * update and G_TRIGGER command status + */ +struct bmi2_gyr_user_gain_status { + /* Status in x-axis + * This bit will be 1 if the updated gain + * results to saturated value based on the + * ratio provided for x axis, otherwise it will be 0 + */ + uint8_t sat_x; + + /* Status in y-axis + * This bit will be 1 if the updated gain + * results to saturated value based on the + * ratio provided for y axis, otherwise it will be 0 + */ + uint8_t sat_y; + + /* Status in z-axis + * This bit will be 1 if the updated gain + * results to saturated value based on the + * ratio provided for z axis, otherwise it will be 0 + */ + uint8_t sat_z; + + /* G trigger status + * Status of gyroscope trigger G_TRIGGER command. + * These bits are updated at the end of feature execution . + */ + gtrigger_status g_trigger_status; +}; + +/** @name Structure to store the compensated user-gain data of gyroscope */ +struct bmi2_gyro_user_gain_data { + /** x-axis */ + int8_t x; + + /** y-axis */ + int8_t y; + + /** z-axis */ + int8_t z; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_BMI270_H_ */