cancel
Showing results for 
Search instead for 
Did you mean: 

Question on SAI DMA buffer

Jansunil
Associate II

Hi Team,

I am using a the SAI Peripheral from the STM32L5 family to read data from a master device. I am employing the DMA peripheral to read the data from SAI. I have a buffer of 32kb and I am using the STM board as a slave device. I am using the HAL_SAI_RxCpltCallback() to detect the buffer full status. However, I see that the DMA data is getting overwritten by the time it reaches the Rx complete callback function, unless I stop the DMA transfer inside the Rx complete callback (which is not preferred for the use case that I am working on). This is seen only for a certain frequencies of FS signal.

Here are my debug steps:

STEP-1: Start SAI DMA transfer

STEP-2: Wait for control to get into the HAL_SAI_RxCpltCallback()

STEP-3: Read the data from the DMA buffer within the HAL_SAI_RxCpltCallback()- Here's where I see the data is being overwritten when I read it.

DMA Settings: Circular Mode, 32 bit word transfer

SAI Settings: 32 bit data * 4 slots , slave mode.

Are there any suggestions to circumvent this issue? Any leads on this would be of help. Thanks in advance.

Regards,

Janani Sunil.

6 REPLIES 6
LCE
Principal

Check if that STM32's DMA supports double buffer mode (DBM bit, usually set in DMA's CR register).

If it does support DBM, then you activate that, and in half-complete callback you change the currently unused (check CR's CT bit) destination address register M0AR / M1AR.

If it does not support DBM, you should choose the buffer size more wisely: 32 kB takes a lot time to work on, even if it is only copying data, so you need a smaller buffer which can be worked on in the time it takes new data to arrive (SAI sampling period).

Hi @Community member​ - Thank you for the suggestion. However, I have a question on DBM.

I have activated DBM by calling the HAL_DMAEx_MultiBufferStart_IT(). I have submitted two local buffers :

uint32_t buffer1[400];

uint32_t buffer2[400];

Upon the processor's entry to HAL_SAI_RxHalfCpltCallback() after filling up half of the buffer, I see that both the buffers (ie buffer1 and buffer2) are filled up completely.

How is the callback supposed to work in this case?- Does the processor access the half transfer complete callback after receiving every 200 slots of data?

Thanks,

Janani Sunil

AScha.3
Chief III
  • dont use : HAL_DMAEx_MultiBufferStart_IT
  • just set DMA Settings: Circular Mode
  • enable callbacks (in Cube -> project manager -> advanced s. -> SAI enable
  • now you get 2 callbacks: half... and full...
  • process the calling -> but in time, before the other callback coming.
  • thats all.
If you feel a post has answered your question, please click "Accept as Solution".

Hi @AScha.3​ - Thank you for your reply.

The above steps work perfect for the single buffer mode.

In case I want to employ a DBM, without using the HAL_DMAEx_MultiBufferStart_IT(), which other way would I tell the processor that the DMA needs to work in double buffer mode? The HAL_DMAEx_MultiBufferStart_IT() accepts two memory addresses with which I can configure both the buffers.

Thanks,

Janani Sunil

DMA in Circular Mode can do " double buffer " anyway.

(is the "usual" way to work with dma for continuous data transfers )

the buffer is used in 2 half blocks, thats why you have to use/process both blocks:

  1. HAL_SAI_TxHalfCpltCallback() - or ..Rx... for receiving data
  2. HAL_SAI_TxCpltCallback()

so set the buffer 2x size , what as a data-block size you want.

memory addresses are simply : block start, block 1/2 size , block end.

understand now ?

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

AScha.3 is correct, DBM is not needed in most cases.

The Half- / Complete splitting is probably good enough.