drivers: sensor: adxl345: Support for RTIO I2C stream

Updated ADXL345 driver with RTIO I2C stream functionality.

Signed-off-by: Dimitrije Lilic <dimitrije.lilic@orioninc.com>
This commit is contained in:
Dimitrije Lilic 2024-11-21 14:23:48 +01:00 committed by Benjamin Cabé
parent fa8ebd3e45
commit 088afe9359
5 changed files with 55 additions and 11 deletions

View file

@ -38,7 +38,7 @@ config ADXL345_STREAM
bool "Use FIFO to stream data"
select ADXL345_TRIGGER
default y
depends on SPI_RTIO
depends on (SPI_RTIO || I2C_RTIO)
depends on SENSOR_ASYNC_API
help
Use this configuration option to enable streaming sensor data via RTIO.

View file

@ -519,18 +519,43 @@ static int adxl345_init(const struct device *dev)
#define ADXL345_CFG_IRQ(inst)
#endif /* CONFIG_ADXL345_TRIGGER */
#define ADXL345_RTIO_DEFINE(inst) \
SPI_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst), \
SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \
SPI_MODE_CPOL | SPI_MODE_CPHA, 0U); \
RTIO_DEFINE(adxl345_rtio_ctx_##inst, 64, 64);
#define ADXL345_RTIO_SPI_DEFINE(inst) \
COND_CODE_1(CONFIG_SPI_RTIO, \
(SPI_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst), \
SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \
SPI_MODE_CPOL | SPI_MODE_CPHA, 0U);), \
())
#define ADXL345_RTIO_I2C_DEFINE(inst) \
COND_CODE_1(CONFIG_I2C_RTIO, \
(I2C_DT_IODEV_DEFINE(adxl345_iodev_##inst, DT_DRV_INST(inst));), \
())
/* Conditionally set the RTIO size based on the presence of SPI/I2C
* lines 541 - 542.
* The sizes of sqe and cqe pools are increased due to the amount of
* multibyte reads needed for watermark using 31 samples
* (adx345_stram - line 203), using smaller amounts of samples
* to trigger an interrupt can decrease the pool sizes.
*/
#define ADXL345_RTIO_DEFINE(inst) \
/* Conditionally include SPI and/or I2C parts based on their presence */ \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
(ADXL345_RTIO_SPI_DEFINE(inst)), \
()) \
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
(ADXL345_RTIO_I2C_DEFINE(inst)), \
()) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, spi_dt_spec) && \
DT_INST_NODE_HAS_PROP(inst, i2c_dt_spec), \
(RTIO_DEFINE(adxl345_rtio_ctx_##inst, 128, 128);), \
(RTIO_DEFINE(adxl345_rtio_ctx_##inst, 64, 64);)) \
#define ADXL345_CONFIG(inst) \
.odr = DT_INST_PROP(inst, odr), \
.fifo_config.fifo_mode = ADXL345_FIFO_STREAMED, \
.fifo_config.fifo_trigger = ADXL345_INT2, \
.fifo_config.fifo_samples = SAMPLE_NUM, \
.op_mode = TRUE, \
.odr = ADXL345_RATE_25HZ, \
#define ADXL345_CONFIG_SPI(inst) \
@ -543,6 +568,7 @@ static int adxl345_init(const struct device *dev)
0)}, \
.bus_is_ready = adxl345_bus_is_ready_spi, \
.reg_access = adxl345_reg_access_spi, \
.bus_type = ADXL345_BUS_SPI, \
ADXL345_CONFIG(inst) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int2_gpios), \
(ADXL345_CFG_IRQ(inst)), ()) \
@ -553,13 +579,17 @@ static int adxl345_init(const struct device *dev)
.bus = {.i2c = I2C_DT_SPEC_INST_GET(inst)}, \
.bus_is_ready = adxl345_bus_is_ready_i2c, \
.reg_access = adxl345_reg_access_i2c, \
.bus_type = ADXL345_BUS_I2C, \
ADXL345_CONFIG(inst) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int2_gpios), \
(ADXL345_CFG_IRQ(inst)), ()) \
}
#define ADXL345_DEFINE(inst) \
IF_ENABLED(CONFIG_ADXL345_STREAM, (ADXL345_RTIO_DEFINE(inst))); \
static struct adxl345_dev_data adxl345_data_##inst = { \
IF_ENABLED(CONFIG_ADXL345_STREAM, (.rtio_ctx = &adxl345_rtio_ctx_##inst, \
.iodev = &adxl345_iodev_##inst,)) \
static struct adxl345_dev_data adxl345_data_##inst = { \
COND_CODE_1(adxl345_iodev_##inst, (.rtio_ctx = &adxl345_rtio_ctx_##inst, \
.iodev = &adxl345_iodev_##inst,), ()) \
}; \
static const struct adxl345_dev_config adxl345_config_##inst = \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), (ADXL345_CONFIG_SPI(inst)), \

View file

@ -113,6 +113,9 @@
#define ADXL345_ODR_MSK GENMASK(3, 0)
#define ADXL345_ODR_MODE(x) ((x) & 0xF)
#define ADXL345_BUS_I2C 0
#define ADXL345_BUS_SPI 1
enum adxl345_odr {
ADXL345_ODR_12HZ = 0x7,
ADXL345_ODR_25HZ,
@ -226,6 +229,7 @@ struct adxl345_dev_config {
enum adxl345_odr odr;
bool op_mode;
struct adxl345_fifo_config fifo_config;
uint8_t bus_type;
#ifdef CONFIG_ADXL345_TRIGGER
struct gpio_dt_spec interrupt;
#endif

View file

@ -216,6 +216,9 @@ static void adxl345_process_fifo_samples_cb(struct rtio *r, const struct rtio_sq
read_buf + data->fifo_total_bytes,
SAMPLE_SIZE, current_sqe);
data->fifo_total_bytes += SAMPLE_SIZE;
if (cfg->bus_type == ADXL345_BUS_I2C) {
read_fifo_data->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
}
if (i == fifo_samples-1) {
struct rtio_sqe *complete_op = rtio_sqe_acquire(data->rtio_ctx);
@ -342,6 +345,9 @@ static void adxl345_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq
rtio_sqe_prep_read(read_fifo_data, data->iodev, RTIO_PRIO_NORM, data->fifo_ent, 1,
current_sqe);
read_fifo_data->flags = RTIO_SQE_CHAINED;
if (cfg->bus_type == ADXL345_BUS_I2C) {
read_fifo_data->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
}
rtio_sqe_prep_callback(complete_op, adxl345_process_fifo_samples_cb, (void *)dev,
current_sqe);
@ -351,6 +357,7 @@ static void adxl345_process_status1_cb(struct rtio *r, const struct rtio_sqe *sq
void adxl345_stream_irq_handler(const struct device *dev)
{
struct adxl345_dev_data *data = (struct adxl345_dev_data *) dev->data;
const struct adxl345_dev_config *cfg = (const struct adxl345_dev_config *) dev->config;
if (data->sqe == NULL) {
return;
@ -366,6 +373,9 @@ void adxl345_stream_irq_handler(const struct device *dev)
rtio_sqe_prep_read(read_status_reg, data->iodev, RTIO_PRIO_NORM, &data->status1, 1, NULL);
read_status_reg->flags = RTIO_SQE_CHAINED;
if (cfg->bus_type == ADXL345_BUS_I2C) {
read_status_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
}
rtio_sqe_prep_callback(check_status_reg, adxl345_process_status1_cb, (void *)dev, NULL);
rtio_submit(data->rtio_ctx, 0);
}

View file

@ -5,4 +5,4 @@ description: ADXL345 3-axis I2C accelerometer
compatible: "adi,adxl345"
include: [sensor-device.yaml, i2c-device.yaml]
include: ["i2c-device.yaml", "adi,adxl345-common.yaml"]