From bc7f0c956d6715abb0095e82d23734f0a129e5df Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Mon, 14 Jul 2025 15:56:49 -0400 Subject: [PATCH 1/4] bmp581: Add dts-properties to set default configuration The existing driver requires setting multiple attributes in order to work basic fetch/get reads. Simplify this by allowing the user to set dts node properties based on the use-case. As a result, basic settings results in the driver being up and running from the start, one can just get sensor readings out of the box. These still can be overriden at run-time if need be. Signed-off-by: Luis Ubieda --- drivers/sensor/bosch/bmp581/bmp581.c | 67 ++++++++-- drivers/sensor/bosch/bmp581/bmp581.h | 45 ++++--- dts/bindings/sensor/bosch,bmp581.yaml | 133 ++++++++++++++++++++ include/zephyr/drivers/sensor/bmp581_user.h | 57 +-------- include/zephyr/dt-bindings/sensor/bmp581.h | 94 ++++++++++++++ 5 files changed, 312 insertions(+), 84 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/bmp581.h diff --git a/drivers/sensor/bosch/bmp581/bmp581.c b/drivers/sensor/bosch/bmp581/bmp581.c index eb6d80b58b31..f08beafeea10 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.c +++ b/drivers/sensor/bosch/bmp581/bmp581.c @@ -254,15 +254,42 @@ static int get_osr_odr_press_config(struct bmp581_osr_odr_press_config *osr_odr_ rslt = i2c_burst_read_dt(&conf->i2c, BMP5_REG_OSR_CONFIG, reg_data, 2); if (rslt == BMP5_OK) { - osr_odr_press_cfg->osr_t = BMP5_GET_BITS_POS_0(reg_data[0], BMP5_TEMP_OS); - osr_odr_press_cfg->osr_p = BMP5_GET_BITSLICE(reg_data[0], BMP5_PRESS_OS); + osr_odr_press_cfg->osr_t = BMP5_GET_BITS_POS_0(reg_data[0], BMP5_TEMP_OSR); + osr_odr_press_cfg->osr_p = BMP5_GET_BITSLICE(reg_data[0], BMP5_PRESS_OSR); osr_odr_press_cfg->press_en = BMP5_GET_BITSLICE(reg_data[0], BMP5_PRESS_EN); - osr_odr_press_cfg->odr = BMP5_GET_BITSLICE(reg_data[1], BMP5_ODR); } return rslt; } +static int set_osr_odr_press_config(const struct bmp581_osr_odr_press_config *osr_odr_press_cfg, + const struct device *dev) +{ + const struct bmp581_config *cfg = (const struct bmp581_config *)dev->config; + uint8_t reg_data[2] = {0}; + + reg_data[0] = BMP5_SET_BITSLICE(reg_data[0], BMP5_TEMP_OSR, osr_odr_press_cfg->osr_t); + reg_data[0] = BMP5_SET_BITSLICE(reg_data[0], BMP5_PRESS_OSR, osr_odr_press_cfg->osr_p); + reg_data[0] = BMP5_SET_BITSLICE(reg_data[0], BMP5_PRESS_EN, osr_odr_press_cfg->press_en); + + reg_data[1] = BMP5_SET_BITSLICE(reg_data[1], BMP5_POWERMODE, osr_odr_press_cfg->power_mode); + reg_data[1] = BMP5_SET_BITSLICE(reg_data[1], BMP5_ODR, osr_odr_press_cfg->odr); + + return i2c_burst_write_dt(&cfg->i2c, BMP5_REG_OSR_CONFIG, reg_data, sizeof(reg_data)); +} + +static int set_iir_filters_config(const struct bmp581_osr_odr_press_config *osr_odr_press_cfg, + const struct device *dev) +{ + const struct bmp581_config *cfg = (const struct bmp581_config *)dev->config; + uint8_t reg_data = 0; + + reg_data = BMP5_SET_BITSLICE(reg_data, BMP5_SET_IIR_TEMP, osr_odr_press_cfg->iir_t); + reg_data = BMP5_SET_BITSLICE(reg_data, BMP5_SET_IIR_PRESS, osr_odr_press_cfg->iir_p); + + return i2c_burst_write_dt(&cfg->i2c, BMP5_REG_DSP_IIR, ®_data, 1); +} + static int set_osr_config(const struct sensor_value *osr, enum sensor_channel chan, const struct device *dev) { @@ -282,16 +309,16 @@ static int set_osr_config(const struct sensor_value *osr, enum sensor_channel ch if (ret == BMP5_OK) { switch (chan) { case SENSOR_CHAN_ALL: - osr_val = BMP5_SET_BITS_POS_0(osr_val, BMP5_TEMP_OS, oversampling); - osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_OS, oversampling); + osr_val = BMP5_SET_BITS_POS_0(osr_val, BMP5_TEMP_OSR, oversampling); + osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_OSR, oversampling); osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_EN, press_en); break; case SENSOR_CHAN_PRESS: - osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_OS, oversampling); + osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_OSR, oversampling); osr_val = BMP5_SET_BITSLICE(osr_val, BMP5_PRESS_EN, press_en); break; case SENSOR_CHAN_AMBIENT_TEMP: - osr_val = BMP5_SET_BITS_POS_0(osr_val, BMP5_TEMP_OS, oversampling); + osr_val = BMP5_SET_BITS_POS_0(osr_val, BMP5_TEMP_OSR, oversampling); break; default: ret = -ENOTSUP; @@ -519,7 +546,6 @@ static int bmp581_init(const struct device *dev) /* Reset the chip id. */ drv->chip_id = 0; - memset(&drv->osr_odr_press_config, 0, sizeof(drv->osr_odr_press_config)); memset(&drv->last_sample, 0, sizeof(drv->last_sample)); soft_reset(dev); @@ -544,6 +570,19 @@ static int bmp581_init(const struct device *dev) BMP5_CHIP_ID_PRIM, BMP5_CHIP_ID_SEC); return -EINVAL; } + + ret = set_iir_filters_config(&drv->osr_odr_press_config, dev); + if (ret != 0) { + LOG_ERR("Failed to set initial IIR settings: %d", ret); + return ret; + } + + ret = set_osr_odr_press_config(&drv->osr_odr_press_config, dev); + if (ret != 0) { + LOG_ERR("Failed to set initial ODR OSR settings: %d", ret); + return ret; + } + return ret; } @@ -559,7 +598,17 @@ static DEVICE_API(sensor, bmp581_driver_api) = { } #define BMP581_INIT(i) \ - static struct bmp581_data bmp581_data_##i; \ + static struct bmp581_data bmp581_data_##i = { \ + .osr_odr_press_config = { \ + .press_en = 1, \ + .odr = DT_INST_PROP(i, odr), \ + .osr_t = DT_INST_PROP(i, temp_osr), \ + .osr_p = DT_INST_PROP(i, press_osr), \ + .iir_t = DT_INST_PROP(i, temp_iir), \ + .iir_p = DT_INST_PROP(i, press_iir), \ + .power_mode = DT_INST_PROP(i, power_mode), \ + }, \ + }; \ BMP581_CONFIG(i); \ \ SENSOR_DEVICE_DT_INST_DEFINE(i, bmp581_init, NULL, &bmp581_data_##i, &bmp581_config_##i, \ diff --git a/drivers/sensor/bosch/bmp581/bmp581.h b/drivers/sensor/bosch/bmp581/bmp581.h index cdbe7f7e0b8f..cda5504fb950 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.h +++ b/drivers/sensor/bosch/bmp581/bmp581.h @@ -175,10 +175,11 @@ #define BMP5_ODR_POS 2 /* OSR configurations */ -#define BMP5_TEMP_OS_MSK 0x07 +#define BMP5_TEMP_OSR_MSK 0x07 +#define BMP5_TEMP_OSR_POS 0 -#define BMP5_PRESS_OS_MSK 0x38 -#define BMP5_PRESS_OS_POS 3 +#define BMP5_PRESS_OSR_MSK 0x38 +#define BMP5_PRESS_OSR_POS 3 /* Pressure enable */ #define BMP5_PRESS_EN_MSK 0x40 @@ -186,6 +187,7 @@ /* IIR configurations */ #define BMP5_SET_IIR_TEMP_MSK 0x07 +#define BMP5_SET_IIR_TEMP_POS 0 #define BMP5_SET_IIR_PRESS_MSK 0x38 #define BMP5_SET_IIR_PRESS_POS 3 @@ -219,6 +221,7 @@ /* Powermode */ #define BMP5_POWERMODE_MSK 0x03 +#define BMP5_POWERMODE_POS 0 #define BMP5_DEEP_DISABLE_MSK 0x80 #define BMP5_DEEP_DISABLE_POS 7 @@ -266,27 +269,27 @@ struct bmp581_osr_odr_press_config { /*! Temperature oversampling * Assignable macros : - * - BMP5_OVERSAMPLING_1X - * - BMP5_OVERSAMPLING_2X - * - BMP5_OVERSAMPLING_4X - * - BMP5_OVERSAMPLING_8X - * - BMP5_OVERSAMPLING_16X - * - BMP5_OVERSAMPLING_32X - * - BMP5_OVERSAMPLING_64X - * - BMP5_OVERSAMPLING_128X + * - BMP581_DT_OVERSAMPLING_1X + * - BMP581_DT_OVERSAMPLING_2X + * - BMP581_DT_OVERSAMPLING_4X + * - BMP581_DT_OVERSAMPLING_8X + * - BMP581_DT_OVERSAMPLING_16X + * - BMP581_DT_OVERSAMPLING_32X + * - BMP581_DT_OVERSAMPLING_64X + * - BMP581_DT_OVERSAMPLING_128X */ uint8_t osr_t; /*! Pressure oversampling * Assignable macros : - * - BMP5_OVERSAMPLING_1X - * - BMP5_OVERSAMPLING_2X - * - BMP5_OVERSAMPLING_4X - * - BMP5_OVERSAMPLING_8X - * - BMP5_OVERSAMPLING_16X - * - BMP5_OVERSAMPLING_32X - * - BMP5_OVERSAMPLING_64X - * - BMP5_OVERSAMPLING_128X + * - BMP581_DT_OVERSAMPLING_1X + * - BMP581_DT_OVERSAMPLING_2X + * - BMP581_DT_OVERSAMPLING_4X + * - BMP581_DT_OVERSAMPLING_8X + * - BMP581_DT_OVERSAMPLING_16X + * - BMP581_DT_OVERSAMPLING_32X + * - BMP581_DT_OVERSAMPLING_64X + * - BMP581_DT_OVERSAMPLING_128X */ uint8_t osr_p; @@ -298,6 +301,10 @@ struct bmp581_osr_odr_press_config { /*! Output Data Rate */ uint8_t odr; + + uint8_t iir_t; + uint8_t iir_p; + uint8_t power_mode; }; struct bmp581_sample { diff --git a/dts/bindings/sensor/bosch,bmp581.yaml b/dts/bindings/sensor/bosch,bmp581.yaml index 5afad7eea466..4650b40fa5c4 100644 --- a/dts/bindings/sensor/bosch,bmp581.yaml +++ b/dts/bindings/sensor/bosch,bmp581.yaml @@ -2,6 +2,22 @@ description: | The BMP581 is a Barometric pressure sensor. See more info at: https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp581/ + When setting the sensor DTS properties, make sure to include + bmp581.h and use the macros defined there. + + Example: + #include + + bmp581@46 { + ... + odr = ; + press-osr = ; + temp-osr = ; + press-iir = ; + temp-iir = ; + power-mode = ; + }; + compatible: "bosch,bmp581" include: [sensor-device.yaml, i2c-device.yaml] @@ -13,3 +29,120 @@ properties: The interrupt pin of BMP581 is open-drain, active low. If connected directly to the MCU, the pin should be configured as pull-up, active low. + + odr: + type: int + default: 0x1C # BMP581_DT_ODR_1_HZ + description: | + Output data rate. Please note this is only valid on BMP581_DT_MODE_NORMAL. + Default is power-on reset. + enum: + - 0x00 # BMP581_DT_ODR_240_HZ + - 0x01 # BMP581_DT_ODR_218_5_HZ + - 0x02 # BMP581_DT_ODR_199_1_HZ + - 0x03 # BMP581_DT_ODR_179_2_HZ + - 0x04 # BMP581_DT_ODR_160_HZ + - 0x05 # BMP581_DT_ODR_149_3_HZ + - 0x06 # BMP581_DT_ODR_140_HZ + - 0x07 # BMP581_DT_ODR_129_8_HZ + - 0x08 # BMP581_DT_ODR_120_HZ + - 0x09 # BMP581_DT_ODR_110_1_HZ + - 0x0A # BMP581_DT_ODR_100_2_HZ + - 0x0B # BMP581_DT_ODR_89_6_HZ + - 0x0C # BMP581_DT_ODR_80_HZ + - 0x0D # BMP581_DT_ODR_70_HZ + - 0x0E # BMP581_DT_ODR_60_HZ + - 0x0F # BMP581_DT_ODR_50_HZ + - 0x10 # BMP581_DT_ODR_45_HZ + - 0x11 # BMP581_DT_ODR_40_HZ + - 0x12 # BMP581_DT_ODR_35_HZ + - 0x13 # BMP581_DT_ODR_30_HZ + - 0x14 # BMP581_DT_ODR_25_HZ + - 0x15 # BMP581_DT_ODR_20_HZ + - 0x16 # BMP581_DT_ODR_15_HZ + - 0x17 # BMP581_DT_ODR_10_HZ + - 0x18 # BMP581_DT_ODR_5_HZ + - 0x19 # BMP581_DT_ODR_4_HZ + - 0x1A # BMP581_DT_ODR_3_HZ + - 0x1B # BMP581_DT_ODR_2_HZ + - 0x1C # BMP581_DT_ODR_1_HZ + - 0x1D # BMP581_DT_ODR_0_5_HZ + - 0x1E # BMP581_DT_ODR_0_250_HZ + - 0x1F # BMP581_DT_ODR_0_125_HZ + + press-osr: + type: int + default: 0x00 # BMP581_DT_OVERSAMPLING_1X + description: | + Pressure oversampling rate. + Default is power-on reset. + enum: + - 0x00 # BMP581_DT_OVERSAMPLING_1X + - 0x01 # BMP581_DT_OVERSAMPLING_2X + - 0x02 # BMP581_DT_OVERSAMPLING_4X + - 0x03 # BMP581_DT_OVERSAMPLING_8X + - 0x04 # BMP581_DT_OVERSAMPLING_16X + - 0x05 # BMP581_DT_OVERSAMPLING_32X + - 0x06 # BMP581_DT_OVERSAMPLING_64X + - 0x07 # BMP581_DT_OVERSAMPLING_128X + + temp-osr: + type: int + default: 0x00 # BMP581_DT_OVERSAMPLING_1X + description: | + Temperature oversampling rate. + Default is power-on reset. + enum: + - 0x00 # BMP581_DT_OVERSAMPLING_1X + - 0x01 # BMP581_DT_OVERSAMPLING_2X + - 0x02 # BMP581_DT_OVERSAMPLING_4X + - 0x03 # BMP581_DT_OVERSAMPLING_8X + - 0x04 # BMP581_DT_OVERSAMPLING_16X + - 0x05 # BMP581_DT_OVERSAMPLING_32X + - 0x06 # BMP581_DT_OVERSAMPLING_64X + - 0x07 # BMP581_DT_OVERSAMPLING_128X + + power-mode: + type: int + default: 1 # BMP581_DT_MODE_NORMAL + description: | + Power mode. + Default favors ease of use by simply setting ODR and OSR. Otherwise user + needs to look into driver details, as the other modes require some quirks + (e.g: Forced mode does not just work). + enum: + - 1 # BMP581_DT_MODE_NORMAL + - 2 # BMP581_DT_MODE_FORCED + - 3 # BMP581_DT_MODE_CONTINUOUS + + press-iir: + type: int + default: 0x00 # BMP581_DT_IIR_FILTER_BYPASS + description: | + Pressure IIR filter coefficient. + Default is power-on reset (bypass). + enum: + - 0x00 # BMP581_DT_IIR_FILTER_BYPASS + - 0x01 # BMP581_DT_IIR_FILTER_COEFF_1 + - 0x02 # BMP581_DT_IIR_FILTER_COEFF_3 + - 0x03 # BMP581_DT_IIR_FILTER_COEFF_7 + - 0x04 # BMP581_DT_IIR_FILTER_COEFF_15 + - 0x05 # BMP581_DT_IIR_FILTER_COEFF_31 + - 0x06 # BMP581_DT_IIR_FILTER_COEFF_63 + - 0x07 # BMP581_DT_IIR_FILTER_COEFF_127 + + temp-iir: + type: int + default: 0x00 # BMP581_DT_IIR_FILTER_BYPASS + description: | + Temperature IIR filter coefficient. + Default is power-on reset (bypass). + enum: + - 0x00 # BMP581_DT_IIR_FILTER_BYPASS + - 0x01 # BMP581_DT_IIR_FILTER_COEFF_1 + - 0x02 # BMP581_DT_IIR_FILTER_COEFF_3 + - 0x03 # BMP581_DT_IIR_FILTER_COEFF_7 + - 0x04 # BMP581_DT_IIR_FILTER_COEFF_15 + - 0x05 # BMP581_DT_IIR_FILTER_COEFF_31 + - 0x06 # BMP581_DT_IIR_FILTER_COEFF_63 + - 0x07 # BMP581_DT_IIR_FILTER_COEFF_127 diff --git a/include/zephyr/drivers/sensor/bmp581_user.h b/include/zephyr/drivers/sensor/bmp581_user.h index e0fd000c8c06..27c36dbca8b1 100644 --- a/include/zephyr/drivers/sensor/bmp581_user.h +++ b/include/zephyr/drivers/sensor/bmp581_user.h @@ -13,62 +13,7 @@ #define ZEPHYR_INCLUDE_DRIVERS_SENSOR_BMP581_USER_H_ #include - -#define BMP5_SEA_LEVEL_PRESSURE_PA 101325 - -/* ODR settings */ -#define BMP5_ODR_240_HZ 0x00 -#define BMP5_ODR_218_5_HZ 0x01 -#define BMP5_ODR_199_1_HZ 0x02 -#define BMP5_ODR_179_2_HZ 0x03 -#define BMP5_ODR_160_HZ 0x04 -#define BMP5_ODR_149_3_HZ 0x05 -#define BMP5_ODR_140_HZ 0x06 -#define BMP5_ODR_129_8_HZ 0x07 -#define BMP5_ODR_120_HZ 0x08 -#define BMP5_ODR_110_1_HZ 0x09 -#define BMP5_ODR_100_2_HZ 0x0A -#define BMP5_ODR_89_6_HZ 0x0B -#define BMP5_ODR_80_HZ 0x0C -#define BMP5_ODR_70_HZ 0x0D -#define BMP5_ODR_60_HZ 0x0E -#define BMP5_ODR_50_HZ 0x0F -#define BMP5_ODR_45_HZ 0x10 -#define BMP5_ODR_40_HZ 0x11 -#define BMP5_ODR_35_HZ 0x12 -#define BMP5_ODR_30_HZ 0x13 -#define BMP5_ODR_25_HZ 0x14 -#define BMP5_ODR_20_HZ 0x15 -#define BMP5_ODR_15_HZ 0x16 -#define BMP5_ODR_10_HZ 0x17 -#define BMP5_ODR_05_HZ 0x18 -#define BMP5_ODR_04_HZ 0x19 -#define BMP5_ODR_03_HZ 0x1A -#define BMP5_ODR_02_HZ 0x1B -#define BMP5_ODR_01_HZ 0x1C -#define BMP5_ODR_0_5_HZ 0x1D -#define BMP5_ODR_0_250_HZ 0x1E -#define BMP5_ODR_0_125_HZ 0x1F - -/* Oversampling for temperature and pressure */ -#define BMP5_OVERSAMPLING_1X 0x00 -#define BMP5_OVERSAMPLING_2X 0x01 -#define BMP5_OVERSAMPLING_4X 0x02 -#define BMP5_OVERSAMPLING_8X 0x03 -#define BMP5_OVERSAMPLING_16X 0x04 -#define BMP5_OVERSAMPLING_32X 0x05 -#define BMP5_OVERSAMPLING_64X 0x06 -#define BMP5_OVERSAMPLING_128X 0x07 - -/* IIR filter for temperature and pressure */ -#define BMP5_IIR_FILTER_BYPASS 0x00 -#define BMP5_IIR_FILTER_COEFF_1 0x01 -#define BMP5_IIR_FILTER_COEFF_3 0x02 -#define BMP5_IIR_FILTER_COEFF_7 0x03 -#define BMP5_IIR_FILTER_COEFF_15 0x04 -#define BMP5_IIR_FILTER_COEFF_31 0x05 -#define BMP5_IIR_FILTER_COEFF_63 0x06 -#define BMP5_IIR_FILTER_COEFF_127 0x07 +#include /* Custom ATTR values */ diff --git a/include/zephyr/dt-bindings/sensor/bmp581.h b/include/zephyr/dt-bindings/sensor/bmp581.h new file mode 100644 index 000000000000..03a1a025005f --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/bmp581.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 Croxel Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_BOSCH_BMP581_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_BOSCH_BMP581_H_ + +/** + * @defgroup bmp581 Bosch BMP581 DT Options + * @ingroup sensor_interface + * @{ + */ + +/** + * @defgroup BMP581_POWER_MODES Sensor power modes + * @{ + */ +#define BMP581_DT_MODE_NORMAL 1 +#define BMP581_DT_MODE_FORCED 2 +#define BMP581_DT_MODE_CONTINUOUS 3 +/** @} */ + +/** + * @defgroup BMP581_OUTPUT_DATA_RATE Output data rate options + * @{ + */ +#define BMP581_DT_ODR_240_HZ 0x00 +#define BMP581_DT_ODR_218_5_HZ 0x01 +#define BMP581_DT_ODR_199_1_HZ 0x02 +#define BMP581_DT_ODR_179_2_HZ 0x03 +#define BMP581_DT_ODR_160_HZ 0x04 +#define BMP581_DT_ODR_149_3_HZ 0x05 +#define BMP581_DT_ODR_140_HZ 0x06 +#define BMP581_DT_ODR_129_8_HZ 0x07 +#define BMP581_DT_ODR_120_HZ 0x08 +#define BMP581_DT_ODR_110_1_HZ 0x09 +#define BMP581_DT_ODR_100_2_HZ 0x0A +#define BMP581_DT_ODR_89_6_HZ 0x0B +#define BMP581_DT_ODR_80_HZ 0x0C +#define BMP581_DT_ODR_70_HZ 0x0D +#define BMP581_DT_ODR_60_HZ 0x0E +#define BMP581_DT_ODR_50_HZ 0x0F +#define BMP581_DT_ODR_45_HZ 0x10 +#define BMP581_DT_ODR_40_HZ 0x11 +#define BMP581_DT_ODR_35_HZ 0x12 +#define BMP581_DT_ODR_30_HZ 0x13 +#define BMP581_DT_ODR_25_HZ 0x14 +#define BMP581_DT_ODR_20_HZ 0x15 +#define BMP581_DT_ODR_15_HZ 0x16 +#define BMP581_DT_ODR_10_HZ 0x17 +#define BMP581_DT_ODR_5_HZ 0x18 +#define BMP581_DT_ODR_4_HZ 0x19 +#define BMP581_DT_ODR_3_HZ 0x1A +#define BMP581_DT_ODR_2_HZ 0x1B +#define BMP581_DT_ODR_1_HZ 0x1C +#define BMP581_DT_ODR_0_5_HZ 0x1D +#define BMP581_DT_ODR_0_250_HZ 0x1E +#define BMP581_DT_ODR_0_125_HZ 0x1F +/** @} */ + +/** + * @defgroup BMP581_OVERSAMPLING Oversampling options. Valid for temperature and pressure. + * @{ + */ +#define BMP581_DT_OVERSAMPLING_1X 0x00 +#define BMP581_DT_OVERSAMPLING_2X 0x01 +#define BMP581_DT_OVERSAMPLING_4X 0x02 +#define BMP581_DT_OVERSAMPLING_8X 0x03 +#define BMP581_DT_OVERSAMPLING_16X 0x04 +#define BMP581_DT_OVERSAMPLING_32X 0x05 +#define BMP581_DT_OVERSAMPLING_64X 0x06 +#define BMP581_DT_OVERSAMPLING_128X 0x07 +/** @} */ + +/** + * @defgroup BMP581_IIR_FILTER IIR Filter options. Valid for temperature and pressure. + * @{ + */ +#define BMP581_DT_IIR_FILTER_BYPASS 0x00 +#define BMP581_DT_IIR_FILTER_COEFF_1 0x01 +#define BMP581_DT_IIR_FILTER_COEFF_3 0x02 +#define BMP581_DT_IIR_FILTER_COEFF_7 0x03 +#define BMP581_DT_IIR_FILTER_COEFF_15 0x04 +#define BMP581_DT_IIR_FILTER_COEFF_31 0x05 +#define BMP581_DT_IIR_FILTER_COEFF_63 0x06 +#define BMP581_DT_IIR_FILTER_COEFF_127 0x07 +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_BOSCH_BMP581_H_*/ From 6e5a7dfce55d69323bd28672adf5bb778fe5c325 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Mon, 14 Jul 2025 08:53:45 -0400 Subject: [PATCH 2/4] bmp581: Move bus transfers to work over RTIO In order to abstract details of the transport itself, improving portability. No functional changes at this point. Driver works the same as far as my local testing goes. Signed-off-by: Luis Ubieda --- drivers/sensor/bosch/bmp581/CMakeLists.txt | 6 +- drivers/sensor/bosch/bmp581/Kconfig | 1 + drivers/sensor/bosch/bmp581/bmp581.c | 56 ++++----- drivers/sensor/bosch/bmp581/bmp581.h | 4 +- drivers/sensor/bosch/bmp581/bmp581_bus.c | 125 +++++++++++++++++++++ drivers/sensor/bosch/bmp581/bmp581_bus.h | 38 +++++++ 6 files changed, 203 insertions(+), 27 deletions(-) create mode 100644 drivers/sensor/bosch/bmp581/bmp581_bus.c create mode 100644 drivers/sensor/bosch/bmp581/bmp581_bus.h diff --git a/drivers/sensor/bosch/bmp581/CMakeLists.txt b/drivers/sensor/bosch/bmp581/CMakeLists.txt index 2f471fda359a..b0a560b1e1fa 100644 --- a/drivers/sensor/bosch/bmp581/CMakeLists.txt +++ b/drivers/sensor/bosch/bmp581/CMakeLists.txt @@ -5,4 +5,8 @@ # zephyr_library() -zephyr_library_sources(bmp581.c) +zephyr_library_include_directories(.) +zephyr_library_sources( + bmp581.c + bmp581_bus.c +) diff --git a/drivers/sensor/bosch/bmp581/Kconfig b/drivers/sensor/bosch/bmp581/Kconfig index 325276b7a97a..718c3cdeaf14 100644 --- a/drivers/sensor/bosch/bmp581/Kconfig +++ b/drivers/sensor/bosch/bmp581/Kconfig @@ -8,4 +8,5 @@ config BMP581 bool "BMP581 barometric pressure sensor" depends on DT_HAS_BOSCH_BMP581_ENABLED select I2C + select I2C_RTIO default y diff --git a/drivers/sensor/bosch/bmp581/bmp581.c b/drivers/sensor/bosch/bmp581/bmp581.c index f08beafeea10..e97cbbabf5e6 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.c +++ b/drivers/sensor/bosch/bmp581/bmp581.c @@ -6,6 +6,7 @@ */ #include "bmp581.h" +#include "bmp581_bus.h" #include @@ -60,14 +61,13 @@ static int set_power_mode(enum bmp5_powermode powermode, const struct device *de * Device should be set to standby before transitioning to forced mode or normal * mode or continuous mode. */ - - ret = i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, &odr); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &odr, 1); if (ret == BMP5_OK) { /* Setting deep_dis = 1(BMP5_DEEP_DISABLED) disables the deep standby mode */ odr = BMP5_SET_BITSLICE(odr, BMP5_DEEP_DISABLE, BMP5_DEEP_DISABLED); odr = BMP5_SET_BITS_POS_0(odr, BMP5_POWERMODE, BMP5_POWERMODE_STANDBY); - ret = i2c_reg_write_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, odr); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &odr, 1); if (ret != BMP5_OK) { LOG_DBG("Failed to set power mode to BMP5_POWERMODE_STANDBY."); @@ -92,7 +92,7 @@ static int set_power_mode(enum bmp5_powermode powermode, const struct device *de case BMP5_POWERMODE_CONTINUOUS: odr = BMP5_SET_BITSLICE(odr, BMP5_DEEP_DISABLE, BMP5_DEEP_DISABLED); odr = BMP5_SET_BITS_POS_0(odr, BMP5_POWERMODE, powermode); - ret = i2c_reg_write_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, odr); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &odr, 1); break; default: /* invalid power mode */ @@ -116,7 +116,7 @@ static int get_power_mode(enum bmp5_powermode *powermode, const struct device *d uint8_t reg = 0; uint8_t raw_power_mode = 0; - ret = i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, ®); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, ®, 1); if (ret != BMP5_OK) { LOG_DBG("Failed to read odr config to get power mode!"); return ret; @@ -195,7 +195,7 @@ static int get_interrupt_status(uint8_t *int_status, const struct device *dev) conf = (const struct bmp581_config *)dev->config; - return i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_INT_STATUS, int_status); + return bmp581_reg_read_rtio(&conf->bus, BMP5_REG_INT_STATUS, int_status, 1); } static int get_nvm_status(uint8_t *nvm_status, const struct device *dev) @@ -208,7 +208,7 @@ static int get_nvm_status(uint8_t *nvm_status, const struct device *dev) conf = (const struct bmp581_config *)dev->config; - return i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_STATUS, nvm_status); + return bmp581_reg_read_rtio(&conf->bus, BMP5_REG_STATUS, nvm_status, 1); } static int validate_chip_id(struct bmp581_data *drv) @@ -251,7 +251,7 @@ static int get_osr_odr_press_config(struct bmp581_osr_odr_press_config *osr_odr_ conf = (const struct bmp581_config *)dev->config; /* Get OSR and ODR configuration in burst read */ - rslt = i2c_burst_read_dt(&conf->i2c, BMP5_REG_OSR_CONFIG, reg_data, 2); + rslt = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_OSR_CONFIG, reg_data, 2); if (rslt == BMP5_OK) { osr_odr_press_cfg->osr_t = BMP5_GET_BITS_POS_0(reg_data[0], BMP5_TEMP_OSR); @@ -275,7 +275,7 @@ static int set_osr_odr_press_config(const struct bmp581_osr_odr_press_config *os reg_data[1] = BMP5_SET_BITSLICE(reg_data[1], BMP5_POWERMODE, osr_odr_press_cfg->power_mode); reg_data[1] = BMP5_SET_BITSLICE(reg_data[1], BMP5_ODR, osr_odr_press_cfg->odr); - return i2c_burst_write_dt(&cfg->i2c, BMP5_REG_OSR_CONFIG, reg_data, sizeof(reg_data)); + return bmp581_reg_write_rtio(&cfg->bus, BMP5_REG_OSR_CONFIG, reg_data, sizeof(reg_data)); } static int set_iir_filters_config(const struct bmp581_osr_odr_press_config *osr_odr_press_cfg, @@ -287,7 +287,7 @@ static int set_iir_filters_config(const struct bmp581_osr_odr_press_config *osr_ reg_data = BMP5_SET_BITSLICE(reg_data, BMP5_SET_IIR_TEMP, osr_odr_press_cfg->iir_t); reg_data = BMP5_SET_BITSLICE(reg_data, BMP5_SET_IIR_PRESS, osr_odr_press_cfg->iir_p); - return i2c_burst_write_dt(&cfg->i2c, BMP5_REG_DSP_IIR, ®_data, 1); + return bmp581_reg_write_rtio(&cfg->bus, BMP5_REG_DSP_IIR, ®_data, 1); } static int set_osr_config(const struct sensor_value *osr, enum sensor_channel chan, @@ -305,7 +305,7 @@ static int set_osr_config(const struct sensor_value *osr, enum sensor_channel ch uint8_t press_en = osr->val2 != 0; /* if it is not 0 then pressure is enabled */ uint8_t osr_val = 0; - ret = i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_OSR_CONFIG, &osr_val); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_OSR_CONFIG, &osr_val, 1); if (ret == BMP5_OK) { switch (chan) { case SENSOR_CHAN_ALL: @@ -326,7 +326,7 @@ static int set_osr_config(const struct sensor_value *osr, enum sensor_channel ch } if (ret == BMP5_OK) { - ret = i2c_reg_write_byte_dt(&conf->i2c, BMP5_REG_OSR_CONFIG, osr_val); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_OSR_CONFIG, &osr_val, 1); get_osr_odr_press_config(&drv->osr_odr_press_config, dev); } } @@ -345,12 +345,12 @@ static int set_odr_config(const struct sensor_value *odr, const struct device *d int ret = 0; uint8_t odr_val = 0; - ret = i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, &odr_val); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &odr_val, 1); if (ret != BMP5_OK) { return ret; } odr_val = BMP5_SET_BITSLICE(odr_val, BMP5_ODR, odr->val1); - ret = i2c_reg_write_byte_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, odr_val); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &odr_val, 1); get_osr_odr_press_config(&drv->osr_odr_press_config, dev); return ret; @@ -367,7 +367,7 @@ static int soft_reset(const struct device *dev) return -EINVAL; } - ret = i2c_reg_write_byte_dt(&conf->i2c, BMP5_REG_CMD, reset_cmd); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_CMD, &reset_cmd, 1); if (ret == BMP5_OK) { k_usleep(BMP5_DELAY_US_SOFT_RESET); @@ -401,7 +401,7 @@ static int bmp581_sample_fetch(const struct device *dev, enum sensor_channel cha uint8_t data[6]; int ret = 0; - ret = i2c_burst_read_dt(&conf->i2c, BMP5_REG_TEMP_DATA_XLSB, data, 6); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_TEMP_DATA_XLSB, data, 6); if (ret == BMP5_OK) { /* convert raw sensor data to sensor_value. Shift the decimal part by 1 decimal * place to compensate for the conversion in sensor_value_to_double() @@ -473,7 +473,7 @@ static int set_iir_config(const struct sensor_value *iir, const struct device *d /* update IIR config */ uint8_t dsp_config[2]; - ret = i2c_burst_read_dt(&conf->i2c, BMP5_REG_DSP_CONFIG, dsp_config, 2); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_DSP_CONFIG, dsp_config, 2); if (ret != BMP5_OK) { LOG_DBG("Failed to read dsp config register."); return ret; @@ -487,7 +487,7 @@ static int set_iir_config(const struct sensor_value *iir, const struct device *d dsp_config[1] = BMP5_SET_BITSLICE(dsp_config[1], BMP5_SET_IIR_PRESS, iir->val2); /* Set IIR configuration */ - ret = i2c_burst_write_dt(&conf->i2c, BMP5_REG_DSP_CONFIG, dsp_config, 2); + ret = bmp581_reg_write_rtio(&conf->bus, BMP5_REG_DSP_CONFIG, dsp_config, 2); if (ret != BMP5_OK) { LOG_DBG("Failed to configure IIR filter."); @@ -550,7 +550,7 @@ static int bmp581_init(const struct device *dev) soft_reset(dev); - ret = i2c_reg_read_byte_dt(&conf->i2c, BMP5_REG_CHIP_ID, &drv->chip_id); + ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_CHIP_ID, &drv->chip_id, 1); if (ret != BMP5_OK) { return ret; } @@ -592,12 +592,11 @@ static DEVICE_API(sensor, bmp581_driver_api) = { .attr_set = bmp581_attr_set, }; -#define BMP581_CONFIG(i) \ - static const struct bmp581_config bmp581_config_##i = { \ - .i2c = I2C_DT_SPEC_INST_GET(i), \ - } - #define BMP581_INIT(i) \ + \ + RTIO_DEFINE(bmp581_rtio_ctx_##i, 8, 8); \ + I2C_DT_IODEV_DEFINE(bmp581_bus_##i, DT_DRV_INST(i)); \ + \ static struct bmp581_data bmp581_data_##i = { \ .osr_odr_press_config = { \ .press_en = 1, \ @@ -609,7 +608,14 @@ static DEVICE_API(sensor, bmp581_driver_api) = { .power_mode = DT_INST_PROP(i, power_mode), \ }, \ }; \ - BMP581_CONFIG(i); \ + \ + static const struct bmp581_config bmp581_config_##i = { \ + .bus.rtio = { \ + .ctx = &bmp581_rtio_ctx_##i, \ + .iodev = &bmp581_bus_##i, \ + .type = BMP581_BUS_TYPE_I2C, \ + }, \ + }; \ \ SENSOR_DEVICE_DT_INST_DEFINE(i, bmp581_init, NULL, &bmp581_data_##i, &bmp581_config_##i, \ POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ diff --git a/drivers/sensor/bosch/bmp581/bmp581.h b/drivers/sensor/bosch/bmp581/bmp581.h index cda5504fb950..4fd55c0925c2 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.h +++ b/drivers/sensor/bosch/bmp581/bmp581.h @@ -20,6 +20,8 @@ #include #include +#include "bmp581_bus.h" + #define DT_DRV_COMPAT bosch_bmp581 /* UTILITY MACROS */ @@ -319,7 +321,7 @@ struct bmp581_data { }; struct bmp581_config { - struct i2c_dt_spec i2c; + struct bmp581_bus bus; }; #endif /* ZEPHYR_DRIVERS_SENSOR_BMP581_BMP581_H_ */ diff --git a/drivers/sensor/bosch/bmp581/bmp581_bus.c b/drivers/sensor/bosch/bmp581/bmp581_bus.c new file mode 100644 index 000000000000..f3df5a388b06 --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_bus.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bmp581_bus.h" + +int bmp581_prep_reg_read_rtio_async(const struct bmp581_bus *bus, + uint8_t reg, uint8_t *buf, size_t size, + struct rtio_sqe **out) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_iodev *iodev = bus->rtio.iodev; + struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(ctx); + struct rtio_sqe *read_buf_sqe = rtio_sqe_acquire(ctx); + + if (!write_reg_sqe || !read_buf_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + + rtio_sqe_prep_tiny_write(write_reg_sqe, iodev, RTIO_PRIO_NORM, ®, 1, NULL); + write_reg_sqe->flags |= RTIO_SQE_TRANSACTION; + rtio_sqe_prep_read(read_buf_sqe, iodev, RTIO_PRIO_NORM, buf, size, NULL); + if (bus->rtio.type == BMP581_BUS_TYPE_I2C) { + read_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; + } + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = read_buf_sqe; + } + + return 2; +} + +int bmp581_prep_reg_write_rtio_async(const struct bmp581_bus *bus, + uint8_t reg, const uint8_t *buf, size_t size, + struct rtio_sqe **out) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_iodev *iodev = bus->rtio.iodev; + struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(ctx); + struct rtio_sqe *write_buf_sqe = rtio_sqe_acquire(ctx); + + if (!write_reg_sqe || !write_buf_sqe) { + rtio_sqe_drop_all(ctx); + return -ENOMEM; + } + + /** More than 7 won't work with tiny-write */ + if (size > 7) { + return -EINVAL; + } + + rtio_sqe_prep_tiny_write(write_reg_sqe, iodev, RTIO_PRIO_NORM, ®, 1, NULL); + write_reg_sqe->flags |= RTIO_SQE_TRANSACTION; + rtio_sqe_prep_tiny_write(write_buf_sqe, iodev, RTIO_PRIO_NORM, buf, size, NULL); + if (bus->rtio.type == BMP581_BUS_TYPE_I2C) { + write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP; + } + + /** Send back last SQE so it can be concatenated later. */ + if (out) { + *out = write_buf_sqe; + } + + return 2; +} + +int bmp581_reg_read_rtio(const struct bmp581_bus *bus, uint8_t start, uint8_t *buf, int size) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_cqe *cqe; + int ret; + + ret = bmp581_prep_reg_read_rtio_async(bus, start, buf, size, NULL); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} + +int bmp581_reg_write_rtio(const struct bmp581_bus *bus, uint8_t reg, const uint8_t *buf, int size) +{ + struct rtio *ctx = bus->rtio.ctx; + struct rtio_cqe *cqe; + int ret; + + ret = bmp581_prep_reg_write_rtio_async(bus, reg, buf, size, NULL); + if (ret < 0) { + return ret; + } + + ret = rtio_submit(ctx, ret); + if (ret) { + return ret; + } + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + ret = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + return ret; +} diff --git a/drivers/sensor/bosch/bmp581/bmp581_bus.h b/drivers/sensor/bosch/bmp581/bmp581_bus.h new file mode 100644 index 000000000000..7e7921a223ea --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_bus.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMP581_BMP581_BUS_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMP581_BMP581_BUS_H_ + +#include +#include + +enum bmp581_bus_type { + BMP581_BUS_TYPE_I2C, +}; + +struct bmp581_bus { + struct { + struct rtio *ctx; + struct rtio_iodev *iodev; + enum bmp581_bus_type type; + } rtio; +}; + +int bmp581_prep_reg_read_rtio_async(const struct bmp581_bus *bus, + uint8_t reg, uint8_t *buf, size_t size, + struct rtio_sqe **out); + +int bmp581_prep_reg_write_rtio_async(const struct bmp581_bus *bus, + uint8_t reg, const uint8_t *buf, size_t size, + struct rtio_sqe **out); + +int bmp581_reg_read_rtio(const struct bmp581_bus *bus, uint8_t start, uint8_t *buf, int size); + +int bmp581_reg_write_rtio(const struct bmp581_bus *bus, uint8_t reg, const uint8_t *buf, int size); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMP581_BMP581_BUS_H_ */ From 6da536e58ba8d59fa8b6733512031bc3edbba69d Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Mon, 14 Jul 2025 18:10:22 -0400 Subject: [PATCH 3/4] bmp581: Add One-shot Read-Decode support Decoding one-shot reads through submit API. Signed-off-by: Luis Ubieda --- drivers/sensor/bosch/bmp581/CMakeLists.txt | 3 + drivers/sensor/bosch/bmp581/bmp581.c | 97 +++++++++ drivers/sensor/bosch/bmp581/bmp581_decoder.c | 199 +++++++++++++++++++ drivers/sensor/bosch/bmp581/bmp581_decoder.h | 33 +++ 4 files changed, 332 insertions(+) create mode 100644 drivers/sensor/bosch/bmp581/bmp581_decoder.c create mode 100644 drivers/sensor/bosch/bmp581/bmp581_decoder.h diff --git a/drivers/sensor/bosch/bmp581/CMakeLists.txt b/drivers/sensor/bosch/bmp581/CMakeLists.txt index b0a560b1e1fa..8189d7151f6f 100644 --- a/drivers/sensor/bosch/bmp581/CMakeLists.txt +++ b/drivers/sensor/bosch/bmp581/CMakeLists.txt @@ -10,3 +10,6 @@ zephyr_library_sources( bmp581.c bmp581_bus.c ) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API + bmp581_decoder.c +) diff --git a/drivers/sensor/bosch/bmp581/bmp581.c b/drivers/sensor/bosch/bmp581/bmp581.c index e97cbbabf5e6..feb86c9c9b0b 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.c +++ b/drivers/sensor/bosch/bmp581/bmp581.c @@ -7,6 +7,7 @@ #include "bmp581.h" #include "bmp581_bus.h" +#include "bmp581_decoder.h" #include @@ -586,10 +587,106 @@ static int bmp581_init(const struct device *dev) return ret; } +#ifdef CONFIG_SENSOR_ASYNC_API + +static void bmp581_complete_result(struct rtio *ctx, const struct rtio_sqe *sqe, void *arg) +{ + struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)arg; + struct rtio_cqe *cqe; + int err = 0; + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe != NULL) { + err = cqe->result; + rtio_cqe_release(ctx, cqe); + } + } while (cqe != NULL); + + if (err != 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + } else { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } +} + +static void bmp581_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + uint32_t min_buf_len = sizeof(struct bmp581_encoded_data); + int err; + uint8_t *buf; + uint32_t buf_len; + struct bmp581_encoded_data *edata; + const struct bmp581_config *conf = dev->config; + + err = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); + CHECKIF((err < 0) || (buf_len < min_buf_len) || !buf) { + LOG_ERR("Failed to get a read buffer of size %u bytes", min_buf_len); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + + edata = (struct bmp581_encoded_data *)buf; + + err = bmp581_encode(dev, cfg, 0, buf); + if (err != 0) { + LOG_ERR("Failed to encode sensor data"); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + + struct rtio_sqe *read_sqe; + + err = bmp581_prep_reg_read_rtio_async(&conf->bus, BMP5_REG_TEMP_DATA_XLSB, + edata->payload, sizeof(edata->payload), + &read_sqe); + if (err < 0) { + LOG_ERR("Failed to prepare async read operation"); + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + read_sqe->flags |= RTIO_SQE_CHAINED; + + struct rtio_sqe *complete_sqe = rtio_sqe_acquire(conf->bus.rtio.ctx); + + if (!complete_sqe) { + LOG_ERR("Failed to acquire completion SQE"); + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + rtio_sqe_drop_all(conf->bus.rtio.ctx); + return; + } + + rtio_sqe_prep_callback_no_cqe(complete_sqe, + bmp581_complete_result, + iodev_sqe, + (void *)dev); + + rtio_submit(conf->bus.rtio.ctx, 0); +} + +static void bmp581_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + + if (!cfg->is_streaming) { + bmp581_submit_one_shot(dev, iodev_sqe); + } else { + LOG_ERR("Streaming not supported"); + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + } +} + +#endif /* #ifdef CONFIG_SENSOR_ASYNC_API */ + static DEVICE_API(sensor, bmp581_driver_api) = { .sample_fetch = bmp581_sample_fetch, .channel_get = bmp581_channel_get, .attr_set = bmp581_attr_set, +#ifdef CONFIG_SENSOR_ASYNC_API + .submit = bmp581_submit, + .get_decoder = bmp581_get_decoder, +#endif }; #define BMP581_INIT(i) \ diff --git a/drivers/sensor/bosch/bmp581/bmp581_decoder.c b/drivers/sensor/bosch/bmp581/bmp581_decoder.c new file mode 100644 index 000000000000..e0bb631962bc --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_decoder.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "bmp581.h" +#include "bmp581_decoder.h" + +#include +LOG_MODULE_REGISTER(BMP581_DECODER, CONFIG_SENSOR_LOG_LEVEL); + +static uint8_t bmp581_encode_channel(enum sensor_channel chan) +{ + uint8_t encode_bmask = 0; + + switch (chan) { + case SENSOR_CHAN_AMBIENT_TEMP: + encode_bmask |= BIT(0); + break; + case SENSOR_CHAN_PRESS: + encode_bmask |= BIT(1); + break; + case SENSOR_CHAN_ALL: + encode_bmask |= BIT(0) | BIT(1); + break; + default: + break; + } + + return encode_bmask; +} + +int bmp581_encode(const struct device *dev, + const struct sensor_read_config *read_config, + uint8_t trigger_status, + uint8_t *buf) +{ + struct bmp581_encoded_data *edata = (struct bmp581_encoded_data *)buf; + struct bmp581_data *data = dev->data; + uint64_t cycles; + int err; + + edata->header.channels = 0; + edata->header.press_en = data->osr_odr_press_config.press_en; + + if (trigger_status) { + edata->header.channels |= bmp581_encode_channel(SENSOR_CHAN_ALL); + } else { + const struct sensor_chan_spec *const channels = read_config->channels; + size_t num_channels = read_config->count; + + for (size_t i = 0; i < num_channels; i++) { + edata->header.channels |= bmp581_encode_channel(channels[i].chan_type); + } + } + + err = sensor_clock_get_cycles(&cycles); + if (err != 0) { + return err; + } + + edata->header.events = trigger_status ? BIT(0) : 0; + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); + + return 0; +} + +static int bmp581_decoder_get_frame_count(const uint8_t *buffer, + struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + const struct bmp581_encoded_data *edata = (const struct bmp581_encoded_data *)buffer; + + if (chan_spec.chan_idx != 0) { + return -ENOTSUP; + } + + uint8_t channel_request = bmp581_encode_channel(chan_spec.chan_type); + + /* Filter unknown channels and having no data */ + if ((edata->header.channels & channel_request) != channel_request) { + return -ENODATA; + } + + *frame_count = 1; + return 0; +} + +static int bmp581_decoder_get_size_info(struct sensor_chan_spec chan_spec, + size_t *base_size, + size_t *frame_size) +{ + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: + case SENSOR_CHAN_PRESS: + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + +static int bmp581_decoder_decode(const uint8_t *buffer, + struct sensor_chan_spec chan_spec, + uint32_t *fit, + uint16_t max_count, + void *data_out) +{ + const struct bmp581_encoded_data *edata = (const struct bmp581_encoded_data *)buffer; + uint8_t channel_request; + + if (*fit != 0) { + return 0; + } + + if (max_count == 0 || chan_spec.chan_idx != 0) { + return -EINVAL; + } + + channel_request = bmp581_encode_channel(chan_spec.chan_type); + if ((channel_request & edata->header.channels) != channel_request) { + return -ENODATA; + } + + struct sensor_q31_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_AMBIENT_TEMP: { + /* Temperature is in data[2:0], data[2] is integer part */ + uint32_t raw_temp = ((uint32_t)edata->payload[2] << 16) | + ((uint16_t)edata->payload[1] << 8) | + edata->payload[0]; + int32_t raw_temp_signed = sign_extend(raw_temp, 23); + + out->shift = (31 - 16); /* 16 left shifts gives us the value in celsius */ + out->readings[0].value = raw_temp_signed; + break; + } + case SENSOR_CHAN_PRESS: + if (!edata->header.press_en) { + return -ENODATA; + } + /* Shift by 10 bits because we'll divide by 1000 to make it kPa */ + uint64_t raw_press = (((uint32_t)edata->payload[5] << 16) | + ((uint16_t)edata->payload[4] << 8) | + edata->payload[3]); + + int64_t raw_press_signed = sign_extend_64(raw_press, 23); + + raw_press_signed *= 1024; + raw_press_signed /= 1000; + + /* Original value was in Pa by left-shifting 6 spaces, but + * we've multiplied by 2^10 to not lose precision when + * converting to kPa. Hence, left-shift 16 spaces. + */ + out->shift = (31 - 6 - 10); + out->readings[0].value = (int32_t)raw_press_signed; + break; + default: + return -EINVAL; + } + + *fit = 1; + return 1; +} + +static bool bmp581_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) +{ + const struct bmp581_encoded_data *edata = (const struct bmp581_encoded_data *)buffer; + + if ((trigger == SENSOR_TRIG_DATA_READY) && (edata->header.events != 0)) { + return true; + } + + return false; +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = bmp581_decoder_get_frame_count, + .get_size_info = bmp581_decoder_get_size_info, + .decode = bmp581_decoder_decode, + .has_trigger = bmp581_decoder_has_trigger, +}; + +int bmp581_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +{ + ARG_UNUSED(dev); + *decoder = &SENSOR_DECODER_NAME(); + return 0; +} diff --git a/drivers/sensor/bosch/bmp581/bmp581_decoder.h b/drivers/sensor/bosch/bmp581/bmp581_decoder.h new file mode 100644 index 000000000000..3150408d3053 --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_decoder.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Croxel, Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMP581_DECODER_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMP581_DECODER_H_ + +#include +#include +#include "bmp581.h" + +struct bmp581_encoded_data { + struct { + uint8_t channels; + uint8_t events; + uint64_t timestamp; + uint8_t press_en; + } header; + uint8_t payload[6]; /* 3 bytes temp + 3 bytes press */ +}; + +int bmp581_encode(const struct device *dev, + const struct sensor_read_config *read_config, + uint8_t trigger_status, + uint8_t *buf); + +int bmp581_get_decoder(const struct device *dev, + const struct sensor_decoder_api **decoder); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMP581_DECODER_H_ */ From 95ef866850d28665021668643c9fed0c2281f366 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Mon, 14 Jul 2025 19:13:57 -0400 Subject: [PATCH 4/4] bmp581: Add Streaming support Working only with DRDY Interrupts. FIFO watermark not added yet. Signed-off-by: Luis Ubieda --- drivers/sensor/bosch/bmp581/CMakeLists.txt | 4 + drivers/sensor/bosch/bmp581/Kconfig | 9 + drivers/sensor/bosch/bmp581/bmp581.c | 12 + drivers/sensor/bosch/bmp581/bmp581.h | 11 + drivers/sensor/bosch/bmp581/bmp581_stream.c | 238 ++++++++++++++++++++ drivers/sensor/bosch/bmp581/bmp581_stream.h | 18 ++ 6 files changed, 292 insertions(+) create mode 100644 drivers/sensor/bosch/bmp581/bmp581_stream.c create mode 100644 drivers/sensor/bosch/bmp581/bmp581_stream.h diff --git a/drivers/sensor/bosch/bmp581/CMakeLists.txt b/drivers/sensor/bosch/bmp581/CMakeLists.txt index 8189d7151f6f..40d1a4a9f020 100644 --- a/drivers/sensor/bosch/bmp581/CMakeLists.txt +++ b/drivers/sensor/bosch/bmp581/CMakeLists.txt @@ -13,3 +13,7 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API bmp581_decoder.c ) + +zephyr_library_sources_ifdef(CONFIG_BMP581_STREAM + bmp581_stream.c +) diff --git a/drivers/sensor/bosch/bmp581/Kconfig b/drivers/sensor/bosch/bmp581/Kconfig index 718c3cdeaf14..f9768d9321f9 100644 --- a/drivers/sensor/bosch/bmp581/Kconfig +++ b/drivers/sensor/bosch/bmp581/Kconfig @@ -1,5 +1,7 @@ # # Copyright (c) 2022 Badgerd Technologies B.V and its affiliates +# Copyright (c) 2025 Croxel, Inc. +# Copyright (c) 2025 CogniPilot Foundation # # SPDX-License-Identifier: Apache-2.0 # @@ -10,3 +12,10 @@ config BMP581 select I2C select I2C_RTIO default y + +config BMP581_STREAM + bool "Streaming mode" + default y + depends on SENSOR_ASYNC_API + depends on GPIO + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_BOSCH_BMP581),int-gpios) diff --git a/drivers/sensor/bosch/bmp581/bmp581.c b/drivers/sensor/bosch/bmp581/bmp581.c index feb86c9c9b0b..7258d8f6fd8b 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.c +++ b/drivers/sensor/bosch/bmp581/bmp581.c @@ -8,6 +8,7 @@ #include "bmp581.h" #include "bmp581_bus.h" #include "bmp581_decoder.h" +#include "bmp581_stream.h" #include @@ -584,6 +585,14 @@ static int bmp581_init(const struct device *dev) return ret; } + if (IS_ENABLED(CONFIG_BMP581_STREAM)) { + ret = bmp581_stream_init(dev); + if (ret != 0) { + LOG_ERR("Failed to initialize streaming support: %d", ret); + return ret; + } + } + return ret; } @@ -671,6 +680,8 @@ static void bmp581_submit(const struct device *dev, struct rtio_iodev_sqe *iodev if (!cfg->is_streaming) { bmp581_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_BMP581_STREAM)) { + bmp581_stream_submit(dev, iodev_sqe); } else { LOG_ERR("Streaming not supported"); rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); @@ -712,6 +723,7 @@ static DEVICE_API(sensor, bmp581_driver_api) = { .iodev = &bmp581_bus_##i, \ .type = BMP581_BUS_TYPE_I2C, \ }, \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(i, int_gpios, {0}), \ }; \ \ SENSOR_DEVICE_DT_INST_DEFINE(i, bmp581_init, NULL, &bmp581_data_##i, &bmp581_config_##i, \ diff --git a/drivers/sensor/bosch/bmp581/bmp581.h b/drivers/sensor/bosch/bmp581/bmp581.h index 4fd55c0925c2..befdf24f4f58 100644 --- a/drivers/sensor/bosch/bmp581/bmp581.h +++ b/drivers/sensor/bosch/bmp581/bmp581.h @@ -151,6 +151,7 @@ /* Interrupt configurations */ #define BMP5_INT_MODE_MSK 0x01 +#define BMP5_INT_MODE_POS 0 #define BMP5_INT_POL_MSK 0x02 #define BMP5_INT_POL_POS 1 @@ -162,6 +163,7 @@ #define BMP5_INT_EN_POS 3 #define BMP5_INT_DRDY_EN_MSK 0x01 +#define BMP5_INT_DRDY_EN_POS 0 #define BMP5_INT_FIFO_FULL_EN_MSK 0x02 #define BMP5_INT_FIFO_FULL_EN_POS 1 @@ -314,14 +316,23 @@ struct bmp581_sample { struct sensor_value temperature; }; +struct bmp581_stream { + const struct device *dev; + struct gpio_callback cb; + struct rtio_iodev_sqe *iodev_sqe; + atomic_t state; +}; + struct bmp581_data { uint8_t chip_id; struct bmp581_sample last_sample; struct bmp581_osr_odr_press_config osr_odr_press_config; + struct bmp581_stream stream; }; struct bmp581_config { struct bmp581_bus bus; + struct gpio_dt_spec int_gpio; }; #endif /* ZEPHYR_DRIVERS_SENSOR_BMP581_BMP581_H_ */ diff --git a/drivers/sensor/bosch/bmp581/bmp581_stream.c b/drivers/sensor/bosch/bmp581/bmp581_stream.c new file mode 100644 index 000000000000..0b66c704e6d0 --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_stream.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2025 Croxel Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +#include "bmp581.h" +#include "bmp581_stream.h" +#include "bmp581_decoder.h" + +#include +LOG_MODULE_REGISTER(BMP581_STREAM, CONFIG_SENSOR_LOG_LEVEL); + +enum bmp581_stream_state { + BMP581_STREAM_OFF = 0, + BMP581_STREAM_ON = 1, + BMP581_STREAM_BUSY = 2, +}; + +static void bmp581_stream_event_complete(struct rtio *ctx, const struct rtio_sqe *sqe, void *arg0) +{ + struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)arg0; + const struct device *dev = (const struct device *)sqe->userdata; + struct bmp581_data *data = dev->data; + uint8_t *buf; + uint32_t buf_len; + struct rtio_cqe *cqe; + int err = 0; + + do { + cqe = rtio_cqe_consume(ctx); + if (cqe == NULL) { + continue; + } + + if (err == 0) { + err = cqe->result; + } + rtio_cqe_release(ctx, cqe); + } while (cqe != NULL); + + if (err != 0) { + goto bmp581_stream_evt_finish; + } + + err = rtio_sqe_rx_buf(iodev_sqe, 0, 0, &buf, &buf_len); + + CHECKIF(err != 0 || !buf || buf_len < sizeof(struct bmp581_encoded_data)) { + LOG_ERR("Couldn't get encoded buffer on completion"); + err = -EIO; + goto bmp581_stream_evt_finish; + } + + err = bmp581_encode(dev, (struct sensor_read_config *)iodev_sqe->sqe.iodev->data, + 0x01, buf); + if (err != 0) { + LOG_ERR("Failed to encode frame: %d", err); + goto bmp581_stream_evt_finish; + } + +bmp581_stream_evt_finish: + atomic_set(&data->stream.state, BMP581_STREAM_ON); + + if (err < 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + } else { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } +} + +static void bmp581_event_handler(const struct device *dev) +{ + struct bmp581_data *data = dev->data; + const struct bmp581_config *cfg = dev->config; + struct rtio_iodev_sqe *iodev_sqe = data->stream.iodev_sqe; + uint8_t *buf = NULL; + uint32_t buf_len = 0; + int err; + + CHECKIF(!data->stream.iodev_sqe || FIELD_GET(RTIO_SQE_CANCELED, iodev_sqe->sqe.flags)) { + + uint8_t val = 0; + + LOG_WRN("Callback triggered with no streaming submission - Disabling interrupts"); + + (void)gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + + err = bmp581_prep_reg_write_rtio_async(&cfg->bus, BMP5_REG_INT_SOURCE, &val, 1, + NULL); + if (err >= 0) { + rtio_submit(cfg->bus.rtio.ctx, 0); + } + + (void)atomic_set(&data->stream.state, BMP581_STREAM_OFF); + + return; + } + + CHECKIF(atomic_cas(&data->stream.state, BMP581_STREAM_ON, BMP581_STREAM_BUSY) == false) { + LOG_WRN("Callback triggered while stream is busy. Ignoring request"); + return; + } + + err = rtio_sqe_rx_buf(iodev_sqe, + sizeof(struct bmp581_encoded_data), + sizeof(struct bmp581_encoded_data), + &buf, &buf_len); + CHECKIF(err != 0 || buf_len < sizeof(struct bmp581_encoded_data)) { + LOG_ERR("Failed to allocate BMP581 encoded buffer: %d", err); + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + return; + } + + struct bmp581_encoded_data *edata = (struct bmp581_encoded_data *)buf; + struct rtio_sqe *read_sqe = NULL; + struct rtio_sqe *cb_sqe; + + err = bmp581_prep_reg_read_rtio_async(&cfg->bus, BMP5_REG_TEMP_DATA_XLSB, + edata->payload, sizeof(edata->payload), + &read_sqe); + CHECKIF(err < 0 || !read_sqe) { + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + read_sqe->flags |= RTIO_SQE_CHAINED; + + cb_sqe = rtio_sqe_acquire(cfg->bus.rtio.ctx); + if (cb_sqe == NULL) { + LOG_ERR("Failed to acquire callback SQE"); + rtio_iodev_sqe_err(iodev_sqe, -ENOMEM); + return; + } + + rtio_sqe_prep_callback_no_cqe(cb_sqe, bmp581_stream_event_complete, + iodev_sqe, (void *)dev); + + rtio_submit(cfg->bus.rtio.ctx, 0); +} + +static void bmp581_gpio_callback(const struct device *port, struct gpio_callback *cb, uint32_t pin) +{ + struct bmp581_stream *stream = CONTAINER_OF(cb, struct bmp581_stream, cb); + const struct device *dev = stream->dev; + + bmp581_event_handler(dev); +} + +void bmp581_stream_submit(const struct device *dev, + struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *read_config = iodev_sqe->sqe.iodev->data; + struct bmp581_data *data = dev->data; + const struct bmp581_config *cfg = dev->config; + int err; + + if ((read_config->count != 1) || + (read_config->triggers[0].trigger != SENSOR_TRIG_DATA_READY)) { + LOG_ERR("Only SENSOR_TRIG_DATA_READY is supported"); + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + return; + } + + data->stream.iodev_sqe = iodev_sqe; + + if (atomic_cas(&data->stream.state, BMP581_STREAM_OFF, BMP581_STREAM_ON)) { + /* Enable DRDY interrupt */ + struct rtio_sqe *int_src_sqe; + uint8_t val = 0; + + val = BMP5_SET_BITSLICE(val, BMP5_INT_DRDY_EN, 1); + + err = bmp581_prep_reg_write_rtio_async(&cfg->bus, BMP5_REG_INT_SOURCE, &val, 1, + &int_src_sqe); + if (err < 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + int_src_sqe->flags |= RTIO_SQE_CHAINED; + + val = BMP5_SET_BITSLICE(val, BMP5_INT_MODE, BMP5_INT_MODE_PULSED); + val = BMP5_SET_BITSLICE(val, BMP5_INT_POL, BMP5_INT_POL_ACTIVE_HIGH); + val = BMP5_SET_BITSLICE(val, BMP5_INT_OD, BMP5_INT_OD_PUSHPULL); + val = BMP5_SET_BITSLICE(val, BMP5_INT_EN, 1); + + err = bmp581_prep_reg_write_rtio_async(&cfg->bus, BMP5_REG_INT_CONFIG, &val, 1, + NULL); + if (err < 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + return; + } + + (void)rtio_submit(cfg->bus.rtio.ctx, 0); + + err = gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (err < 0) { + rtio_iodev_sqe_err(iodev_sqe, err); + } + } +} + +int bmp581_stream_init(const struct device *dev) +{ + struct bmp581_data *data = dev->data; + const struct bmp581_config *cfg = dev->config; + int err; + + data->stream.dev = dev; + atomic_set(&data->stream.state, BMP581_STREAM_OFF); + + if (!device_is_ready(cfg->int_gpio.port)) { + LOG_ERR("DRDY GPIO device is not ready"); + return -ENODEV; + } + + err = gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT); + if (err < 0) { + return err; + } + + gpio_init_callback(&data->stream.cb, bmp581_gpio_callback, BIT(cfg->int_gpio.pin)); + + err = gpio_add_callback(cfg->int_gpio.port, &data->stream.cb); + if (err < 0) { + return err; + } + + err = gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_DISABLE); + if (err < 0) { + return err; + } + + return 0; +} diff --git a/drivers/sensor/bosch/bmp581/bmp581_stream.h b/drivers/sensor/bosch/bmp581/bmp581_stream.h new file mode 100644 index 000000000000..1c43965b9641 --- /dev/null +++ b/drivers/sensor/bosch/bmp581/bmp581_stream.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Croxel Inc. + * Copyright (c) 2025 CogniPilot Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_BMP581_STREAM_H_ +#define ZEPHYR_DRIVERS_SENSOR_BMP581_STREAM_H_ + +#include +#include + +int bmp581_stream_init(const struct device *dev); + +void bmp581_stream_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); + +#endif /* ZEPHYR_DRIVERS_SENSOR_BMP581_STREAM_H_ */