Skip to content

Commit

Permalink
drivers: sensors: bmi270: Extend public API for bmi270 CRT.
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
peter-axe committed Oct 21, 2023
1 parent 1856833 commit f3c4d22
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 101 deletions.
3 changes: 1 addition & 2 deletions drivers/sensor/bmi270/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 6 additions & 4 deletions drivers/sensor/bmi270/bmi270.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <zephyr/drivers/i2c.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/sensor/bmi270.h>

#define BMI270_REG_CHIP_ID 0x00
#define BMI270_REG_ERROR 0x02
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
135 changes: 40 additions & 95 deletions drivers/sensor/bmi270/bmi270_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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");
}

Expand Down
Loading

0 comments on commit f3c4d22

Please sign in to comment.