Skip to content

Commit 89542d1

Browse files
[nrf fromlist] 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. Upstream PR #: 85565 Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent 965e5b4 commit 89542d1

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

drivers/i2c/i2c_nrfx_twim_rtio.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct i2c_nrfx_twim_rtio_config {
2626
struct i2c_rtio *ctx;
2727
};
2828

29+
struct i2c_nrfx_twim_rtio_data {
30+
uint8_t *user_rx_buf;
31+
uint16_t user_rx_buf_size;
32+
};
33+
2934
static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags, uint8_t *buf,
3035
size_t buf_len, uint16_t i2c_addr)
3136
{
@@ -44,12 +49,28 @@ static bool i2c_nrfx_twim_rtio_msg_start(const struct device *dev, uint8_t flags
4449
static bool i2c_nrfx_twim_rtio_start(const struct device *dev)
4550
{
4651
const struct i2c_nrfx_twim_rtio_config *config = dev->config;
52+
struct i2c_nrfx_twim_rtio_data *data = dev->data;
4753
struct i2c_rtio *ctx = config->ctx;
4854
struct rtio_sqe *sqe = &ctx->txn_curr->sqe;
4955
struct i2c_dt_spec *dt_spec = sqe->iodev->data;
5056

5157
switch (sqe->op) {
5258
case RTIO_OP_RX:
59+
if (!nrf_dma_accessible_check(&config->common.twim, sqe->rx.buf)) {
60+
if (sqe->rx.buf_len > config->common.msg_buf_size) {
61+
return i2c_rtio_complete(ctx, -ENOSPC);
62+
}
63+
64+
data->user_rx_buf = sqe->rx.buf;
65+
data->user_rx_buf_size = sqe->rx.buf_len;
66+
return i2c_nrfx_twim_rtio_msg_start(dev,
67+
I2C_MSG_READ | sqe->iodev_flags,
68+
config->common.msg_buf,
69+
data->user_rx_buf_size,
70+
dt_spec->addr);
71+
}
72+
73+
data->user_rx_buf = NULL;
5374
return i2c_nrfx_twim_rtio_msg_start(dev, I2C_MSG_READ | sqe->iodev_flags,
5475
sqe->rx.buf, sqe->rx.buf_len, dt_spec->addr);
5576
case RTIO_OP_TINY_TX:
@@ -144,8 +165,14 @@ static void i2c_nrfx_twim_rtio_submit(const struct device *dev, struct rtio_iode
144165
static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context)
145166
{
146167
const struct device *dev = p_context;
168+
const struct i2c_nrfx_twim_rtio_config *config = dev->config;
169+
struct i2c_nrfx_twim_rtio_data *data = dev->data;
147170
int status = p_event->type == NRFX_TWIM_EVT_DONE ? 0 : -EIO;
148171

172+
if (data->user_rx_buf) {
173+
memcpy(data->user_rx_buf, config->common.msg_buf, data->user_rx_buf_size);
174+
}
175+
149176
i2c_nrfx_twim_rtio_complete(dev, status);
150177
}
151178

@@ -214,6 +241,7 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev)
214241
DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \
215242
DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \
216243
PINCTRL_DT_DEFINE(I2C(idx)); \
244+
static struct i2c_nrfx_twim_rtio_data twim_##idx##z_data; \
217245
static const struct i2c_nrfx_twim_rtio_config twim_##idx##z_config = { \
218246
.common = \
219247
{ \
@@ -234,9 +262,9 @@ int i2c_nrfx_twim_rtio_init(const struct device *dev)
234262
.ctx = &_i2c##idx##_twim_rtio, \
235263
}; \
236264
PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \
237-
I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), NULL, \
238-
&twim_##idx##z_config, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
239-
&i2c_nrfx_twim_driver_api);
265+
I2C_DEVICE_DT_DEFINE(I2C(idx), i2c_nrfx_twim_rtio_init, PM_DEVICE_DT_GET(I2C(idx)), \
266+
&twim_##idx##z_data, &twim_##idx##z_config, POST_KERNEL, \
267+
CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api);
240268

241269
#ifdef CONFIG_HAS_HW_NRF_TWIM0
242270
I2C_NRFX_TWIM_RTIO_DEVICE(0);

0 commit comments

Comments
 (0)