2020-07-05 03:02 AM
Hi,
I have configured DMA and SAI interface as below.
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* SAI2 */
if(hsai->Instance==SAI2_Block_A)
{
/* Peripheral clock enable */
if (SAI2_client == 0)
{
__HAL_RCC_SAI2_CLK_ENABLE();
}
SAI2_client ++;
/**SAI2_A_Block_A GPIO Configuration
PI6 ------> SAI2_SD_A
PI5 ------> SAI2_SCK_A
PI4 ------> SAI2_MCLK_A
PI7 ------> SAI2_FS_A
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_sai2_a.Instance = DMA2_Stream1;
hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;
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_HALFWORD;
hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
hdma_sai2_a.Init.Priority = DMA_PRIORITY_HIGH;
hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sai2_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sai2_a.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_sai2_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
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 channel to perform all the requested DMAs. */
__HAL_LINKDMA(hsai,hdmarx,hdma_sai2_a);
__HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
}
}
static void MX_SAI2_Init(void)
{
/* USER CODE BEGIN SAI2_Init 0 */
/* USER CODE END SAI2_Init 0 */
/* USER CODE BEGIN SAI2_Init 1 */
/* SAI PCM Output init */
__HAL_SAI_RESET_HANDLE_STATE(&hsai_BlockA2);
/* USER CODE END SAI2_Init 1 */
hsai_BlockA2.Instance = SAI2_Block_A;
hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
hsai_BlockA2.Init.DataSize = SAI_DATASIZE_16;
hsai_BlockA2.Init.FirstBit = SAI_FIRSTBIT_MSB;
hsai_BlockA2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
hsai_BlockA2.Init.PdmInit.Activation = DISABLE;
hsai_BlockA2.Init.PdmInit.MicPairsNbr = 1;
hsai_BlockA2.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
hsai_BlockA2.FrameInit.FrameLength = 128;
hsai_BlockA2.FrameInit.ActiveFrameLength = 64;
hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockA2.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
hsai_BlockA2.SlotInit.FirstBitOffset = 0;
hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockA2.SlotInit.SlotNumber = 4;
hsai_BlockA2.SlotInit.SlotActive = 0x00000005;
if (HAL_SAI_Init(&hsai_BlockA2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SAI2_Init 2 */
/* Enable SAI to generate clock used by audio driver */
__HAL_SAI_ENABLE(&hsai_BlockA2);
/* USER CODE END SAI2_Init 2 */
}
Now HAL_SAI_Init and HAL_DMA_Init works fine. My STM32H745 discovery board is connected to PC using USB_OTG cable to make board to work as USB device audio class. I am able to detect Audio Class. Now when I plays some file on PC then it will send some data to board and board will send same to Audio Codec via SAI interface. Here to transfer data to SAI DMA is used. When HAL_SAI_Transmit_DMA used to transfer data in DMA interrupt handler it returns with Transmit Error. Also function HAL_SAI_Transmit_DMA gives FIFO timeout as it's not able to empty FIFO within given duration. I have increased timeout also but still same issue. Any idea how can I resolve transmit error? which is caused by FIFO is not getting empty.
Thanks,
Nilesh Kadivar