2023-11-09 05:32 AM
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.
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.
Solved! Go to Solution.
2023-11-14 07:26 AM - edited 2023-11-14 07:28 AM
Now it's ok
I just to change the configuration and I configure the SAI in DMA only for transmission but not for reception.
2023-11-10 01:13 AM
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
2023-11-10 01:39 AM - edited 2023-11-10 01:42 AM
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
I configured the SAI with DMA, one for sending and the other for receiving :
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.
2023-11-10 01:48 AM
ok, i see start -> transmit dma...
but no start : HAL_SAI_Receive_DMA(SAI...) - try. (and maybe better, start receive first, then transmit .)
2023-11-10 01:52 AM
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);
2023-11-10 02:19 AM - edited 2023-11-10 02:19 AM
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...
2023-11-10 04:01 AM
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.
2023-11-10 04:40 AM - edited 2023-11-10 04:40 AM
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.
2023-11-10 05:46 AM - edited 2023-11-10 06:10 AM
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
I make a breakpoint and I watch the array playbuf_RX :
For me there is no transmission. What's wrong ?
2023-11-10 06:22 AM - edited 2023-11-10 06:25 AM
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 !