Skip to main content
Visitor II
April 2, 2024
Solved

STM32U5A5: DMA to SAI2 does not work - why?

  • April 2, 2024
  • 1 reply
  • 1017 views

I want to send audio samples (received via SAI1 from PDM MIC) to SAI2_SD_B as SPDIF out.

It does not work, because: the DMA does not seem to write the DR in SAI2:

  • the memory is filled with audio samples
  • the DMA seems to run (I get the HAL_SAI_TxCpltCallback and I can see via debugger that the DMA pointers are moving)
  • but the SPDIF sends all zero: on scope, the SPDIF output is all as zero words

Remark: it is on a STM32U5A5RJT6Q (LQFP64 package): the datasheet "says": not a SAI2 there (just one SAI) - but not true - it works also with SAI2, even CubeMX does not let me configure SAI2 pins (also wrong in CubeMX tool). But I can configure SAI2 and see it working (in Polling and INT mode, just the DMA fails).

So, my impression: the circular buffer and DMA does not work. No idea why not: the code is generated by CubeMX.

This topic is related to this thread:

Solved: STM32U5xx: SPDIF out - how to configure? - STMicroelectronics Community

Here is the DMA config I use: Why does it send all as zero (or does not send anything into SAI2_B DR)?

 

 /* Peripheral DMA init - SAI2_SD_B as SPDIF - use CH5 */
 NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
 NodeConfig.Init.Request = GPDMA1_REQUEST_SAI2_B;
 NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
 NodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH;
 NodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
 NodeConfig.Init.DestInc = DMA_DINC_FIXED;
 NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
 NodeConfig.Init.DestDataWidth = DMA_SRC_DATAWIDTH_WORD;
 NodeConfig.Init.SrcBurstLength = 1;
 NodeConfig.Init.DestBurstLength = 1;
 NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
 NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 NodeConfig.Init.Mode = DMA_NORMAL;
 NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
 NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
 NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
 if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel5) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel5, NULL, &Node_GPDMA1_Channel5) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel5) != HAL_OK)
 {
 Error_Handler();
 }

 handle_GPDMA1_Channel5.Instance = GPDMA1_Channel5;
 handle_GPDMA1_Channel5.InitLinkedList.Priority = DMA_LOW_PRIORITY_MID_WEIGHT;
 handle_GPDMA1_Channel5.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
 handle_GPDMA1_Channel5.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
 handle_GPDMA1_Channel5.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 handle_GPDMA1_Channel5.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
 if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel5) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel5, &List_GPDMA1_Channel5) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(hsai, hdmatx, handle_GPDMA1_Channel5);

 if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel5, DMA_CHANNEL_NPRIV) != HAL_OK)
 {
 Error_Handler();
 }

 

BTW: what is "DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0"?
It is the same for the SAI1 DMA, using channel 4, with quite similar config (just direction is reversed), but also PORT0 used there. Is this a conflict? (even the channel is a different one).

Why is the circular DMA buffer config not working for Memory-to-SAI2_B?

 

 

    This topic has been closed for replies.
    Best answer by tjaekel

    close the ticket

    1 reply

    tjaekelAuthorAnswer
    Visitor II
    July 11, 2024

    close the ticket