2026-01-28 9:46 PM - last edited on 2026-01-29 12:56 AM by mƎALLEm
Hi All,
I have been using SPI1 over DMA2 on Zephyr RTOS recently to read my external flash. I had done similar thing on Bare metal / FreeRTOS based program. Both of them work fine. However, there is a problem in Zephyr based implementation of its driver compared with what i developed on Bare Metal. I configure the SPI1 to use its full possible clock 42MHz on both platforms. On my bare metal platform it runs at full 42Mbps but on Zephyr it starts giving read errors. However, if i reduce the clock to < 42MHz (to which zephyr driver forcelly rounds it down to 21MHz) it works fine.
Here is my dts node of spi1 for my development board:
&spi1 {
pinctrl-0 = <&spi1_sck_pb3 &spi1_miso_pb4 &spi1_mosi_pb5>;
pinctrl-names = "default";
clock-frequency = <42000000>; // 42MHz
dmas = <&dma2 2 3 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_MEM_INC | STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>,
<&dma2 3 3 (STM32_DMA_MEMORY_TO_PERIPH | STM32_DMA_MEM_INC | STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>;
dma-names = "rx", "tx";
status = "okay";
};
INF RTC_NOK ** ExtFlash Read 8192 Bytes @ 0x4100 **
INF RTC_NOK Read 8192 Bytes in 3.385ms
INF RTC_NOK ** ExtFlash Read 12288 Bytes @ 0x4100 **
INF RTC_NOK Read 12288 Bytes in 4.945ms
INF RTC_NOK ** ExtFlash Read 16384 Bytes @ 0x4100 **
INF RTC_NOK Read 16384 Bytes in 6.506ms
INF RTC_NOK ** ExtFlash Read 20480 Bytes @ 0x4100 **
INF RTC_NOK Read 20480 Bytes in 8.066ms
And here is the log of same reads via my own implementation of bare metal / freeRTOS
INF RTC_NOK ** ExtFlash Read 8192 Bytes @ 0x4100 **
INF RTC_NOK Read 8192 Bytes in 1.740ms
INF RTC_NOK ** ExtFlash Read 12288 Bytes @ 0x4100 **
INF RTC_NOK Read 12288 Bytes in 2.527ms
INF RTC_NOK ** ExtFlash Read 16384 Bytes @ 0x4100 **
INF RTC_NOK Read 16384 Bytes in 3.306ms
INF RTC_NOK ** ExtFlash Read 20480 Bytes @ 0x4100 **
INF RTC_NOK Read 20480 Bytes in 4.082ms
As we can clearly see that time taken by each read is double in Zephyr (not just one time overhead) due to lowered clock. But if i just use 42MHz the read simply fails.
Can someone please guide me in this regard ?
2026-01-28 10:31 PM
Having done some very superficial experiments with OSes similiar to zephyr, I can't immediately point to the issue.
But such OSes usually take control over most interrupts, which influences task timing and communication.
I would try to capture a full SPI block with e.g. a logic analyser, and check where / when it fails.
Presumably the DMA setup for subsequent blocks is linked interrupts, which are blocked by others of higher priority.
And second, I would stepwise reduce the size of transferred blocks (at full SPI speed), and see if this works.
2026-01-29 12:49 AM
@Ozone Thank you for the suggestions. I have these on my list. But, before doing any of the low level investigation, i would like to know the high level context of the things from someone who is perhaps involved in the development of that driver. I have been recently actively in contact with stm employees on discord and there definitely seem to be limitations in existing zephyr spi drivers of stm32.
Likewise, i am hoping to get a high level answer to why it is not working at 42MHz for same readback block while it works for 21MHz.
P.S: I am only using 1 block at a time. So, no chaining behavior is involved here.
2026-01-29 2:10 AM
Yes, I suppose ST staff can give more detailed answers in regard to Zephyr.
I have a somewhat similiar application, although with periodic transfer of realtime data.
The STM32 is the SPI slave device, using a bare-metal implementation.