From 5065edb417c4dc4a9642da2006d06fda192199a6 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 12 Jun 2025 14:23:03 +0200 Subject: [PATCH] drivers: i2c: stm32: support more than 256 bytes transfer for RTIO Add support for transfer of more than 256 byte in STM32 v1 and v2 RTIO drivers. Signed-off-by: Etienne Carriere --- drivers/i2c/i2c_ll_stm32.h | 4 ++-- drivers/i2c/i2c_ll_stm32_v1_rtio.c | 6 ----- drivers/i2c/i2c_ll_stm32_v2_rtio.c | 35 ++++++++++++++++++------------ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/i2c/i2c_ll_stm32.h b/drivers/i2c/i2c_ll_stm32.h index b3ca4a5e725..01f9115a5d2 100644 --- a/drivers/i2c/i2c_ll_stm32.h +++ b/drivers/i2c/i2c_ll_stm32.h @@ -73,10 +73,10 @@ struct i2c_stm32_data { struct i2c_rtio *ctx; uint32_t dev_config; uint8_t *xfer_buf; - uint8_t xfer_len; + size_t xfer_len; uint8_t xfer_flags; #ifdef CONFIG_I2C_STM32_V1 - uint8_t msg_len; + size_t msg_len; uint8_t is_restart; uint16_t slave_address; #endif /* CONFIG_I2C_STM32_V1 */ diff --git a/drivers/i2c/i2c_ll_stm32_v1_rtio.c b/drivers/i2c/i2c_ll_stm32_v1_rtio.c index 7e8ef89039a..3c0728d79d6 100644 --- a/drivers/i2c/i2c_ll_stm32_v1_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_v1_rtio.c @@ -333,12 +333,6 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags, data->is_restart = 0; data->slave_address = i2c_addr; - /* TODO deal with larger than 255 byte transfers correctly */ - if (buf_len > UINT8_MAX) { - /* TODO LL_I2C_EnableReloadMode(i2c); */ - return -EINVAL; - } - LL_I2C_Enable(i2c); LL_I2C_DisableBitPOS(i2c); diff --git a/drivers/i2c/i2c_ll_stm32_v2_rtio.c b/drivers/i2c/i2c_ll_stm32_v2_rtio.c index c0f5697f9c3..519066afad7 100644 --- a/drivers/i2c/i2c_ll_stm32_v2_rtio.c +++ b/drivers/i2c/i2c_ll_stm32_v2_rtio.c @@ -101,22 +101,29 @@ void i2c_stm32_event(const struct device *dev) LL_I2C_ClearFlag_STOP(i2c); LL_I2C_DisableReloadMode(i2c); i2c_stm32_master_mode_end(dev); + + if (i2c_rtio_complete(ctx, ret)) { + i2c_stm32_start(dev); + return; + } } - /* TODO handle the reload separately from complete */ - /* Transfer Complete or Transfer Complete Reload */ if (LL_I2C_IsActiveFlag_TC(i2c) || LL_I2C_IsActiveFlag_TCR(i2c)) { + /* Issue stop condition if necessary */ - /* TODO look at current sqe flags */ if ((data->xfer_flags & I2C_MSG_STOP) != 0) { - LL_I2C_GenerateStopCondition(i2c); + if (data->xfer_len == 0) { + LL_I2C_GenerateStopCondition(i2c); + } else { + LL_I2C_SetTransferSize(i2c, MIN(data->xfer_len, UINT8_MAX)); + } } else { i2c_stm32_disable_transfer_interrupts(dev); - } - if ((data->xfer_len == 0) && i2c_rtio_complete(ctx, ret)) { - i2c_stm32_start(dev); + if ((data->xfer_len == 0) && i2c_rtio_complete(ctx, ret)) { + i2c_stm32_start(dev); + } } } } @@ -162,12 +169,6 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags, transfer = LL_I2C_REQUEST_WRITE; } - /* TODO deal with larger than 255 byte transfers correctly */ - if (buf_len > UINT8_MAX) { - /* TODO LL_I2C_EnableReloadMode(i2c); */ - return -EINVAL; - } - if ((I2C_MSG_ADDR_10_BITS & flags) != 0) { LL_I2C_SetMasterAddressingMode(i2c, LL_I2C_ADDRESSING_MODE_10BIT); @@ -178,9 +179,15 @@ int i2c_stm32_msg_start(const struct device *dev, uint8_t flags, LL_I2C_SetSlaveAddr(i2c, (uint32_t) i2c_addr << 1); } + if (buf_len > UINT8_MAX) { + LL_I2C_EnableReloadMode(i2c); + } else { + LL_I2C_DisableReloadMode(i2c); + } + LL_I2C_DisableAutoEndMode(i2c); LL_I2C_SetTransferRequest(i2c, transfer); - LL_I2C_SetTransferSize(i2c, buf_len); + LL_I2C_SetTransferSize(i2c, MIN(buf_len, UINT8_MAX)); LL_I2C_Enable(i2c);