2022-03-26 09:58 AM
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
Solved! Go to Solution.
2022-03-29 06:22 AM
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
2022-03-26 11:29 AM
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
2022-03-29 06:22 AM
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