cancel
Showing results for 
Search instead for 
Did you mean: 

DMA with SAI

DYann.1
Senior

Hello,

I would like to use DMA with SAI but I am having difficulty writing the code. Can you check if my code is correct and why I cannot retrieve the RX values ?

 

  /* USER CODE BEGIN 2 */

  HAL_SAI_RegisterCallback(&hsai_BlockA1, HAL_SAI_RX_HALFCOMPLETE_CB_ID, HAL_SAI_RxHalfCpltCallback);
  HAL_SAI_RegisterCallback(&hsai_BlockA1, HAL_SAI_RX_COMPLETE_CB_ID, HAL_SAI_RxCpltCallback);
  fresult= HAL_SAI_Init(&hsai_BlockA1);
  if (fresult != HAL_OK)
  	{
  	return HAL_ERROR;
  	}
  fresult = HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t *)playbuf_RX, (sizeof(playbuf_RX))/4);

  HAL_SAI_RegisterCallback(&hsai_BlockB1, HAL_SAI_TX_HALFCOMPLETE_CB_ID, HAL_SAI_TxHalfCpltCallback);
  HAL_SAI_RegisterCallback(&hsai_BlockB1, HAL_SAI_TX_COMPLETE_CB_ID, HAL_SAI_TxCpltCallback);
  fresult= HAL_SAI_Init(&hsai_BlockB1);
  if (fresult != HAL_OK)
	{
  	return HAL_ERROR;
	}

  fresult = HAL_SAI_Transmit_DMA(&hsai_BlockB1, (uint8_t *)playbuf , (sizeof(playbuf))/4);

 

With CubeMX I have configured 2 DMAs.

DYann1_0-1699536737285.png

One to send the data and the other to read the data again.
I think I'm missing something for the callback but I don't know how to use it to retrieve the values.

Thank you for your helps. 

Regards.

1 ACCEPTED SOLUTION

Accepted Solutions
DYann.1
Senior

Now it's ok

DYann1_2-1699975477522.png

DYann1_3-1699975686560.png

I just to change the configuration and I configure the SAI in DMA only for transmission but not for reception.

View solution in original post

30 REPLIES 30
Imen.D
ST Employee

Hello @DYann.1 ,

Can you please share more details (Clock, GPIO config.., device used?)

Did you try and test the SAI example provided within Cube firmware?

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi Imen,

Thank you for your feedback but I my goal is not to check the example programs. I've seen 2 examples and it doesn't match what I'm doing. Especially since there was no '.ioc' file so we can't see anything. So I can give to you my configuration and the purpose of my test. I just want to send the data through the SAI (playbuf) and retrieve (playbuf_RX) it in a table to validate the operation of my SAI. I created 2 buffers one for sending and the other for receiving. I looped the TX with the RX together

DYann1_0-1699608791451.png

I configured the SAI with DMA, one for sending and the other for receiving :

DYann1_1-1699609020941.png

If I initialize my sending table then in principle I must have the same values ​​as in my receiving table right ?

Thank you for your helps.

AScha.3
Chief II

ok, i see start -> transmit dma...

but no start :   HAL_SAI_Receive_DMA(SAI...) - try. (and maybe better, start receive first, then transmit .)

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

Hi AScha,

Are you sure ? In my code I initialized the slave before the master like this :

fresult = HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t *)playbuf_RX, (sizeof(playbuf_RX))/4);

ah, didnt see it,  ok.   but i would put the  HAL_SAI_Receive_DMA() just close to transmit start..

 (might change nothing...just try.)

 

HAL_SAI_Recieve_DMA...
HAL_SAI_Transmit_DMA...

 

 

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

Just one thing : how to know that the RX_buffer is completely filled (there is no Flag to indicate?) and how to recover the data? Do I have to create another function or is it managed automatically by the SAI DMA callback ?

In my While loop I have only this code and nothing else  :

  while (1)
  {
    /* USER CODE END WHILE */
	  HAL_Delay(100);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 Really, I think something is missing.

missing ?  when buffer half/full , you get the callback - continuous, automatic. fine.

but now in the callback - you have to use the data. move away...whatever. because short time later, depends on buffer size and data speed, data will be overwritten with the new values...

so to test: write some 0xAFFE to the transmit buffer and zero to receive buffer and start dma's then.

then stop in debug and look at the receive data...should be no more zeros there.

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

After your advice

 

 

  fresult = HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t *)playbuf_RX, (sizeof(playbuf_RX))/4);
  fresult = HAL_SAI_Transmit_DMA(&hsai_BlockB1, (uint8_t *)playbuf , (sizeof(playbuf))/4);

 

 

And I filled my TX array (playbuf) like this

DYann1_0-1699623866484.png

I make a breakpoint and I watch the array playbuf_RX :

DYann1_0-1699625402976.png

DYann1_1-1699623946734.png

For me there is no transmission. What's wrong ?

something....wrong. 🙂

what cpu we have here?  (H7 -> disable d-cache !  )

+ preset arrays before starting dma .

1. check with a scope...clk, wclk generated really ?

2. set a breakpoint at receive callback - then you know, its coming there at all !

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