diff --git a/drivers/sensor/bosch/bmm350/bmm350.c b/drivers/sensor/bosch/bmm350/bmm350.c index 3c58c710c9d..5f7db0db95e 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.c +++ b/drivers/sensor/bosch/bmm350/bmm350.c @@ -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;