Skip to main content
DGast.1
Associate III
February 20, 2023
Question

How to reduce the time between SPI (DMA) transactions

  • February 20, 2023
  • 3 replies
  • 2897 views

I need to transfer a large amount of bits over SPI de-asserting/asserting the select line very 64 bits. I'm using DMA. The time between transmissions is huge, as can be seen below:

0693W00000aHFGqQAO.pngThe pink channel is SCK, each chunk is 64 bits. The code is below:

while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);
 HAL_StatusTypeDef rc = HAL_SPI_Transmit_DMA(&hspi1, buff, 8);
 while (LL_SPI_IsActiveFlag_EOT(SPI1)) {}
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);
 
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);
 HAL_SPI_Transmit_DMA(&hspi1, buff, 8);
 while (LL_SPI_IsActiveFlag_EOT(SPI1)) {}
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);
 
 HAL_Delay (1000); /* Insert delay 100 ms */
 }

How can I decrease this delay?

I have though that I could config. DMA to send all the data I have, but I need to generate a pulse in the SPI SS line every 64 bits. How can I do this?

This topic has been closed for replies.

3 replies

waclawek.jan
Super User
February 20, 2023

Don't use Cube/HAL.

Increase optimization level of compiler.

You could generate complex waveform of SCK/NSS using timers in master-slave arrangement, and feed them back to SPI used as slave.

JW

S.Ma
Principal
February 20, 2023

If sending 2 blocks of data bidirectionally, use TXE, and "RXNE" at the end of all data transfer.

DMA setup takes time in HAL... you already use LL for GPIO, use HAL for GPIO and compare them.

Some STM32 have HW 32 bit FIFO on SPI, some other STM32 have linked list DMA which could make intra data packet delay down to nearly zero remains the time from NSS down to SCK toggles, and SCK stop to NSS up delays.

S.Ma
Principal
February 20, 2023

And one general note: The way you code as bare metal won't scale well if you have multiple SPI in your application (and in the MCU), as it will be time multiplexed. If you want all SPI (and other serial interfaces) to work in // , you'll need to use interrupts.