cancel
Showing results for 
Search instead for 
Did you mean: 

F411 LL SPI-DMA callback delay too long

HDaji.1
Senior

My code is based on LL SPI-DMA example.

The original code does not have chip select, so I use one GPIO pin as CS pin.

  /* Start SPI Tx/Rx */
  ADC_CS_Low();
 
  /* Enable DMA Channels to start Tx/Rx */
  LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
  LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_3);
 
  /* Wait for previous Tx/Rx complete bf we send again
   */
  while(ub_SPI1_TxComplete != 1) { }
  ub_SPI1_TxComplete = 0;
  LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_3);
 
  while(ub_SPI1_RxComplete != 1) { }
  ub_SPI1_RxComplete = 0;
 
  LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_2);
 
  ADC_CS_High();

So the basic steps are:

  1. CS Low
  2. Enable Rx stream
  3. Enable Tx stream
  4. Wait for Tx/Rx complete signals, which are modified in Tx and Rx callback functions
  5. Disable Tx/Rx stream
  6. CS High

I used PicoScope to monitor clock, and CS signal.

I found from CS low to clock start the delay is well below 1 microsecond; while from clock end to CS high, it takes 2 microseconds. It's too long.

I wonder if there is any register value for me to check if Tx and Rx have finished; instead of replying on callback function.

4 REPLIES 4
S.Ma
Principal

I would bury everything under interrupt which enables you to queue up transaction request... if time is critical, NSS high time will be too. For this, you will probably need a LPTIM interrupt to fully automate the SPI and NSS toggling.

TDK
Guru

> I wonder if there is any register value for me to check if Tx and Rx have finished; instead of replying on callback function.

You can poll the DMA's NDTR register and the SPI's BUSY bit to determine when the transfer is complete. Possibly don't need the NDTR register at all here.

DMA stream will disable itself when transfer is complete (NDTR=0), but peripheral still needs to shift out data after that.

If you feel a post has answered your question, please click "Accept as Solution".

I don't quite understand how LPTIM can fully automate SPI and NSS toggling. Can you elaborate a bit more?

I guess I still need SPI LL API. For use LPTIM to toggle CS pin, I kind of need an estimated time frame to wait for SPI to finish before pulling CS high. Is this what you suggested?

Thx. I will check the reference manual.