From 125752e7cccb4d6dd2f5f4124d7ef3b1cda360b4 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 11 Feb 2025 10:37:35 +0100 Subject: [PATCH] drivers: i2c: nrfx_twim_rtio: use msg_buf for rx if required The DMA buffer needs to be used both for tx and rx if required. Extend RTIO driver variant to use DMA buffer and copy received data from it to user buffer. Signed-off-by: Bjarki Arge Andreasen --- drivers/i2c/i2c_nrfx_twim_rtio.c | 34 +++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index 7d1ef250e98..8b5f2c625f8 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -26,6 +26,11 @@ struct i2c_nrfx_twim_rtio_config { struct i2c_rtio *ctx; }; +struct i2c_nrfx_twim_rtio_data { + uint8_t *user_rx_buf; + uint16_t user_rx_buf_size; +}; + static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags, uint8_t *buf, size_t buf_len, uint16_t i2c_addr) { @@ -44,12 +49,28 @@ static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags static bool i2c_nrfx_twim_rtio_start(const struct device *dev) { const struct i2c_nrfx_twim_rtio_config *config = dev->config; + struct i2c_nrfx_twim_rtio_data *data = dev->data; struct i2c_rtio *ctx = config->ctx; struct rtio_sqe *sqe = &ctx->txn_curr->sqe; struct i2c_dt_spec *dt_spec = sqe->iodev->data; switch (sqe->op) { case RTIO_OP_RX: + if (!nrf_dma_accessible_check(&config->common.twim, sqe->rx.buf)) { + if (sqe->rx.buf_len > config->common.msg_buf_size) { + return i2c_rtio_complete(ctx, -ENOSPC); + } + + data->user_rx_buf = sqe->rx.buf; + data->user_rx_buf_size = sqe->rx.buf_len; + return i2c_nrfx_twim_rtio_msg_start(dev, + I2C_MSG_READ | sqe->iodev_flags, + config->common.msg_buf, + data->user_rx_buf_size, + dt_spec->addr); + } + + data->user_rx_buf = NULL; return i2c_nrfx_twim_rtio_msg_start(dev, I2C_MSG_READ | sqe->iodev_flags, sqe->rx.buf, sqe->rx.buf_len, dt_spec->addr); case RTIO_OP_TINY_TX: @@ -145,8 +166,14 @@ static void i2c_nrfx_twim_rtio_submit(const struct device *dev, struct rtio_iode static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context) { const struct device *dev = p_context; + const struct i2c_nrfx_twim_rtio_config *config = dev->config; + struct i2c_nrfx_twim_rtio_data *data = dev->data; int status = p_event->type == NRFX_TWIM_EVT_DONE ? 0 : -EIO; + if (data->user_rx_buf) { + memcpy(data->user_rx_buf, config->common.msg_buf, data->user_rx_buf_size); + } + i2c_nrfx_twim_rtio_complete(dev, status); } @@ -215,6 +242,7 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev) DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ PINCTRL_DT_DEFINE(I2C(idx)); \ + static struct i2c_nrfx_twim_rtio_data twim_##idx##z_data; \ static const struct i2c_nrfx_twim_rtio_config twim_##idx##z_config = { \ .common = \ { \ @@ -235,9 +263,9 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev) .ctx = &_i2c##idx##_twim_rtio, \ }; \ PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \ - I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), NULL, \ - &twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ - &i2c_nrfx_twim_driver_api); + I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), \ + &twim_##idx##z_data, &twim_##idx##z_config, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api); #ifdef CONFIG_HAS_HW_NRF_TWIM0 I2C_NRFX_TWIM_RTIO_DEVICE(0);