drivers: sensor: bmm350: nit picky cleanup

There were a lot of places where the return value was sum'ed up
which can be slightly easier to read, but can give an odd return
value in the end. This changes it to just return immediately if
an error is seen.

There was also runtime NULL checking of input arguments that are
rather programmer clown prevention. Change these to asserts.

The return value didn't have a consistant type through the file,
make it consistently an int.

This changes the name of the return value of fix_sign to be
signed_value differenating it from the ret name used elsewhere.

Use the sizeof(buffer) as the argument for reg reads and writes
rather than a hard number.

Some log messages ended with '\n'. Remove all these.

Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
Ryan McClelland 2025-05-20 16:05:23 -07:00 committed by Daniel DeGrasse
parent e636fb2dd1
commit dc6594997c

View File

@ -14,53 +14,65 @@
LOG_MODULE_REGISTER(BMM350, CONFIG_SENSOR_LOG_LEVEL);
static int8_t bmm350_read_otp_word(const struct device *dev, uint8_t addr, uint16_t *lsb_msb)
static int bmm350_read_otp_word(const struct device *dev, uint8_t addr, uint16_t *lsb_msb)
{
int8_t ret = 0;
int ret;
uint8_t tx_buf = 0;
uint8_t rx_buf[3] = {0x00};
uint8_t otp_status = 0;
uint8_t otp_err = BMM350_OTP_STATUS_NO_ERROR;
uint8_t lsb = 0, msb = 0;
if (lsb_msb) {
/* Set OTP command at specified address */
tx_buf = BMM350_OTP_CMD_DIR_READ | (addr & BMM350_OTP_WORD_ADDR_MSK);
ret = bmm350_reg_write(dev, BMM350_REG_OTP_CMD_REG, tx_buf);
if (ret) {
LOG_ERR("i2c xfer failed! read addr = 0x%02x, ret = %d\n", tx_buf, ret);
__ASSERT_NO_MSG(lsb_msb != NULL);
/* Set OTP command at specified address */
tx_buf = BMM350_OTP_CMD_DIR_READ | (addr & BMM350_OTP_WORD_ADDR_MSK);
ret = bmm350_reg_write(dev, BMM350_REG_OTP_CMD_REG, tx_buf);
if (ret != 0) {
LOG_ERR("i2c xfer failed! read addr = 0x%02x, ret = %d", tx_buf, ret);
return ret;
}
do {
/* Get OTP status */
ret = bmm350_reg_read(dev, BMM350_REG_OTP_STATUS_REG, &rx_buf[0], sizeof(rx_buf));
if (ret != 0) {
LOG_ERR("%s: failed to read otp status", dev->name);
return ret;
}
do {
/* Get OTP status */
ret += bmm350_reg_read(dev, BMM350_REG_OTP_STATUS_REG, &rx_buf[0], 3);
otp_status = rx_buf[2];
otp_err = BMM350_OTP_STATUS_ERROR(otp_status);
if (otp_err != BMM350_OTP_STATUS_NO_ERROR) {
break;
}
} while ((!(otp_status & BMM350_OTP_STATUS_CMD_DONE)) && (ret == BMM350_OK));
otp_status = rx_buf[2];
otp_err = BMM350_OTP_STATUS_ERROR(otp_status);
if (otp_err != BMM350_OTP_STATUS_NO_ERROR) {
LOG_ERR("OTP error code: 0x%02x\n", otp_err);
return -EIO;
break;
}
} while ((!(otp_status & BMM350_OTP_STATUS_CMD_DONE)) && (ret == BMM350_OK));
/* Get OTP L/MSB data */
ret += bmm350_reg_read(dev, BMM350_REG_OTP_DATA_MSB_REG, &rx_buf[0], 3);
msb = rx_buf[2];
ret += bmm350_reg_read(dev, BMM350_REG_OTP_DATA_LSB_REG, &rx_buf[0], 3);
lsb = rx_buf[2];
*lsb_msb = ((uint16_t)(msb << 8) | lsb) & 0xFFFF;
if (otp_err != BMM350_OTP_STATUS_NO_ERROR) {
LOG_ERR("OTP error code: 0x%02x", otp_err);
return -EIO;
}
/* Get OTP L/MSB data */
ret = bmm350_reg_read(dev, BMM350_REG_OTP_DATA_MSB_REG, &rx_buf[0], sizeof(rx_buf));
if (ret != 0) {
LOG_ERR("%s: failed to read otp msb data", dev->name);
return ret;
}
msb = rx_buf[2];
ret = bmm350_reg_read(dev, BMM350_REG_OTP_DATA_LSB_REG, &rx_buf[0], sizeof(rx_buf));
if (ret != 0) {
LOG_ERR("%s: failed to read otp lsb data", dev->name);
return ret;
}
lsb = rx_buf[2];
*lsb_msb = ((uint16_t)(msb << 8) | lsb) & 0xFFFF;
return ret;
}
static int32_t fix_sign(uint32_t inval, int8_t number_of_bits)
{
int32_t ret = 0;
int32_t signed_value = 0;
int32_t power = 0;
switch ((enum bmm350_signed_bit)number_of_bits) {
@ -84,12 +96,12 @@ static int32_t fix_sign(uint32_t inval, int8_t number_of_bits)
break;
}
ret = (int32_t)inval;
if (ret >= power) {
ret = ret - (power * 2);
signed_value = (int32_t)inval;
if (signed_value >= power) {
signed_value = signed_value - (power * 2);
}
return ret;
return signed_value;
}
static void bmm350_update_mag_off_sens(struct bmm350_data *data)
@ -202,12 +214,12 @@ static int bmm350_otp_dump_after_boot(const struct device *dev)
data->enable_auto_br = ((data->var_id > BMM350_CURRENT_SHUTTLE_VARIANT_ID) ? BMM350_DISABLE
: BMM350_ENABLE);
LOG_DBG("bmm350 Find the var id %d\n", data->var_id);
LOG_DBG("bmm350 Find the var id %d", data->var_id);
/* Update magnetometer offset and sensitivity data. */
bmm350_update_mag_off_sens(data);
if (ret) {
LOG_ERR("i2c xfer failed, ret = %d\n", ret);
LOG_ERR("i2c xfer failed, ret = %d", ret);
}
return ret;
@ -216,42 +228,41 @@ static int bmm350_otp_dump_after_boot(const struct device *dev)
/*!
* @brief This API gets the PMU command status 0 value
*/
static int8_t bmm350_get_pmu_cmd_status_0(const struct device *dev,
static int bmm350_get_pmu_cmd_status_0(const struct device *dev,
struct bmm350_pmu_cmd_status_0 *pmu_cmd_stat_0)
{
/* Variable to store the function result */
int8_t ret;
int ret;
uint8_t rx_buf[3] = {0x00};
if (pmu_cmd_stat_0 != NULL) {
/* Get PMU command status 0 data */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_STATUS_0, &rx_buf[0], 3);
LOG_DBG("pmu cmd status 0:0x%x\n", rx_buf[2]);
if (ret == BMM350_OK) {
pmu_cmd_stat_0->pmu_cmd_busy =
BMM350_GET_BITS_POS_0(rx_buf[2], BMM350_PMU_CMD_BUSY);
pmu_cmd_stat_0->odr_ovwr = BMM350_GET_BITS(rx_buf[2], BMM350_ODR_OVWR);
pmu_cmd_stat_0->avr_ovwr = BMM350_GET_BITS(rx_buf[2], BMM350_AVG_OVWR);
pmu_cmd_stat_0->pwr_mode_is_normal =
BMM350_GET_BITS(rx_buf[2], BMM350_PWR_MODE_IS_NORMAL);
pmu_cmd_stat_0->cmd_is_illegal =
BMM350_GET_BITS(rx_buf[2], BMM350_CMD_IS_ILLEGAL);
pmu_cmd_stat_0->pmu_cmd_value =
BMM350_GET_BITS(rx_buf[2], BMM350_PMU_CMD_VALUE);
}
} else {
ret = -EINVAL;
__ASSERT_NO_MSG(pmu_cmd_stat_0 != NULL);
/* Get PMU command status 0 data */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_STATUS_0, &rx_buf[0], sizeof(rx_buf));
LOG_DBG("pmu cmd status 0:0x%x", rx_buf[2]);
if (ret == 0) {
pmu_cmd_stat_0->pmu_cmd_busy =
BMM350_GET_BITS_POS_0(rx_buf[2], BMM350_PMU_CMD_BUSY);
pmu_cmd_stat_0->odr_ovwr = BMM350_GET_BITS(rx_buf[2], BMM350_ODR_OVWR);
pmu_cmd_stat_0->avr_ovwr = BMM350_GET_BITS(rx_buf[2], BMM350_AVG_OVWR);
pmu_cmd_stat_0->pwr_mode_is_normal =
BMM350_GET_BITS(rx_buf[2], BMM350_PWR_MODE_IS_NORMAL);
pmu_cmd_stat_0->cmd_is_illegal =
BMM350_GET_BITS(rx_buf[2], BMM350_CMD_IS_ILLEGAL);
pmu_cmd_stat_0->pmu_cmd_value =
BMM350_GET_BITS(rx_buf[2], BMM350_PMU_CMD_VALUE);
}
return ret;
}
/*!
* @brief This internal API is used to switch from suspend mode to normal mode or forced mode.
*/
static int8_t set_powermode(const struct device *dev, enum bmm350_power_modes powermode)
static int set_powermode(const struct device *dev, enum bmm350_power_modes powermode)
{
/* Variable to store the function result */
int8_t ret = 0;
int ret;
uint8_t rx_buf[3] = {0x00};
uint8_t reg_data = powermode;
@ -269,36 +280,34 @@ static int8_t set_powermode(const struct device *dev, enum bmm350_power_modes po
uint8_t avg = 0;
uint32_t delay_us = 0;
if (ret == BMM350_OK) {
/* Get average configuration */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], sizeof(rx_buf));
/* Mask the average value */
avg = ((rx_buf[2] & BMM350_AVG_MSK) >> BMM350_AVG_POS);
if (ret == 0) {
/* Get average configuration */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], 3);
/* Mask the average value */
avg = ((rx_buf[2] & BMM350_AVG_MSK) >> BMM350_AVG_POS);
if (ret == BMM350_OK) {
/* Get average configuration */
if (powermode == BMM350_NORMAL_MODE) {
delay_us = BMM350_SUSPEND_TO_NORMAL_DELAY;
}
/* Check if desired power mode is forced mode */
if (powermode == BMM350_FORCED_MODE) {
/* Store delay based on averaging mode */
delay_us = sus_to_forced_mode[avg];
}
/* Check if desired power mode is forced mode fast */
if (powermode == BMM350_FORCED_MODE_FAST) {
/* Store delay based on averaging mode */
delay_us = sus_to_forced_mode_fast[avg];
}
/* Set PMU command configuration to desired power mode */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, reg_data);
k_usleep(delay_us);
if (powermode == BMM350_NORMAL_MODE) {
delay_us = BMM350_SUSPEND_TO_NORMAL_DELAY;
}
/* Check if desired power mode is forced mode */
if (powermode == BMM350_FORCED_MODE) {
/* Store delay based on averaging mode */
delay_us = sus_to_forced_mode[avg];
}
/* Check if desired power mode is forced mode fast */
if (powermode == BMM350_FORCED_MODE_FAST) {
/* Store delay based on averaging mode */
delay_us = sus_to_forced_mode_fast[avg];
}
/* Set PMU command configuration to desired power mode */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, reg_data);
k_usleep(delay_us);
}
LOG_DBG("pmu cmd agget set powermode %d\n", powermode);
LOG_DBG("pmu cmd agget set powermode %d", powermode);
return ret;
}
@ -306,31 +315,35 @@ static int8_t set_powermode(const struct device *dev, enum bmm350_power_modes po
/*!
* @brief This API is used to set the power mode of the sensor
*/
static int8_t bmm350_set_powermode(const struct device *dev, enum bmm350_power_modes powermode)
static int bmm350_set_powermode(const struct device *dev, enum bmm350_power_modes powermode)
{
/* Variable to store the function result */
int8_t ret = 0;
int ret = 0;
uint8_t rx_buf[3] = {0x00};
if (ret == BMM350_OK) {
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD, &rx_buf[0], 3);
if (ret == BMM350_OK) {
if (rx_buf[2] > BMM350_PMU_CMD_NM_TC) {
ret = -EINVAL;
}
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD, &rx_buf[0], sizeof(rx_buf));
if (ret != 0) {
LOG_ERR("%s: set power mode read failed", dev->name);
return ret;
}
if ((ret == BMM350_OK) && ((rx_buf[2] == BMM350_PMU_CMD_NM) ||
(rx_buf[2] == BMM350_PMU_CMD_UPD_OAE))) {
/* Set PMU command configuration */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_SUS);
}
if (rx_buf[2] > BMM350_PMU_CMD_NM_TC) {
return -EINVAL;
}
if (ret == BMM350_OK) {
ret = set_powermode(dev, powermode);
}
if ((rx_buf[2] == BMM350_PMU_CMD_NM) || (rx_buf[2] == BMM350_PMU_CMD_UPD_OAE)) {
/* Set PMU command configuration */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_SUS);
if (ret != 0) {
LOG_ERR("%s: set PMU cmd failed", dev->name);
}
}
ret = set_powermode(dev, powermode);
if (ret != 0) {
LOG_ERR("%s: set power mode failed", dev->name);
}
return ret;
}
@ -338,277 +351,282 @@ static int8_t bmm350_set_powermode(const struct device *dev, enum bmm350_power_m
* used to perform the magnetic reset of the sensor
* which is necessary after a field shock ( 400mT field applied to sensor )
*/
static int8_t bmm350_magnetic_reset_and_wait(const struct device *dev)
static int bmm350_magnetic_reset_and_wait(const struct device *dev)
{
/* Variable to store the function result */
int8_t ret = 0;
int ret = 0;
struct bmm350_pmu_cmd_status_0 pmu_cmd_stat_0 = {0};
uint8_t restore_normal = BMM350_DISABLE;
/* Read PMU CMD status */
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
LOG_DBG("get status result 0:%d\n", ret);
if (ret != 0) {
LOG_ERR("%s: PMU cmd status read failed", dev->name);
}
/* Check the powermode is normal before performing magnetic reset */
if ((ret == BMM350_OK) && (pmu_cmd_stat_0.pwr_mode_is_normal == BMM350_ENABLE)) {
if (pmu_cmd_stat_0.pwr_mode_is_normal == BMM350_ENABLE) {
restore_normal = BMM350_ENABLE;
/* Reset can only be triggered in suspend */
ret = bmm350_set_powermode(dev, BMM350_SUSPEND_MODE);
LOG_DBG("set power mode 0:%d\n", ret);
}
if (ret == BMM350_OK) {
/* Set BR to PMU_CMD register */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_BR);
k_usleep(BMM350_BR_DELAY);
}
if (ret == BMM350_OK) {
/* Verify if PMU_CMD_STATUS_0 register has BR set */
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
LOG_DBG("get status result 1:%d\n", ret);
if ((ret == BMM350_OK) &&
(pmu_cmd_stat_0.pmu_cmd_value != BMM350_PMU_CMD_STATUS_0_BR)) {
ret = -EIO;
LOG_DBG("set power mode 0:%d", ret);
if (ret != 0) {
LOG_ERR("%s: set power mode failed", dev->name);
return ret;
}
}
if (ret == BMM350_OK) {
/* Set FGR to PMU_CMD register */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_FGR);
k_usleep(BMM350_FGR_DELAY);
/* Set BR to PMU_CMD register */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_BR);
if (ret != 0) {
LOG_ERR("%s: set BR failed", dev->name);
return ret;
}
if (ret == BMM350_OK) {
/* Verify if PMU_CMD_STATUS_0 register has FGR set */
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
LOG_DBG("get status result 2:%d\n", ret);
k_usleep(BMM350_BR_DELAY);
if ((ret == BMM350_OK) &&
(pmu_cmd_stat_0.pmu_cmd_value != BMM350_PMU_CMD_STATUS_0_FGR)) {
ret = -EIO;
}
/* Verify if PMU_CMD_STATUS_0 register has BR set */
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
LOG_DBG("get status result 1:%d", ret);
if (ret != 0) {
LOG_ERR("%s: get PMU cmd status failed", dev->name);
return ret;
}
if (pmu_cmd_stat_0.pmu_cmd_value != BMM350_PMU_CMD_STATUS_0_BR) {
return -EIO;
}
if ((ret == BMM350_OK) && (restore_normal == BMM350_ENABLE)) {
/* Set FGR to PMU_CMD register */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, BMM350_PMU_CMD_FGR);
if (ret != 0) {
LOG_ERR("%s: set FGR failed", dev->name);
return ret;
}
k_usleep(BMM350_FGR_DELAY);
/* Verify if PMU_CMD_STATUS_0 register has FGR set */
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
LOG_DBG("get status result 2:%d", ret);
if (ret != 0) {
LOG_ERR("%s: get PMU cmd status failed", dev->name);
return ret;
}
if (pmu_cmd_stat_0.pmu_cmd_value != BMM350_PMU_CMD_STATUS_0_FGR) {
return -EIO;
}
if (restore_normal == BMM350_ENABLE) {
ret = bmm350_set_powermode(dev, BMM350_NORMAL_MODE);
LOG_DBG("set power mode 1:%d\n", ret);
LOG_DBG("set power mode 1:%d", ret);
} else {
if (ret == BMM350_OK) {
/* Reset PMU_CMD register */
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, 0x00);
}
ret = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, 0x00);
}
return ret;
}
/*!
* @brief This API is used to read uncompensated mag and temperature data.
*/
int8_t bmm350_read_uncomp_mag_temp_data(const struct device *dev,
static int bmm350_read_uncomp_mag_temp_data(const struct device *dev,
struct bmm350_raw_mag_data *raw_data)
{
struct bmm350_data *data = dev->data;
int8_t rslt = BMM350_OK;
int rslt;
uint8_t mag_data[14] = {0};
uint32_t raw_mag_x, raw_mag_y, raw_mag_z, raw_temp;
if (raw_data != NULL) {
/* Get uncompensated mag data */
rslt = bmm350_reg_read(dev, BMM350_REG_MAG_X_XLSB, mag_data, 14);
__ASSERT_NO_MSG(raw_data != NULL);
if (rslt == BMM350_OK) {
raw_mag_x = (uint32_t)mag_data[2] + ((uint32_t)mag_data[3] << 8) +
((uint32_t)mag_data[4] << 16);
raw_mag_y = (uint32_t)mag_data[5] + ((uint32_t)mag_data[6] << 8) +
((uint32_t)mag_data[7] << 16);
raw_mag_z = (uint32_t)mag_data[8] + ((uint32_t)mag_data[9] << 8) +
((uint32_t)mag_data[10] << 16);
raw_temp = (uint32_t)mag_data[11] + ((uint32_t)mag_data[12] << 8) +
((uint32_t)mag_data[13] << 16);
/* Get uncompensated mag data */
rslt = bmm350_reg_read(dev, BMM350_REG_MAG_X_XLSB, mag_data, sizeof(mag_data));
if ((data->axis_en & BMM350_EN_X_MSK) == BMM350_DISABLE) {
raw_data->raw_xdata = BMM350_DISABLE;
} else {
raw_data->raw_xdata = fix_sign(raw_mag_x, BMM350_SIGNED_24_BIT);
}
if (rslt == 0) {
raw_mag_x = (uint32_t)mag_data[2] + ((uint32_t)mag_data[3] << 8) +
((uint32_t)mag_data[4] << 16);
raw_mag_y = (uint32_t)mag_data[5] + ((uint32_t)mag_data[6] << 8) +
((uint32_t)mag_data[7] << 16);
raw_mag_z = (uint32_t)mag_data[8] + ((uint32_t)mag_data[9] << 8) +
((uint32_t)mag_data[10] << 16);
raw_temp = (uint32_t)mag_data[11] + ((uint32_t)mag_data[12] << 8) +
((uint32_t)mag_data[13] << 16);
if ((data->axis_en & BMM350_EN_Y_MSK) == BMM350_DISABLE) {
raw_data->raw_ydata = BMM350_DISABLE;
} else {
raw_data->raw_ydata = fix_sign(raw_mag_y, BMM350_SIGNED_24_BIT);
}
if ((data->axis_en & BMM350_EN_Z_MSK) == BMM350_DISABLE) {
raw_data->raw_zdata = BMM350_DISABLE;
} else {
raw_data->raw_zdata = fix_sign(raw_mag_z, BMM350_SIGNED_24_BIT);
}
raw_data->raw_data_temp = fix_sign(raw_temp, BMM350_SIGNED_24_BIT);
if ((data->axis_en & BMM350_EN_X_MSK) == BMM350_DISABLE) {
raw_data->raw_xdata = BMM350_DISABLE;
} else {
raw_data->raw_xdata = fix_sign(raw_mag_x, BMM350_SIGNED_24_BIT);
}
} else {
rslt = -EINVAL;
if ((data->axis_en & BMM350_EN_Y_MSK) == BMM350_DISABLE) {
raw_data->raw_ydata = BMM350_DISABLE;
} else {
raw_data->raw_ydata = fix_sign(raw_mag_y, BMM350_SIGNED_24_BIT);
}
if ((data->axis_en & BMM350_EN_Z_MSK) == BMM350_DISABLE) {
raw_data->raw_zdata = BMM350_DISABLE;
} else {
raw_data->raw_zdata = fix_sign(raw_mag_z, BMM350_SIGNED_24_BIT);
}
raw_data->raw_data_temp = fix_sign(raw_temp, BMM350_SIGNED_24_BIT);
}
return rslt;
}
static int8_t read_out_raw_data(const struct device *dev, int32_t *out_data)
static int read_out_raw_data(const struct device *dev, int32_t *out_data)
{
int8_t rslt = BMM350_OK;
int rslt;
int32_t temp = 0;
struct bmm350_raw_mag_data raw_data = {0};
if (out_data != NULL) {
rslt = bmm350_read_uncomp_mag_temp_data(dev, &raw_data);
__ASSERT_NO_MSG(out_data != NULL);
if (rslt == BMM350_OK) {
/* Convert mag lsb to uT and temp lsb to degC */
out_data[0] = ((raw_data.raw_xdata * BMM350_LSB_TO_UT_XY_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[1] = ((raw_data.raw_ydata * BMM350_LSB_TO_UT_XY_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[2] = ((raw_data.raw_zdata * BMM350_LSB_TO_UT_Z_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[3] = ((raw_data.raw_data_temp * BMM350_LSB_TO_UT_TEMP_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
rslt = bmm350_read_uncomp_mag_temp_data(dev, &raw_data);
if (out_data[3] > 0) {
temp = (out_data[3] - (2549 / 100));
} else if (out_data[3] < 0) {
temp = (out_data[3] + (2549 / 100));
} else {
temp = out_data[3];
}
if (rslt == 0) {
/* Convert mag lsb to uT and temp lsb to degC */
out_data[0] = ((raw_data.raw_xdata * BMM350_LSB_TO_UT_XY_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[1] = ((raw_data.raw_ydata * BMM350_LSB_TO_UT_XY_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[2] = ((raw_data.raw_zdata * BMM350_LSB_TO_UT_Z_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[3] = ((raw_data.raw_data_temp * BMM350_LSB_TO_UT_TEMP_COEFF) /
BMM350_LSB_TO_UT_COEFF_DIV);
out_data[3] = temp;
if (out_data[3] > 0) {
temp = (out_data[3] - (2549 / 100));
} else if (out_data[3] < 0) {
temp = (out_data[3] + (2549 / 100));
} else {
temp = out_data[3];
}
} else {
rslt = -EINVAL;
out_data[3] = temp;
}
return rslt;
}
int8_t bmm350_get_compensated_mag_xyz_temp_data_fixed(const struct device *dev,
struct bmm350_mag_temp_data *mag_temp_data)
static int
bmm350_get_compensated_mag_xyz_temp_data_fixed(const struct device *dev,
struct bmm350_mag_temp_data *mag_temp_data)
{
struct bmm350_data *data = dev->data;
int8_t rslt = BMM350_OK;
int rslt;
uint8_t indx;
int32_t out_data[4] = {0};
int32_t dut_offset_coef[3], dut_sensit_coef[3], dut_tco[3], dut_tcs[3];
int32_t cr_ax_comp_x, cr_ax_comp_y, cr_ax_comp_z;
if (mag_temp_data != NULL) {
/* Reads raw magnetic x,y and z axis along with temperature */
rslt = read_out_raw_data(dev, out_data);
__ASSERT_NO_MSG(mag_temp_data != NULL);
if (rslt == BMM350_OK) {
/* Apply compensation to temperature reading */
out_data[3] = (((BMM350_MAG_COMP_COEFF_SCALING +
data->mag_comp.dut_sensit_coef.t_sens) *
out_data[3]) +
data->mag_comp.dut_offset_coef.t_offs) /
BMM350_MAG_COMP_COEFF_SCALING;
/* Reads raw magnetic x,y and z axis along with temperature */
rslt = read_out_raw_data(dev, out_data);
/* Store magnetic compensation structure to an array */
dut_offset_coef[0] = data->mag_comp.dut_offset_coef.offset_x;
dut_offset_coef[1] = data->mag_comp.dut_offset_coef.offset_y;
dut_offset_coef[2] = data->mag_comp.dut_offset_coef.offset_z;
if (rslt == 0) {
/* Apply compensation to temperature reading */
out_data[3] = (((BMM350_MAG_COMP_COEFF_SCALING +
data->mag_comp.dut_sensit_coef.t_sens) *
out_data[3]) +
data->mag_comp.dut_offset_coef.t_offs) /
BMM350_MAG_COMP_COEFF_SCALING;
dut_sensit_coef[0] = data->mag_comp.dut_sensit_coef.sens_x;
dut_sensit_coef[1] = data->mag_comp.dut_sensit_coef.sens_y;
dut_sensit_coef[2] = data->mag_comp.dut_sensit_coef.sens_z;
/* Store magnetic compensation structure to an array */
dut_offset_coef[0] = data->mag_comp.dut_offset_coef.offset_x;
dut_offset_coef[1] = data->mag_comp.dut_offset_coef.offset_y;
dut_offset_coef[2] = data->mag_comp.dut_offset_coef.offset_z;
dut_tco[0] = data->mag_comp.dut_tco.tco_x;
dut_tco[1] = data->mag_comp.dut_tco.tco_y;
dut_tco[2] = data->mag_comp.dut_tco.tco_z;
dut_sensit_coef[0] = data->mag_comp.dut_sensit_coef.sens_x;
dut_sensit_coef[1] = data->mag_comp.dut_sensit_coef.sens_y;
dut_sensit_coef[2] = data->mag_comp.dut_sensit_coef.sens_z;
dut_tcs[0] = data->mag_comp.dut_tcs.tcs_x;
dut_tcs[1] = data->mag_comp.dut_tcs.tcs_y;
dut_tcs[2] = data->mag_comp.dut_tcs.tcs_z;
dut_tco[0] = data->mag_comp.dut_tco.tco_x;
dut_tco[1] = data->mag_comp.dut_tco.tco_y;
dut_tco[2] = data->mag_comp.dut_tco.tco_z;
/* Compensate raw magnetic data */
for (indx = 0; indx < 3; indx++) {
out_data[indx] = (out_data[indx] * (BMM350_MAG_COMP_COEFF_SCALING +
dut_sensit_coef[indx])) /
BMM350_MAG_COMP_COEFF_SCALING;
out_data[indx] = (out_data[indx] + dut_offset_coef[indx]);
out_data[indx] =
((out_data[indx] * BMM350_MAG_COMP_COEFF_SCALING) +
(dut_tco[indx] * (out_data[3] - data->mag_comp.dut_t0))) /
BMM350_MAG_COMP_COEFF_SCALING;
out_data[indx] =
(out_data[indx] * BMM350_MAG_COMP_COEFF_SCALING) /
(BMM350_MAG_COMP_COEFF_SCALING +
(dut_tcs[indx] * (out_data[3] - data->mag_comp.dut_t0)));
}
dut_tcs[0] = data->mag_comp.dut_tcs.tcs_x;
dut_tcs[1] = data->mag_comp.dut_tcs.tcs_y;
dut_tcs[2] = data->mag_comp.dut_tcs.tcs_z;
cr_ax_comp_x =
((((out_data[0] * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_x_y * out_data[1])) *
BMM350_MAG_COMP_COEFF_SCALING) /
((BMM350_MAG_COMP_COEFF_SCALING * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
cr_ax_comp_y =
((((out_data[1] * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x * out_data[0])) *
BMM350_MAG_COMP_COEFF_SCALING) /
((BMM350_MAG_COMP_COEFF_SCALING * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
cr_ax_comp_z =
(out_data[2] +
(((out_data[0] * ((data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_z_y) -
(data->mag_comp.cross_axis.cross_z_x *
BMM350_MAG_COMP_COEFF_SCALING))) -
(out_data[1] * ((data->mag_comp.cross_axis.cross_z_y *
BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_x_y *
data->mag_comp.cross_axis.cross_z_x))))) /
(((BMM350_MAG_COMP_COEFF_SCALING *
BMM350_MAG_COMP_COEFF_SCALING) -
data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
out_data[0] = (int32_t)cr_ax_comp_x;
out_data[1] = (int32_t)cr_ax_comp_y;
out_data[2] = (int32_t)cr_ax_comp_z;
/* Compensate raw magnetic data */
for (indx = 0; indx < 3; indx++) {
out_data[indx] = (out_data[indx] * (BMM350_MAG_COMP_COEFF_SCALING +
dut_sensit_coef[indx])) /
BMM350_MAG_COMP_COEFF_SCALING;
out_data[indx] = (out_data[indx] + dut_offset_coef[indx]);
out_data[indx] =
((out_data[indx] * BMM350_MAG_COMP_COEFF_SCALING) +
(dut_tco[indx] * (out_data[3] - data->mag_comp.dut_t0))) /
BMM350_MAG_COMP_COEFF_SCALING;
out_data[indx] =
(out_data[indx] * BMM350_MAG_COMP_COEFF_SCALING) /
(BMM350_MAG_COMP_COEFF_SCALING +
(dut_tcs[indx] * (out_data[3] - data->mag_comp.dut_t0)));
}
LOG_DBG("mag data %d %d %d\n", out_data[0], out_data[1], out_data[2]);
if (rslt == BMM350_OK) {
if ((data->axis_en & BMM350_EN_X_MSK) == BMM350_DISABLE) {
mag_temp_data->x = BMM350_DISABLE;
} else {
mag_temp_data->x = out_data[0];
}
cr_ax_comp_x =
((((out_data[0] * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_x_y * out_data[1])) *
BMM350_MAG_COMP_COEFF_SCALING) /
((BMM350_MAG_COMP_COEFF_SCALING * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
if ((data->axis_en & BMM350_EN_Y_MSK) == BMM350_DISABLE) {
mag_temp_data->y = BMM350_DISABLE;
} else {
mag_temp_data->y = out_data[1];
}
cr_ax_comp_y =
((((out_data[1] * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x * out_data[0])) *
BMM350_MAG_COMP_COEFF_SCALING) /
((BMM350_MAG_COMP_COEFF_SCALING * BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
if ((data->axis_en & BMM350_EN_Z_MSK) == BMM350_DISABLE) {
mag_temp_data->z = BMM350_DISABLE;
} else {
mag_temp_data->z = out_data[2];
}
mag_temp_data->temperature = out_data[3];
cr_ax_comp_z =
(out_data[2] +
(((out_data[0] * ((data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_z_y) -
(data->mag_comp.cross_axis.cross_z_x *
BMM350_MAG_COMP_COEFF_SCALING))) -
(out_data[1] * ((data->mag_comp.cross_axis.cross_z_y *
BMM350_MAG_COMP_COEFF_SCALING) -
(data->mag_comp.cross_axis.cross_x_y *
data->mag_comp.cross_axis.cross_z_x))))) /
(((BMM350_MAG_COMP_COEFF_SCALING *
BMM350_MAG_COMP_COEFF_SCALING) -
data->mag_comp.cross_axis.cross_y_x *
data->mag_comp.cross_axis.cross_x_y)));
out_data[0] = (int32_t)cr_ax_comp_x;
out_data[1] = (int32_t)cr_ax_comp_y;
out_data[2] = (int32_t)cr_ax_comp_z;
LOG_DBG("mag data %d %d %d", out_data[0], out_data[1], out_data[2]);
if ((data->axis_en & BMM350_EN_X_MSK) == BMM350_DISABLE) {
mag_temp_data->x = BMM350_DISABLE;
} else {
mag_temp_data->x = out_data[0];
}
} else {
rslt = -EINVAL;
if ((data->axis_en & BMM350_EN_Y_MSK) == BMM350_DISABLE) {
mag_temp_data->y = BMM350_DISABLE;
} else {
mag_temp_data->y = out_data[1];
}
if ((data->axis_en & BMM350_EN_Z_MSK) == BMM350_DISABLE) {
mag_temp_data->z = BMM350_DISABLE;
} else {
mag_temp_data->z = out_data[2];
}
mag_temp_data->temperature = out_data[3];
}
return rslt;
}
static int bmm350_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
struct bmm350_data *drv_data = dev->data;
struct bmm350_mag_temp_data mag_temp_data;
struct bmm350_mag_temp_data mag_temp_data = {0};
if (bmm350_get_compensated_mag_xyz_temp_data_fixed(dev, &mag_temp_data) < 0) {
LOG_ERR("failed to read sample");
@ -705,12 +723,12 @@ static uint8_t mag_osr_to_reg(const struct sensor_value *val)
/*!
* @brief This API sets the ODR and averaging factor.
*/
int8_t bmm350_set_odr_performance(enum bmm350_data_rates odr,
static int bmm350_set_odr_performance(enum bmm350_data_rates odr,
enum bmm350_performance_parameters performance,
const struct device *dev)
{
/* Variable to store the function result */
int8_t rslt = 0x00;
int rslt;
/* Variable to get PMU command */
uint8_t reg_data = 0;
enum bmm350_performance_parameters performance_fix = performance;
@ -734,15 +752,17 @@ int8_t bmm350_set_odr_performance(enum bmm350_data_rates odr,
/* Set PMU command configurations for ODR and performance */
rslt = bmm350_reg_write(dev, BMM350_REG_PMU_CMD_AGGR_SET, reg_data);
LOG_DBG("odr index %d odr_reg_data 0x%x", odr, reg_data);
if (rslt != 0) {
LOG_ERR("%s: failed to set ODR and performance", dev->name);
return rslt;
}
if (rslt == BMM350_OK) {
/* Set PMU command configurations to update odr and average */
reg_data = BMM350_PMU_CMD_UPD_OAE;
/* Set PMU command configuration */
rslt = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, reg_data);
if (rslt == BMM350_OK) {
k_usleep(BMM350_UPD_OAE_DELAY);
}
/* Set PMU command configurations to update odr and average */
reg_data = BMM350_PMU_CMD_UPD_OAE;
/* Set PMU command configuration */
rslt = bmm350_reg_write(dev, BMM350_REG_PMU_CMD, reg_data);
if (rslt == 0) {
k_usleep(BMM350_UPD_OAE_DELAY);
}
return rslt;
@ -757,7 +777,7 @@ static int set_mag_odr_osr(const struct device *dev, const struct sensor_value *
uint8_t odr_bits;
/* read current state */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], 3);
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], sizeof(rx_buf));
if (ret < 0) {
LOG_ERR("failed to read PMU_CMD_AGGR_SET");
return -EIO;
@ -953,7 +973,7 @@ static int bmm350_init_chip(const struct device *dev)
uint8_t chip_id[3] = {0x00};
int ret = 0;
/* Read chip ID (can only be read in sleep mode)*/
if (bmm350_reg_read(dev, BMM350_REG_CHIP_ID, &chip_id[0], 3) < 0) {
if (bmm350_reg_read(dev, BMM350_REG_CHIP_ID, &chip_id[0], sizeof(chip_id)) < 0) {
LOG_ERR("failed reading chip id");
goto err_poweroff;
}
@ -968,7 +988,7 @@ static int bmm350_init_chip(const struct device *dev)
ret = bmm350_reg_write(dev, BMM350_REG_CMD, soft_reset);
k_usleep(BMM350_SOFT_RESET_DELAY);
/* Read chip ID (can only be read in sleep mode)*/
if (bmm350_reg_read(dev, BMM350_REG_CHIP_ID, &chip_id[0], 3) < 0) {
if (bmm350_reg_read(dev, BMM350_REG_CHIP_ID, &chip_id[0], sizeof(chip_id)) < 0) {
LOG_ERR("failed reading chip id");
goto err_poweroff;
}
@ -979,27 +999,37 @@ static int bmm350_init_chip(const struct device *dev)
/* Set pad drive strength */
ret = bmm350_reg_write(dev, BMM350_REG_PAD_CTRL, config->drive_strength);
if (ret < 0) {
if (ret != 0) {
LOG_ERR("%s: failed to set pad drive strength", dev->name);
return ret;
}
ret = bmm350_otp_dump_after_boot(dev);
LOG_DBG("bmm350 chip_id 0x%x otp dump after boot %d\n", chip_id[2], ret);
LOG_DBG("bmm350 chip_id 0x%x otp dump after boot %d", chip_id[2], ret);
if (bmm350_reg_write(dev, BMM350_REG_OTP_CMD_REG, BMM350_OTP_CMD_PWR_OFF_OTP) < 0) {
LOG_ERR("failed to set REP");
goto err_poweroff;
}
ret += bmm350_magnetic_reset_and_wait(dev);
LOG_DBG("bmm350 setup result %d\n", ret);
ret += bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
ret += bmm350_reg_read(dev, BMM350_REG_ERR_REG, &rx_buf[0], 3);
ret = bmm350_magnetic_reset_and_wait(dev);
if (ret != 0) {
LOG_ERR("%s %d", __func__, ret);
LOG_ERR("failed to perform magnetic reset");
goto err_poweroff;
}
LOG_DBG("bmm350 setup result %d", ret);
ret = bmm350_get_pmu_cmd_status_0(dev, &pmu_cmd_stat_0);
if (ret != 0) {
LOG_ERR("failed to get pmu_cmd_stat_0");
goto err_poweroff;
}
ret = bmm350_reg_read(dev, BMM350_REG_ERR_REG, &rx_buf[0], 3);
if (ret != 0) {
LOG_ERR("failed to read err_reg");
goto err_poweroff;
}
return 0;