cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746: SAI doesn't work in TDM mode

VHEMaster
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
VHEMaster
Associate II

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

View solution in original post

2 REPLIES 2

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
Associate II

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