rtio: add helper function rtio_read_transaction()
Add a helper function that constructs a rtio SQE chain with the purpose
to perform a bus read operation on a list of registers.
Usage:
struct rtio_regs regs;
struct rtio_reg_list regs_list[] = {{regs_addr1, mem_addr_1, mem_len_1},
{regs_addr2, mem_addr_2, mem_len_2},
...
};
regs.rtio_regs_list = regs_list;
regs.rtio_regs_num = ARRAY_SIZE(regs_list);
rtio_read_regs_async(rtio,
iodev,
RTIO_BUS_SPI,
®s,
sqe,
dev,
op_cb);
Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
37d8ec295b
commit
792b7e3570
@ -48,6 +48,13 @@ https://docs.zephyrproject.org/latest/security/vulnerabilities.html
|
|||||||
API Changes
|
API Changes
|
||||||
***********
|
***********
|
||||||
|
|
||||||
|
* RTIO
|
||||||
|
|
||||||
|
* :c:func:`rtio_is_spi`
|
||||||
|
* :c:func:`rtio_is_cspi`
|
||||||
|
* :c:func:`rtio_is_i3c`
|
||||||
|
* :c:func:`rtio_read_regs_async`
|
||||||
|
|
||||||
Removed APIs and options
|
Removed APIs and options
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
|||||||
@ -1331,7 +1331,7 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action
|
|||||||
CONFIG_SPI_RTIO), \
|
CONFIG_SPI_RTIO), \
|
||||||
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
||||||
.iodev = &prefix##_iodev_##inst, \
|
.iodev = &prefix##_iodev_##inst, \
|
||||||
.bus_type = BUS_SPI,)) \
|
.bus_type = RTIO_BUS_SPI,)) \
|
||||||
}; \
|
}; \
|
||||||
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
||||||
LSM6DSV16X_CONFIG_SPI(inst, prefix);
|
LSM6DSV16X_CONFIG_SPI(inst, prefix);
|
||||||
@ -1362,7 +1362,7 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action
|
|||||||
CONFIG_I2C_RTIO), \
|
CONFIG_I2C_RTIO), \
|
||||||
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
||||||
.iodev = &prefix##_iodev_##inst, \
|
.iodev = &prefix##_iodev_##inst, \
|
||||||
.bus_type = BUS_I2C,)) \
|
.bus_type = RTIO_BUS_I2C,)) \
|
||||||
}; \
|
}; \
|
||||||
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
||||||
LSM6DSV16X_CONFIG_I2C(inst, prefix);
|
LSM6DSV16X_CONFIG_I2C(inst, prefix);
|
||||||
@ -1398,7 +1398,7 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action
|
|||||||
CONFIG_I3C_RTIO), \
|
CONFIG_I3C_RTIO), \
|
||||||
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
(.rtio_ctx = &prefix##_rtio_ctx_##inst, \
|
||||||
.iodev = &prefix##_i3c_iodev_##inst, \
|
.iodev = &prefix##_i3c_iodev_##inst, \
|
||||||
.bus_type = BUS_I3C,)) \
|
.bus_type = RTIO_BUS_I3C,)) \
|
||||||
}; \
|
}; \
|
||||||
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
static const struct lsm6dsv16x_config prefix##_config_##inst = \
|
||||||
LSM6DSV16X_CONFIG_I3C(inst, prefix);
|
LSM6DSV16X_CONFIG_I3C(inst, prefix);
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
#include <stmemsc.h>
|
#include <stmemsc.h>
|
||||||
#include "lsm6dsv16x_reg.h"
|
#include "lsm6dsv16x_reg.h"
|
||||||
|
#include <zephyr/rtio/regmap.h>
|
||||||
|
|
||||||
#define DT_DRV_COMPAT_LSM6DSV16X st_lsm6dsv16x
|
#define DT_DRV_COMPAT_LSM6DSV16X st_lsm6dsv16x
|
||||||
#define DT_DRV_COMPAT_LSM6DSV32X st_lsm6dsv32x
|
#define DT_DRV_COMPAT_LSM6DSV32X st_lsm6dsv32x
|
||||||
@ -171,9 +172,9 @@ struct lsm6dsv16x_data {
|
|||||||
uint16_t accel_batch_odr : 4;
|
uint16_t accel_batch_odr : 4;
|
||||||
uint16_t gyro_batch_odr : 4;
|
uint16_t gyro_batch_odr : 4;
|
||||||
uint16_t temp_batch_odr : 2;
|
uint16_t temp_batch_odr : 2;
|
||||||
uint16_t bus_type : 2; /* I2C is 0, SPI is 1, I3C is 2 */
|
|
||||||
uint16_t sflp_batch_odr : 3;
|
uint16_t sflp_batch_odr : 3;
|
||||||
uint16_t reserved : 1;
|
uint16_t reserved : 3;
|
||||||
|
rtio_bus_type bus_type;
|
||||||
int32_t gbias_x_udps;
|
int32_t gbias_x_udps;
|
||||||
int32_t gbias_y_udps;
|
int32_t gbias_y_udps;
|
||||||
int32_t gbias_z_udps;
|
int32_t gbias_z_udps;
|
||||||
@ -206,13 +207,9 @@ struct lsm6dsv16x_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_LSM6DSV16X_STREAM
|
#ifdef CONFIG_LSM6DSV16X_STREAM
|
||||||
#define BUS_I2C 0
|
static inline uint8_t lsm6dsv16x_bus_reg(rtio_bus_type bus, uint8_t addr)
|
||||||
#define BUS_SPI 1
|
|
||||||
#define BUS_I3C 2
|
|
||||||
|
|
||||||
static inline uint8_t lsm6dsv16x_bus_reg(struct lsm6dsv16x_data *data, uint8_t x)
|
|
||||||
{
|
{
|
||||||
return (data->bus_type == BUS_SPI) ? x | 0x80 : x;
|
return (rtio_is_spi(bus)) ? addr | 0x80 : addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LSM6DSV16X_FIFO_ITEM_LEN 7
|
#define LSM6DSV16X_FIFO_ITEM_LEN 7
|
||||||
|
|||||||
@ -16,48 +16,6 @@
|
|||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_DECLARE(LSM6DSV16X_RTIO);
|
LOG_MODULE_DECLARE(LSM6DSV16X_RTIO);
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a chain of SQEs representing a bus transaction to read a reg.
|
|
||||||
* The RTIO-enabled bus driver will:
|
|
||||||
*
|
|
||||||
* - write "reg" address
|
|
||||||
* - read "len" data bytes into "buf".
|
|
||||||
* - call complete_op callback
|
|
||||||
*
|
|
||||||
* If drdy_xl is active it reads XL data (6 bytes) from LSM6DSV16X_OUTX_L_A reg.
|
|
||||||
*/
|
|
||||||
static void lsm6dsv16x_rtio_rw_transaction(const struct device *dev, uint8_t reg,
|
|
||||||
uint8_t *buf, uint32_t len,
|
|
||||||
rtio_callback_t complete_op_cb)
|
|
||||||
{
|
|
||||||
struct lsm6dsv16x_data *lsm6dsv16x = dev->data;
|
|
||||||
struct rtio *rtio = lsm6dsv16x->rtio_ctx;
|
|
||||||
struct rtio_iodev *iodev = lsm6dsv16x->iodev;
|
|
||||||
struct rtio_sqe *write_addr = rtio_sqe_acquire(rtio);
|
|
||||||
struct rtio_sqe *read_reg = rtio_sqe_acquire(rtio);
|
|
||||||
struct rtio_sqe *complete_op = rtio_sqe_acquire(rtio);
|
|
||||||
struct rtio_iodev_sqe *sqe = lsm6dsv16x->streaming_sqe;
|
|
||||||
uint8_t reg_bus = lsm6dsv16x_bus_reg(lsm6dsv16x, reg);
|
|
||||||
|
|
||||||
/* check we have been able to acquire sqe */
|
|
||||||
if (write_addr == NULL || read_reg == NULL || complete_op == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtio_sqe_prep_tiny_write(write_addr, iodev, RTIO_PRIO_NORM, ®_bus, 1, NULL);
|
|
||||||
write_addr->flags = RTIO_SQE_TRANSACTION;
|
|
||||||
rtio_sqe_prep_read(read_reg, iodev, RTIO_PRIO_NORM, buf, len, NULL);
|
|
||||||
read_reg->flags = RTIO_SQE_CHAINED;
|
|
||||||
if (lsm6dsv16x->bus_type == BUS_I2C) {
|
|
||||||
read_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
|
||||||
} else if (lsm6dsv16x->bus_type == BUS_I3C) {
|
|
||||||
read_reg->iodev_flags |= RTIO_IODEV_I3C_STOP | RTIO_IODEV_I3C_RESTART;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtio_sqe_prep_callback_no_cqe(complete_op, complete_op_cb, (void *)dev, sqe);
|
|
||||||
rtio_submit(rtio, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lsm6dsv16x_config_drdy(const struct device *dev, struct trigger_config trig_cfg)
|
static void lsm6dsv16x_config_drdy(const struct device *dev, struct trigger_config trig_cfg)
|
||||||
{
|
{
|
||||||
const struct lsm6dsv16x_config *config = dev->config;
|
const struct lsm6dsv16x_config *config = dev->config;
|
||||||
@ -500,6 +458,19 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe,
|
|||||||
read_buf = buf + sizeof(hdr);
|
read_buf = buf + sizeof(hdr);
|
||||||
buf_avail = buf_len - sizeof(hdr);
|
buf_avail = buf_len - sizeof(hdr);
|
||||||
|
|
||||||
|
uint8_t reg_addr = lsm6dsv16x_bus_reg(lsm6dsv16x->bus_type, LSM6DSV16X_FIFO_DATA_OUT_TAG);
|
||||||
|
struct rtio_regs fifo_regs;
|
||||||
|
struct rtio_regs_list regs_list[] = {
|
||||||
|
{
|
||||||
|
reg_addr,
|
||||||
|
read_buf,
|
||||||
|
buf_avail,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fifo_regs.rtio_regs_list = regs_list;
|
||||||
|
fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare rtio enabled bus to read all fifo_count entries from
|
* Prepare rtio enabled bus to read all fifo_count entries from
|
||||||
* LSM6DSV16X_FIFO_DATA_OUT_TAG. Then lsm6dsv16x_complete_op_cb
|
* LSM6DSV16X_FIFO_DATA_OUT_TAG. Then lsm6dsv16x_complete_op_cb
|
||||||
@ -515,8 +486,8 @@ static void lsm6dsv16x_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe,
|
|||||||
* lsm6dsv16x_fifo_out_raw_get(&dev_ctx, &f_data);
|
* lsm6dsv16x_fifo_out_raw_get(&dev_ctx, &f_data);
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
lsm6dsv16x_rtio_rw_transaction(dev, LSM6DSV16X_FIFO_DATA_OUT_TAG,
|
rtio_read_regs_async(lsm6dsv16x->rtio_ctx, lsm6dsv16x->iodev, lsm6dsv16x->bus_type,
|
||||||
read_buf, buf_avail, lsm6dsv16x_complete_op_cb);
|
&fifo_regs, lsm6dsv16x->streaming_sqe, dev, lsm6dsv16x_complete_op_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -646,6 +617,19 @@ static void lsm6dsv16x_read_status_cb(struct rtio *r, const struct rtio_sqe *sqe
|
|||||||
memcpy(buf, &hdr, sizeof(hdr));
|
memcpy(buf, &hdr, sizeof(hdr));
|
||||||
read_buf = (uint8_t *)&((struct lsm6dsv16x_rtio_data *)buf)->acc[0];
|
read_buf = (uint8_t *)&((struct lsm6dsv16x_rtio_data *)buf)->acc[0];
|
||||||
|
|
||||||
|
uint8_t reg_addr = lsm6dsv16x_bus_reg(lsm6dsv16x->bus_type, LSM6DSV16X_OUTX_L_A);
|
||||||
|
struct rtio_regs fifo_regs;
|
||||||
|
struct rtio_regs_list regs_list[] = {
|
||||||
|
{
|
||||||
|
reg_addr,
|
||||||
|
read_buf,
|
||||||
|
6,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fifo_regs.rtio_regs_list = regs_list;
|
||||||
|
fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare rtio enabled bus to read LSM6DSV16X_OUTX_L_A register
|
* Prepare rtio enabled bus to read LSM6DSV16X_OUTX_L_A register
|
||||||
* where accelerometer data is available.
|
* where accelerometer data is available.
|
||||||
@ -657,8 +641,9 @@ static void lsm6dsv16x_read_status_cb(struct rtio *r, const struct rtio_sqe *sqe
|
|||||||
*
|
*
|
||||||
* lsm6dsv16x_acceleration_raw_get(&dev_ctx, accel_raw);
|
* lsm6dsv16x_acceleration_raw_get(&dev_ctx, accel_raw);
|
||||||
*/
|
*/
|
||||||
lsm6dsv16x_rtio_rw_transaction(dev, LSM6DSV16X_OUTX_L_A,
|
rtio_read_regs_async(lsm6dsv16x->rtio_ctx, lsm6dsv16x->iodev, lsm6dsv16x->bus_type,
|
||||||
read_buf, 6, lsm6dsv16x_complete_op_cb);
|
&fifo_regs, lsm6dsv16x->streaming_sqe, dev,
|
||||||
|
lsm6dsv16x_complete_op_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,12 +693,26 @@ void lsm6dsv16x_stream_irq_handler(const struct device *dev)
|
|||||||
struct rtio_sqe *check_fifo_status_reg = rtio_sqe_acquire(rtio);
|
struct rtio_sqe *check_fifo_status_reg = rtio_sqe_acquire(rtio);
|
||||||
|
|
||||||
rtio_sqe_prep_callback_no_cqe(check_fifo_status_reg,
|
rtio_sqe_prep_callback_no_cqe(check_fifo_status_reg,
|
||||||
lsm6dsv16x_read_fifo_cb, (void *)dev, NULL);
|
lsm6dsv16x_read_fifo_cb, (void *)dev, NULL);
|
||||||
rtio_submit(rtio, 0);
|
rtio_submit(rtio, 0);
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
lsm6dsv16x->fifo_status[0] = lsm6dsv16x->fifo_status[1] = 0;
|
lsm6dsv16x->fifo_status[0] = lsm6dsv16x->fifo_status[1] = 0;
|
||||||
|
|
||||||
|
uint8_t reg_addr =
|
||||||
|
lsm6dsv16x_bus_reg(lsm6dsv16x->bus_type, LSM6DSV16X_FIFO_STATUS1);
|
||||||
|
struct rtio_regs fifo_regs;
|
||||||
|
struct rtio_regs_list regs_list[] = {
|
||||||
|
{
|
||||||
|
reg_addr,
|
||||||
|
lsm6dsv16x->fifo_status,
|
||||||
|
2,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fifo_regs.rtio_regs_list = regs_list;
|
||||||
|
fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare rtio enabled bus to read LSM6DSV16X_FIFO_STATUS1 and
|
* Prepare rtio enabled bus to read LSM6DSV16X_FIFO_STATUS1 and
|
||||||
* LSM6DSV16X_FIFO_STATUS2 registers where FIFO threshold condition and
|
* LSM6DSV16X_FIFO_STATUS2 registers where FIFO threshold condition and
|
||||||
@ -726,8 +725,11 @@ void lsm6dsv16x_stream_irq_handler(const struct device *dev)
|
|||||||
*
|
*
|
||||||
* lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status);
|
* lsm6dsv16x_fifo_status_get(&dev_ctx, &fifo_status);
|
||||||
*/
|
*/
|
||||||
lsm6dsv16x_rtio_rw_transaction(dev, LSM6DSV16X_FIFO_STATUS1,
|
rtio_read_regs_async(lsm6dsv16x->rtio_ctx, lsm6dsv16x->iodev,
|
||||||
lsm6dsv16x->fifo_status, 2, lsm6dsv16x_read_fifo_cb);
|
lsm6dsv16x->bus_type, &fifo_regs,
|
||||||
|
lsm6dsv16x->streaming_sqe, dev,
|
||||||
|
lsm6dsv16x_read_fifo_cb);
|
||||||
|
|
||||||
#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
|
#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -737,6 +739,19 @@ void lsm6dsv16x_stream_irq_handler(const struct device *dev)
|
|||||||
if (lsm6dsv16x->trig_cfg.int_drdy) {
|
if (lsm6dsv16x->trig_cfg.int_drdy) {
|
||||||
lsm6dsv16x->status = 0;
|
lsm6dsv16x->status = 0;
|
||||||
|
|
||||||
|
uint8_t reg_addr = lsm6dsv16x_bus_reg(lsm6dsv16x->bus_type, LSM6DSV16X_STATUS_REG);
|
||||||
|
struct rtio_regs fifo_regs;
|
||||||
|
struct rtio_regs_list regs_list[] = {
|
||||||
|
{
|
||||||
|
reg_addr,
|
||||||
|
&lsm6dsv16x->status,
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fifo_regs.rtio_regs_list = regs_list;
|
||||||
|
fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare rtio enabled bus to read LSM6DSV16X_STATUS_REG register
|
* Prepare rtio enabled bus to read LSM6DSV16X_STATUS_REG register
|
||||||
* where accelerometer and gyroscope data ready status is available.
|
* where accelerometer and gyroscope data ready status is available.
|
||||||
@ -748,7 +763,8 @@ void lsm6dsv16x_stream_irq_handler(const struct device *dev)
|
|||||||
*
|
*
|
||||||
* lsm6dsv16x_flag_data_ready_get(&dev_ctx, &drdy);
|
* lsm6dsv16x_flag_data_ready_get(&dev_ctx, &drdy);
|
||||||
*/
|
*/
|
||||||
lsm6dsv16x_rtio_rw_transaction(dev, LSM6DSV16X_STATUS_REG,
|
rtio_read_regs_async(lsm6dsv16x->rtio_ctx, lsm6dsv16x->iodev, lsm6dsv16x->bus_type,
|
||||||
&lsm6dsv16x->status, 1, lsm6dsv16x_read_status_cb);
|
&fifo_regs, lsm6dsv16x->streaming_sqe, dev,
|
||||||
|
lsm6dsv16x_read_status_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
169
include/zephyr/rtio/regmap.h
Normal file
169
include/zephyr/rtio/regmap.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_RTIO_REGMAP_H_
|
||||||
|
#define ZEPHYR_INCLUDE_RTIO_REGMAP_H_
|
||||||
|
|
||||||
|
#include <zephyr/rtio/rtio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A structure to describe a list of not-consecutive memory chunks
|
||||||
|
* for RTIO operations.
|
||||||
|
*/
|
||||||
|
struct rtio_regs {
|
||||||
|
/** Number of registers in the list **/
|
||||||
|
size_t rtio_regs_num;
|
||||||
|
|
||||||
|
struct rtio_regs_list {
|
||||||
|
/** Register address **/
|
||||||
|
uint8_t reg_addr;
|
||||||
|
|
||||||
|
/** Valid pointer to a data buffer **/
|
||||||
|
uint8_t *bufp;
|
||||||
|
|
||||||
|
/** Length of the buffer in bytes **/
|
||||||
|
size_t len;
|
||||||
|
} *rtio_regs_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief bus type
|
||||||
|
*
|
||||||
|
* RTIO works on top of a RTIO enabled bus, Some RTIO ops require
|
||||||
|
* a bus-related handling (e.g. rtio_read_regs_async)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
RTIO_BUS_I2C,
|
||||||
|
RTIO_BUS_SPI,
|
||||||
|
RTIO_BUS_I3C,
|
||||||
|
} rtio_bus_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if bus is SPI
|
||||||
|
* @param bus_type Type of bus (I2C, SPI, I3C)
|
||||||
|
* @return true if bus type is SPI
|
||||||
|
*/
|
||||||
|
static inline bool rtio_is_spi(rtio_bus_type bus_type)
|
||||||
|
{
|
||||||
|
return (bus_type == RTIO_BUS_SPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if bus is I2C
|
||||||
|
* @param bus_type Type of bus (I2C, SPI, I3C)
|
||||||
|
* @return true if bus type is I2C
|
||||||
|
*/
|
||||||
|
static inline bool rtio_is_i2c(rtio_bus_type bus_type)
|
||||||
|
{
|
||||||
|
return (bus_type == RTIO_BUS_I2C);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if bus is I3C
|
||||||
|
* @param bus_type Type of bus (I2C, SPI, I3C)
|
||||||
|
* @return true if bus type is I3C
|
||||||
|
*/
|
||||||
|
static inline bool rtio_is_i3c(rtio_bus_type bus_type)
|
||||||
|
{
|
||||||
|
return (bus_type == RTIO_BUS_I3C);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Create a chain of SQEs representing a bus transaction to read a reg.
|
||||||
|
*
|
||||||
|
* The RTIO-enabled bus driver is instrumented to perform bus read ops
|
||||||
|
* for each register in the list.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* @code{.c}
|
||||||
|
* struct rtio_regs regs;
|
||||||
|
* struct rtio_reg_list regs_list[] = {{regs_addr1, mem_addr_1, mem_len_1},
|
||||||
|
* {regs_addr2, mem_addr_2, mem_len_2},
|
||||||
|
* ...
|
||||||
|
* };
|
||||||
|
* regs.rtio_regs_list = regs_list;
|
||||||
|
* regs.rtio_regs_num = ARRAY_SIZE(regs_list);
|
||||||
|
*
|
||||||
|
* rtio_read_regs_async(rtio,
|
||||||
|
* iodev,
|
||||||
|
* RTIO_BUS_SPI,
|
||||||
|
* ®s,
|
||||||
|
* sqe,
|
||||||
|
* dev,
|
||||||
|
* op_cb);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param r RTIO context
|
||||||
|
* @param iodev IO device
|
||||||
|
* @param bus_type Type of bus (I2C, SPI, I3C)
|
||||||
|
* @param regs pointer to list of registers to be read. Raise proper bit in case of SPI bus
|
||||||
|
* @param iodev_sqe IODEV submission for the await op
|
||||||
|
* @param dev pointer to the device structure
|
||||||
|
* @param complete_op_cb callback routine at the end of op
|
||||||
|
*/
|
||||||
|
static inline void rtio_read_regs_async(struct rtio *r, struct rtio_iodev *iodev,
|
||||||
|
rtio_bus_type bus_type, struct rtio_regs *regs,
|
||||||
|
struct rtio_iodev_sqe *iodev_sqe, const struct device *dev,
|
||||||
|
rtio_callback_t complete_op_cb)
|
||||||
|
{
|
||||||
|
struct rtio_sqe *write_addr;
|
||||||
|
struct rtio_sqe *read_reg;
|
||||||
|
struct rtio_sqe *complete_op;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < regs->rtio_regs_num; i++) {
|
||||||
|
|
||||||
|
write_addr = rtio_sqe_acquire(r);
|
||||||
|
read_reg = rtio_sqe_acquire(r);
|
||||||
|
|
||||||
|
if (write_addr == NULL || read_reg == NULL) {
|
||||||
|
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
|
||||||
|
rtio_sqe_drop_all(r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtio_sqe_prep_tiny_write(write_addr, iodev, RTIO_PRIO_NORM,
|
||||||
|
®s->rtio_regs_list[i].reg_addr, 1, NULL);
|
||||||
|
write_addr->flags = RTIO_SQE_TRANSACTION;
|
||||||
|
|
||||||
|
rtio_sqe_prep_read(read_reg, iodev, RTIO_PRIO_NORM, regs->rtio_regs_list[i].bufp,
|
||||||
|
regs->rtio_regs_list[i].len, NULL);
|
||||||
|
read_reg->flags = RTIO_SQE_CHAINED;
|
||||||
|
|
||||||
|
switch (bus_type) {
|
||||||
|
case RTIO_BUS_I2C:
|
||||||
|
read_reg->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||||
|
break;
|
||||||
|
case RTIO_BUS_I3C:
|
||||||
|
read_reg->iodev_flags |= RTIO_IODEV_I3C_STOP | RTIO_IODEV_I3C_RESTART;
|
||||||
|
break;
|
||||||
|
case RTIO_BUS_SPI:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_op = rtio_sqe_acquire(r);
|
||||||
|
if (complete_op == NULL) {
|
||||||
|
rtio_iodev_sqe_err(iodev_sqe, -ENOMEM);
|
||||||
|
rtio_sqe_drop_all(r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtio_sqe_prep_callback_no_cqe(complete_op, complete_op_cb, (void *)dev, iodev_sqe);
|
||||||
|
|
||||||
|
rtio_submit(r, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_RTIO_REGMAP_H_ */
|
||||||
Loading…
Reference in New Issue
Block a user