From cfbdc5c1bcc3483cbd89d8dbf8e9444d017d4424 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Fri, 16 May 2025 10:59:08 -0700 Subject: [PATCH 1/2] drivers: sensor: bmm350: add attr_get Add the attr_get api. Also rename functions where they implied accelerometer to imply magnetometer. Signed-off-by: Ryan McClelland --- drivers/sensor/bosch/bmm350/bmm350.c | 127 ++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/bosch/bmm350/bmm350.c b/drivers/sensor/bosch/bmm350/bmm350.c index 901d3ffa7341..e255e4d48ade 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.c +++ b/drivers/sensor/bosch/bmm350/bmm350.c @@ -676,7 +676,8 @@ static int bmm350_channel_get(const struct device *dev, enum sensor_channel chan return 0; } -static uint8_t acc_odr_to_reg(const struct sensor_value *val) + +static uint8_t mag_odr_to_reg(const struct sensor_value *val) { double odr = sensor_value_to_double((struct sensor_value *)val); @@ -706,7 +707,7 @@ static uint8_t acc_odr_to_reg(const struct sensor_value *val) return reg; } -static uint8_t acc_osr_to_reg(const struct sensor_value *val) +static uint8_t mag_osr_to_reg(const struct sensor_value *val) { switch (val->val1) { case 0: @@ -767,6 +768,7 @@ int8_t bmm350_set_odr_performance(enum bmm350_data_rates odr, return rslt; } + static int set_mag_odr_osr(const struct device *dev, const struct sensor_value *odr, const struct sensor_value *osr) { @@ -792,10 +794,10 @@ static int set_mag_odr_osr(const struct device *dev, const struct sensor_value * } if (odr) { - odr_bits = acc_odr_to_reg(odr); + odr_bits = mag_odr_to_reg(odr); } if (osr) { - osr_bits = acc_osr_to_reg(osr); + osr_bits = mag_osr_to_reg(osr); if (osr_bits == 0xFF) { LOG_ERR("unsupported oversampling rate"); return -EINVAL; @@ -836,8 +838,125 @@ static int bmm350_attr_set(const struct device *dev, enum sensor_channel chan, return 0; } + +void mag_reg_to_odr(uint8_t bits, struct sensor_value *val) +{ + switch (bits) { + case BMM350_DATA_RATE_1_5625HZ: + val->val1 = 1; + val->val2 = 562500; + break; + case BMM350_DATA_RATE_3_125HZ: + val->val1 = 3; + val->val2 = 125000; + break; + case BMM350_DATA_RATE_6_25HZ: + val->val1 = 6; + val->val2 = 250000; + break; + case BMM350_DATA_RATE_12_5HZ: + val->val1 = 12; + val->val2 = 500000; + break; + case BMM350_DATA_RATE_25HZ: + val->val1 = 25; + val->val2 = 0; + break; + case BMM350_DATA_RATE_50HZ: + val->val1 = 50; + val->val2 = 0; + break; + case BMM350_DATA_RATE_100HZ: + val->val1 = 100; + val->val2 = 0; + break; + case BMM350_DATA_RATE_200HZ: + val->val1 = 200; + val->val2 = 0; + break; + case BMM350_DATA_RATE_400HZ: + val->val1 = 400; + val->val2 = 0; + break; + default: + val->val1 = 0; + val->val2 = 0; + break; + } +} + +void mag_reg_to_osr(uint8_t bits, struct sensor_value *val) +{ + val->val2 = 0; + + switch (bits) { + case BMM350_NO_AVERAGING: + val->val1 = 1; + break; + case BMM350_AVERAGING_2: + val->val1 = 2; + break; + case BMM350_AVERAGING_4: + val->val1 = 4; + break; + case BMM350_AVERAGING_8: + val->val1 = 8; + break; + default: + val->val1 = 0; + break; + } +} + +static int get_mag_odr_osr(const struct device *dev, struct sensor_value *odr, + struct sensor_value *osr) +{ + int ret; + uint8_t rx_buf[3] = {0x00}; + uint8_t osr_bits; + uint8_t odr_bits; + + /* read current state */ + ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], 3); + if (ret < 0) { + LOG_ERR("failed to read PMU_CMD_AGGR_SET"); + return -EIO; + } + osr_bits = ((rx_buf[2] & BMM350_AVG_MSK) >> BMM350_AVG_POS); + odr_bits = ((rx_buf[2] & BMM350_ODR_MSK) >> BMM350_ODR_POS); + + if (odr) { + mag_reg_to_odr(odr_bits, odr); + } + if (osr) { + mag_reg_to_osr(osr_bits, osr); + } + + return 0; +} + +static int bmm350_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + int ret; + + switch (attr) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + ret = get_mag_odr_osr(dev, val, NULL); + break; + case SENSOR_ATTR_OVERSAMPLING: + ret = get_mag_odr_osr(dev, NULL, val); + break; + default: + ret = -EINVAL; + } + + return ret; +} + static DEVICE_API(sensor, bmm350_api_funcs) = { .attr_set = bmm350_attr_set, + .attr_get = bmm350_attr_get, .sample_fetch = bmm350_sample_fetch, .channel_get = bmm350_channel_get, #ifdef CONFIG_BMM350_TRIGGER From 229d446065a6cdd27d4427804971e6bb88eba19d Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Fri, 16 May 2025 11:02:19 -0700 Subject: [PATCH 2/2] drivers: sensor: bmm350: add default odr/osr Add a way to define the default odr and osr with devicetree for the bmm350. Signed-off-by: Ryan McClelland --- drivers/sensor/bosch/bmm350/bmm350.c | 14 +++++++--- drivers/sensor/bosch/bmm350/bmm350.h | 2 ++ dts/bindings/sensor/bosch,bmm350.yaml | 40 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/sensor/bosch/bmm350/bmm350.c b/drivers/sensor/bosch/bmm350/bmm350.c index e255e4d48ade..a3e46e4c6154 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.c +++ b/drivers/sensor/bosch/bmm350/bmm350.c @@ -710,7 +710,7 @@ static uint8_t mag_odr_to_reg(const struct sensor_value *val) static uint8_t mag_osr_to_reg(const struct sensor_value *val) { switch (val->val1) { - case 0: + case 1: return BMM350_NO_AVERAGING; case 2: return BMM350_AVERAGING_2; @@ -1053,9 +1053,12 @@ static int pm_action(const struct device *dev, enum pm_device_action action) static int bmm350_init(const struct device *dev) { int err = 0; + const struct bmm350_config *config = dev->config; struct bmm350_data *data = dev->data; - const struct sensor_value odr = {100, 0}; - const struct sensor_value osr = {2, 0}; + const struct sensor_value osr = {config->default_osr, 0}; + struct sensor_value odr; + + mag_reg_to_odr(config->default_odr, &odr); err = bmm350_bus_check(dev); if (err < 0) { @@ -1078,8 +1081,9 @@ static int bmm350_init(const struct device *dev) /* Assign axis_en with all axis enabled (BMM350_EN_XYZ_MSK) */ data->axis_en = BMM350_EN_XYZ_MSK; - /* Initialize to 100Hz, averaging between 2 samples by default */ + /* Initialize to odr and osr */ if (set_mag_odr_osr(dev, &odr, &osr) < 0) { + LOG_ERR("failed to set default odr and osr"); return -EIO; } @@ -1095,6 +1099,8 @@ static int bmm350_init(const struct device *dev) static const struct bmm350_config bmm350_config_##inst = { \ .bus.i2c = I2C_DT_SPEC_INST_GET(inst), \ .bus_io = &bmm350_bus_io_i2c, \ + .default_odr = DT_INST_ENUM_IDX(inst, odr) + BMM350_DATA_RATE_400HZ, \ + .default_osr = DT_INST_PROP(inst, osr), \ BMM350_INT_CFG(inst)}; \ \ PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \ diff --git a/drivers/sensor/bosch/bmm350/bmm350.h b/drivers/sensor/bosch/bmm350/bmm350.h index adf23a068e85..7ce36d9b5758 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.h +++ b/drivers/sensor/bosch/bmm350/bmm350.h @@ -452,6 +452,8 @@ struct bmm350_config { struct bmm350_bus bus; const struct bmm350_bus_io *bus_io; struct gpio_dt_spec drdy_int; + uint8_t default_odr; + uint8_t default_osr; }; struct bmm350_data { diff --git a/dts/bindings/sensor/bosch,bmm350.yaml b/dts/bindings/sensor/bosch,bmm350.yaml index 35206be2d2ed..69435c188317 100644 --- a/dts/bindings/sensor/bosch,bmm350.yaml +++ b/dts/bindings/sensor/bosch,bmm350.yaml @@ -10,3 +10,43 @@ properties: description: | This property specifies the connection for data ready pin. The polarity default is active high when sensor data is ready. + + odr: + type: string + description: | + Default output data rate in Hz. Only the following values are allowed: + 400 - 400 - 2.5ms + 200 - 200 - 5ms + 100 - 100 - 10ms + 50 - 50 - 20ms + 25 - 25 - 40ms + 12.5 - 25/2 - 80ms + 6.25 - 25/4 - 160ms + 3.125 - 25/8 - 320ms + 1.5625 - 25/16 - 640ms + default: "100" + enum: + - "400" + - "200" + - "100" + - "50" + - "25" + - "12.5" + - "6.25" + - "3.125" + - "1.5625" + + osr: + type: int + description: | + Default oversampling. Only the following values are allowed: + 8 - 8x + 4 - 4x + 2 - 2x + 1 - 1x + default: 2 + enum: + - 1 + - 2 + - 4 + - 8