Skip to main content
VHEMaster
Associate III
March 26, 2022
Solved

STM32F746: SAI doesn't work in TDM mode

Good day everyone.

Trying to make SAI work in TDM mode with DMA on STM32F746.

Need to transmit 8 stereo channels, the sample is 16-bit long. So 16 * 2 * 8 = 256 bit frame.

Init code:

hsai_BlockA1.Instance = SAI2_Block_A;
 hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
 hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
 hsai_BlockA1.Init.DataSize = SAI_DATASIZE_32;
 hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB;
 hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
 hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
 hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
 hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
 hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL;
 hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
 hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
 hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
 hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
 hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
 hsai_BlockA1.FrameInit.FrameLength = 256;
 hsai_BlockA1.FrameInit.ActiveFrameLength = 1;
 hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
 hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
 hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
 hsai_BlockA1.SlotInit.FirstBitOffset = 0;
 hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
 hsai_BlockA1.SlotInit.SlotNumber = 8;
 hsai_BlockA1.SlotInit.SlotActive = 0x000000FF;
 HAL_SAI_Init(&hsai_BlockA1);

MSP init:

if(hsai->Instance==SAI2_Block_A)
 {
 /* Peripheral clock enable */
 
 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
 PeriphClkInitStruct.PLLSAI.PLLSAIN = 316;
 PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
 PeriphClkInitStruct.PLLSAI.PLLSAIQ = 7;
 PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV2;
 PeriphClkInitStruct.PLLSAIDivQ = 1;
 PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
 PeriphClkInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 
 if (SAI2_client == 0)
 {
 __HAL_RCC_SAI2_CLK_ENABLE();
 
 /* Peripheral interrupt init*/
 HAL_NVIC_SetPriority(SAI2_IRQn, 5, 0);
 HAL_NVIC_EnableIRQ(SAI2_IRQn);
 }
 SAI2_client ++;
 
 /**SAI2_A_Block_A GPIO Configuration
 PD11 ------> SAI2_SD_A
 PD12 ------> SAI2_FS_A
 PD13 ------> SAI2_SCK_A
 */
 GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF8_SAI2;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
 /* Peripheral DMA init*/
 
 hdma_sai2_a.Instance = DMA2_Stream4;
 hdma_sai2_a.Init.Channel = DMA_CHANNEL_3;
 hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
 hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
 hdma_sai2_a.Init.Priority = DMA_PRIORITY_MEDIUM;
 hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Several peripheral DMA handle pointers point to the same DMA handle.
 Be aware that there is only one stream to perform all the requested DMAs. */
 __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_a);
 
 __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
 
 }

After starting DMA, NDTR register of DMA stream is set to BufferSize-8 (I assume due to FIFO size of 8 bytes) and nothing happenens after. No any interrupt generated. In software polling mode I'm getting HAL_ERROR due to timeout.

Please help.

Best Regards

This topic has been closed for replies.
VHEMaster
VHEMasterBest answer
Associate III
March 29, 2022

Hi, thank you for a message. I found a reason... The problem was in wrong alternate function of GPIOs. It was GPIO_AF8_SAI2, but GPIO_AF10_SAI2 needed.

Thanks!

Maks

2 replies

waclawek.jan
Super User
March 26, 2022

Sounds like missing clock.

Try some other, "simpler" mode.

Read out and check/post relevant RCC (both enable and the dedicated clock generation), GPIO, SAI and DMA registers content.

Is there any activity on the related pins?

JW

VHEMaster
VHEMasterAuthorBest answer
Associate III
March 29, 2022

Hi, thank you for a message. I found a reason... The problem was in wrong alternate function of GPIOs. It was GPIO_AF8_SAI2, but GPIO_AF10_SAI2 needed.

Thanks!

Maks