Commit a32d5c15 authored by Luis Ubieda's avatar Luis Ubieda Committed by Anas Nashif
Browse files

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: default avatarLuis Ubieda <luisf@croxel.com>
parent c62e4b5a
Loading
Loading
Loading
Loading
+5 −1
Changes for drivers/sensor/bosch/bmp581/CMakeLists.txt: 5 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -5,4 +5,8 @@
#

zephyr_library()
zephyr_library_sources(bmp581.c)
zephyr_library_include_directories(.)
zephyr_library_sources(
	bmp581.c
	bmp581_bus.c
)
+1 −0
Changes for drivers/sensor/bosch/bmp581/Kconfig: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -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
+31 −25
Changes for drivers/sensor/bosch/bmp581/bmp581.c: 31 added lines, 25 removed lines.
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */

#include "bmp581.h"
#include "bmp581_bus.h"

#include <math.h>

@@ -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, &reg);
	ret = bmp581_reg_read_rtio(&conf->bus, BMP5_REG_ODR_CONFIG, &reg, 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, &reg_data, 1);
	return bmp581_reg_write_rtio(&cfg->bus, BMP5_REG_DSP_IIR, &reg_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,                     \
+3 −1
Changes for drivers/sensor/bosch/bmp581/bmp581.h: 3 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
#include <zephyr/types.h>
#include <zephyr/drivers/sensor/bmp581_user.h>

#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_ */
+125 −0
Changes for drivers/sensor/bosch/bmp581/bmp581_bus.c: 125 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
 * 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, &reg, 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, &reg, 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;
}
Loading