zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.83k stars 6.6k forks source link

SPI STM32 - DMA optimalization #46297

Open paveldedourek-eaton opened 2 years ago

paveldedourek-eaton commented 2 years ago

Is your enhancement proposal related to a problem? Please describe. I found timing problem with spi_ll_stm32 driver was used and DMA was enabled. The problem is, when the same amount of data needs to be transferred periodically with short period (transfer few bytes every new transfer in few tens of us). I mean, that issue is there, when the time for initialization takes longer that DMA transfer itself.

transceive_dma() is developed in the way that SPI and DMA is always initialized from the scratch which takes time and it is not needed to do it when the same amount of data are going to transfer - spi_dma_move_buffers() takes ~20 us @ CPU=168MHz.

Describe the solution you'd like Solution will be, that driver knows if initialization needs to be done inside or not. User can do initialization only once. I tried to fix it, but there is still room to improve it. spi_dma_performance_nucleo_32f429zi

Describe alternatives you've considered NA

Additional context NA

erwango commented 2 years ago

@paveldedourek-eaton Thanks for reporting this. If you have a solution, would you be able to push a PR directly?

paveldedourek-eaton commented 2 years ago

@erwango My code is not tested and even this, is not correctly implemented from the entire system point of view. There is missing function/parameter which tell to the DMA, that next time, initialization can be skipped. Function spi_transceive() does not have such parameter. I guess, the driver needs other function which can configure it. We cannot use init/config function, because you can decide it in runtime that which SPI transactions needs every time DMA init or which does NOT need it.

erwango commented 1 year ago

@teburd By any chance, in the latests DMA evolutions, is there any solution to address this ?

teburd commented 1 year ago

if I'm understanding the issue, at the moment each time spi_transcieve() is called, and for every normalized tx/rx/txrx (lengths are equal) dma_config() is done under the assumption that an entirely new transfer needs to be setup. dma_config() in this setup is considered costly.

dma_reload() could possibly be used here in place of re-configuring entirely, there's no requirement that dma_config() be called every time before dma_start(). You could go so far as to only call dma_config() and dma_start() once for all time, and forever more call dma_reload in this case it seems.

Would dma_reload() be enough in this case?

erwango commented 9 months ago

@paveldedourek-eaton Any feedback on above suggestion ?