diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index b6c37f455dc..07d0975f333 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -32,6 +32,7 @@ struct i2c_nrfx_twim_data { struct k_sem transfer_sync; struct k_sem completion_sync; volatile nrfx_err_t res; + uint8_t *buf_ptr; }; int i2c_nrfx_twim_exclusive_access_acquire(const struct device *dev, k_timeout_t timeout) @@ -69,6 +70,7 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, uint16_t msg_buf_size = dev_config->msg_buf_size; uint8_t *buf; uint16_t buf_len; + uint8_t *dma_buf; (void)i2c_nrfx_twim_exclusive_access_acquire(dev, K_FOREVER); @@ -133,6 +135,23 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, buf = msg_buf; buf_len = msg_buf_used; } + + if (msgs[i].flags & I2C_MSG_READ) { + ret = dmm_buffer_in_prepare(dev_config->mem_reg, buf, buf_len, + (void **)&dma_buf); + } else { + ret = dmm_buffer_out_prepare(dev_config->mem_reg, buf, buf_len, + (void **)&dma_buf); + } + + if (ret < 0) { + LOG_ERR("Failed to prepare buffer: %d", ret); + return ret; + } + + dev_data->buf_ptr = buf; + buf = dma_buf; + ret = i2c_nrfx_twim_msg_transfer(dev, msgs[i].flags, buf, buf_len, addr); if (ret < 0) { break; @@ -198,6 +217,23 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *p_context) switch (p_event->type) { case NRFX_TWIM_EVT_DONE: + const struct i2c_nrfx_twim_common_config *config = dev->config; + int ret = 0; + + if (p_event->xfer_desc.type == NRFX_TWIM_XFER_TX) { + ret = dmm_buffer_out_release(config->mem_reg, + (void **)&p_event->xfer_desc.p_primary_buf); + } else { + ret = dmm_buffer_in_release(config->mem_reg, dev_data->buf_ptr, + p_event->xfer_desc.primary_length, + p_event->xfer_desc.p_primary_buf); + } + + if (ret < 0) { + dev_data->res = NRFX_ERROR_INTERNAL; + break; + } + dev_data->res = NRFX_SUCCESS; break; case NRFX_TWIM_EVT_ADDRESS_NACK: @@ -282,6 +318,7 @@ static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { (.msg_buf = twim_##idx##_msg_buf,)) \ .max_transfer_size = BIT_MASK( \ DT_PROP(I2C(idx), easydma_maxcnt_bits)), \ + .mem_reg = DMM_DEV_TO_REG(I2C(idx)), \ }; \ PM_DEVICE_DT_DEFINE(I2C(idx), twim_nrfx_pm_action, \ PM_DEVICE_ISR_SAFE); \ @@ -301,78 +338,7 @@ static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { DT_PHANDLE(I2C(idx), memory_regions)))))), \ ()) -#ifdef CONFIG_HAS_HW_NRF_TWIM0 -I2C_NRFX_TWIM_DEVICE(0); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM1 -I2C_NRFX_TWIM_DEVICE(1); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM2 -I2C_NRFX_TWIM_DEVICE(2); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM3 -I2C_NRFX_TWIM_DEVICE(3); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM20 -I2C_NRFX_TWIM_DEVICE(20); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM21 -I2C_NRFX_TWIM_DEVICE(21); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM22 -I2C_NRFX_TWIM_DEVICE(22); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM23 -I2C_NRFX_TWIM_DEVICE(23); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM24 -I2C_NRFX_TWIM_DEVICE(24); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM30 -I2C_NRFX_TWIM_DEVICE(30); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM120 -I2C_NRFX_TWIM_DEVICE(120); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM130 -I2C_NRFX_TWIM_DEVICE(130); -#endif +#define COND_I2C_NRF_TWIM_DEVICE(unused, prefix, i, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_TWIM##prefix##i, (I2C_NRFX_TWIM_DEVICE(prefix##i);)) -#ifdef CONFIG_HAS_HW_NRF_TWIM131 -I2C_NRFX_TWIM_DEVICE(131); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM132 -I2C_NRFX_TWIM_DEVICE(132); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM133 -I2C_NRFX_TWIM_DEVICE(133); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM134 -I2C_NRFX_TWIM_DEVICE(134); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM135 -I2C_NRFX_TWIM_DEVICE(135); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM136 -I2C_NRFX_TWIM_DEVICE(136); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM137 -I2C_NRFX_TWIM_DEVICE(137); -#endif +NRFX_FOREACH_PRESENT(TWIM, COND_I2C_NRF_TWIM_DEVICE, (), ()) diff --git a/drivers/i2c/i2c_nrfx_twim_common.h b/drivers/i2c/i2c_nrfx_twim_common.h index 3c5c82311ba..7d24739e83e 100644 --- a/drivers/i2c/i2c_nrfx_twim_common.h +++ b/drivers/i2c/i2c_nrfx_twim_common.h @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -40,6 +41,7 @@ struct i2c_nrfx_twim_common_config { const struct pinctrl_dev_config *pcfg; uint8_t *msg_buf; uint16_t max_transfer_size; + void *mem_reg; }; int i2c_nrfx_twim_common_init(const struct device *dev); diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index 5eef549ba2e..09df4896a62 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -29,14 +29,33 @@ struct i2c_nrfx_twim_rtio_config { struct i2c_nrfx_twim_rtio_data { uint8_t *user_rx_buf; uint16_t user_rx_buf_size; + uint8_t *buf_ptr; }; 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) { 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; int ret = 0; + uint8_t *dma_buf; + + if (flags & I2C_MSG_READ) { + ret = dmm_buffer_in_prepare(config->common.mem_reg, buf, buf_len, + (void **)&dma_buf); + } else { + ret = dmm_buffer_out_prepare(config->common.mem_reg, buf, buf_len, + (void **)&dma_buf); + } + + if (ret < 0) { + LOG_ERR("Failed to prepare buffer: %d", ret); + return false; + } + + data->buf_ptr = buf; + buf = dma_buf; ret = i2c_nrfx_twim_msg_transfer(dev, flags, buf, buf_len, i2c_addr); if (ret != 0) { @@ -188,6 +207,21 @@ static void event_handler(nrfx_twim_evt_t const *p_event, void *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; + int ret = 0; + + if (p_event->xfer_desc.type == NRFX_TWIM_XFER_TX) { + ret = dmm_buffer_out_release(config->common.mem_reg, + (void **)&p_event->xfer_desc.p_primary_buf); + } else { + ret = dmm_buffer_in_release(config->common.mem_reg, data->buf_ptr, + p_event->xfer_desc.primary_length, + p_event->xfer_desc.p_primary_buf); + } + + if (ret < 0) { + i2c_nrfx_twim_rtio_complete(dev, ret); + return; + } if (data->user_rx_buf) { memcpy(data->user_rx_buf, config->common.msg_buf, data->user_rx_buf_size); @@ -283,6 +317,7 @@ static int i2c_nrfx_twim_rtio_deinit(const struct device *dev) .pcfg = PINCTRL_DT_DEV_CONFIG_GET(I2C(idx)), \ IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = MSG_BUF_SYM(idx),)) \ .max_transfer_size = MAX_TRANSFER_SIZE(idx), \ + .mem_reg = DMM_DEV_TO_REG(I2C(idx)), \ }, \ .ctx = &_i2c##idx##_twim_rtio, \ }; \ @@ -292,78 +327,7 @@ static int i2c_nrfx_twim_rtio_deinit(const struct device *dev) &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); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM1 -I2C_NRFX_TWIM_RTIO_DEVICE(1); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM2 -I2C_NRFX_TWIM_RTIO_DEVICE(2); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM3 -I2C_NRFX_TWIM_RTIO_DEVICE(3); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM20 -I2C_NRFX_TWIM_RTIO_DEVICE(20); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM21 -I2C_NRFX_TWIM_RTIO_DEVICE(21); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM22 -I2C_NRFX_TWIM_RTIO_DEVICE(22); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM23 -I2C_NRFX_TWIM_RTIO_DEVICE(23); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM24 -I2C_NRFX_TWIM_RTIO_DEVICE(24); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM30 -I2C_NRFX_TWIM_RTIO_DEVICE(30); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM120 -I2C_NRFX_TWIM_RTIO_DEVICE(120); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM130 -I2C_NRFX_TWIM_RTIO_DEVICE(130); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM131 -I2C_NRFX_TWIM_RTIO_DEVICE(131); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM132 -I2C_NRFX_TWIM_RTIO_DEVICE(132); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM133 -I2C_NRFX_TWIM_RTIO_DEVICE(133); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM134 -I2C_NRFX_TWIM_RTIO_DEVICE(134); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM135 -I2C_NRFX_TWIM_RTIO_DEVICE(135); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIM136 -I2C_NRFX_TWIM_RTIO_DEVICE(136); -#endif +#define COND_I2C_NRF_TWIM_RTIO_DEVICE(unused, prefix, i, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_TWIM##prefix##i, (I2C_NRFX_TWIM_RTIO_DEVICE(prefix##i);)) -#ifdef CONFIG_HAS_HW_NRF_TWIM137 -I2C_NRFX_TWIM_RTIO_DEVICE(137); -#endif +NRFX_FOREACH_PRESENT(TWIM, COND_I2C_NRF_TWIM_RTIO_DEVICE, (), ()) diff --git a/drivers/i2c/i2c_nrfx_twis.c b/drivers/i2c/i2c_nrfx_twis.c index dca3a457cf2..bb3f36803ae 100644 --- a/drivers/i2c/i2c_nrfx_twis.c +++ b/drivers/i2c/i2c_nrfx_twis.c @@ -373,70 +373,7 @@ static int shim_nrf_twis_deinit(const struct device *dev) &shim_nrf_twis_api \ ); -#ifdef CONFIG_HAS_HW_NRF_TWIS0 -SHIM_NRF_TWIS_DEVICE_DEFINE(0); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS1 -SHIM_NRF_TWIS_DEVICE_DEFINE(1); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS2 -SHIM_NRF_TWIS_DEVICE_DEFINE(2); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS3 -SHIM_NRF_TWIS_DEVICE_DEFINE(3); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS20 -SHIM_NRF_TWIS_DEVICE_DEFINE(20); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS21 -SHIM_NRF_TWIS_DEVICE_DEFINE(21); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS22 -SHIM_NRF_TWIS_DEVICE_DEFINE(22); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS23 -SHIM_NRF_TWIS_DEVICE_DEFINE(23); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS24 -SHIM_NRF_TWIS_DEVICE_DEFINE(24); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS30 -SHIM_NRF_TWIS_DEVICE_DEFINE(30); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS130 -SHIM_NRF_TWIS_DEVICE_DEFINE(130); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS131 -SHIM_NRF_TWIS_DEVICE_DEFINE(131); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS133 -SHIM_NRF_TWIS_DEVICE_DEFINE(133); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS134 -SHIM_NRF_TWIS_DEVICE_DEFINE(134); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS135 -SHIM_NRF_TWIS_DEVICE_DEFINE(135); -#endif - -#ifdef CONFIG_HAS_HW_NRF_TWIS136 -SHIM_NRF_TWIS_DEVICE_DEFINE(136); -#endif +#define COND_SHIM_NRF_TWIS_DEVICE(unused, prefix, i, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_TWIS##prefix##i, (SHIM_NRF_TWIS_DEVICE_DEFINE(prefix##i);)) -#ifdef CONFIG_HAS_HW_NRF_TWIS137 -SHIM_NRF_TWIS_DEVICE_DEFINE(137); -#endif +NRFX_FOREACH_PRESENT(TWIS, COND_SHIM_NRF_TWIS_DEVICE, (), ())