-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i2c: stm32: dma enhancement #81814
base: main
Are you sure you want to change the base?
i2c: stm32: dma enhancement #81814
Conversation
Hello @sgilbert182, and thank you very much for your first pull request to the Zephyr project! |
1adf73d
to
601d56f
Compare
@sgilbert182 Thanks for this contribution. We'll try to review in best delays. Meanwhile,please have a look at feedback reported by compliance scripts |
357f005
to
d465675
Compare
Hi, no worries. I tested this on a g4 |
@sgilbert182 Quick hint: |
d465675
to
57b1147
Compare
57b1147
to
057bc2b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initial review attempt:
Mains request before going further:
Did you consider implementing I2C_CALLBACK
which is supposed to be the async version of I2C API while you're at?
If adding DMA support it would be more logical to make use of this API which allows truly async transfers rather than adding DMA support on a blocking API.
Reason I ask is to avoid current state of STM32 SPI driver which is in a similar state today with a sync API allowing use of DMA and ASYNC API effectively blocking.
(Note also that driver is supposed to get further changes to support RTIO API, so let's limit the changes to where it makes real sense)
Then let's club all DMA related additions to the driver in a single commit to make it easier to review.
Finally, if possible, let's rebase on top of #82015 (once merged) in order to get rid of clang-format suggestions.
drivers/i2c/Kconfig.stm32
Outdated
config I2C_DMA | ||
bool "DMA support" | ||
depends on I2C_STM32_V2 | ||
help | ||
Enable DMA support for the STM32 I2C driver. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config I2C_DMA | |
bool "DMA support" | |
depends on I2C_STM32_V2 | |
help | |
Enable DMA support for the STM32 I2C driver. | |
config I2C_STM32_DMA | |
bool "STM32 I2C DMA support" | |
depends on I2C_STM32_V2 | |
select DMA | |
help | |
Enable DMA support for the STM32 I2C driver. | |
Limited to `st,stm32-i2c-v2` compatible SoCs for now. |
Optionally we should add select CACHE_MANAGEMENT if CPU_HAS_DCACHE
if tested on H7/F7.
Otherwise, let's specify it is not supported for now on those (depends on !DCACHE
and provide details in help
section)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
drivers/i2c/i2c_ll_stm32.c
Outdated
data->current.is_err = 0; | ||
dma_stop(dma_dev, channel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
drivers/i2c/i2c_ll_stm32.c
Outdated
switch (status) { | ||
case DMA_STATUS_COMPLETE: | ||
data->current.is_err = 0; | ||
dma_stop(dma_dev, channel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
drivers/i2c/i2c_ll_stm32.c
Outdated
uint8_t *next_msg_flags = NULL; | ||
|
||
if (num_msgs > 1) { | ||
next = current + 1; | ||
next_msg_flags = &(next->flags); | ||
} | ||
ret = stm32_i2c_transaction(dev, *current, next_msg_flags, slave); | ||
ret = stm32_i2c_transaction(dev, *current, next ? &(next->flags) : NULL, slave); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not mix non related DMA changes within this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
k_sem_init(&data->dma_rx_sem, 1, K_SEM_MAX_LIMIT); | ||
k_sem_init(&data->dma_tx_sem, 1, K_SEM_MAX_LIMIT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See definition for K_SEM_MAX_LIMIT
This is intended for use when a semaphore does not have an explicit maximum limit, and instead is just used for counting purposes.
Are you sure this is the intended behavior in this case ?
Note that we probably have other bad usages elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used this to catch an unknown number of threads accessing the same I2C bus, do you have any known good usages I can follow instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
k_sem_init(&data->dma_rx_sem, 1, 1);
k_sem_init(&data->dma_tx_sem, 1, 1);
drivers/i2c/i2c_ll_stm32.c
Outdated
case DMA_STATUS_BLOCK: | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Support of DMA_STATUS_BLOCK
is related to enabling circular mode. If not supported for now (support could be enabled later) let's generate an assert in this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you prefer an assert or a log_err?
drivers/i2c/i2c_ll_stm32_v2.c
Outdated
static int configure_dma(const struct device *dma_dev, uint32_t dma_channel, | ||
struct dma_config *dma_cfg, struct dma_block_config *blk_cfg, | ||
uint32_t source_address, uint32_t dest_address, struct i2c_msg *msg, | ||
struct k_sem *dma_sem, const char *direction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is suboptimal to use more than 4 parameters in a function on ARM platforms. 4 first params are accessed from registers (r0-r3), other params will be accessed from stack.
Any way to do this differently ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad you mentioned it, I've been playing with re-jigging the structs which may help here... so yes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
structs re-jigged
I did not, I was porting over changes I was using for a project but I can take a look at this when I have time.
I will revert this
should I close this MR until this can be rebased and I've had a chance to look at the callback mechanism? |
057bc2b
to
94c6e1d
Compare
Would be great. Thanks
Not required. But for clarity, you can move it to draft. |
Add option to enable DMA support Signed-off-by: Simon Gilbert <[email protected]>
Add initial DMA settings structs to stm32 i2c config and data structs Signed-off-by: Simon Gilbert <[email protected]>
Add macrobatics to pull DMA settings from device tree Signed-off-by: Simon Gilbert <[email protected]>
Add DMA header files Signed-off-by: Simon Gilbert <[email protected]>
Add DMA options (phandle-array and names) to yaml file Signed-off-by: Simon Gilbert <[email protected]>
Tidy up of i2c_stm32_transfer and added TX and RX semaphore inits
Added stop DMA fot transmit complete or other master end conditions
Clang format Signed-off-by: Simon Gilbert <[email protected]>
94c6e1d
to
c14037a
Compare
Add assert catches in DMA callbacks Signed-off-by: Simon Gilbert <[email protected]>
use structs to pass dma device and config settings more easily Signed-off-by: Simon Gilbert <[email protected]>
f9bdf86
to
cfd0b0a
Compare
Second pass at applying Clang Format Signed-off-by: Simon Gilbert <[email protected]>
cfd0b0a
to
8c030ea
Compare
Add DMA enhancement for stm32 i2c_v2 driver
Fix #34354