cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745 SAI DMA receiving error

srikanth
Associate III

We are using the STM32H745 dual core MCU in the we are trying read and write the data using DMA. When we are trying to receive the data that controller going to the DMA error call back function ,for this what may be the issue . And also in interrupt mode its receiving. When iam trying to read in the DMA mode its giving an DMA error . Iam using the following for the initialization.

 hsai_BlockA2.Instance = SAI2_Block_A;

 hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;

 hsai_BlockA2.Init.AudioMode = SAI_MODESLAVE_RX;

 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_DISABLE;

 hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;

 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 = 64;

 hsai_BlockA2.FrameInit.ActiveFrameLength = 1;

 hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_STARTFRAME;

 hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;

 hsai_BlockA2.FrameInit.FSOffset = SAI_FS_FIRSTBIT;

 hsai_BlockA2.SlotInit.FirstBitOffset = 0;

 hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;

 hsai_BlockA2.SlotInit.SlotNumber = 4;

 hsai_BlockA2.SlotInit.SlotActive = 0x0000000F;

 if (HAL_SAI_Init(&hsai_BlockA2) != HAL_OK)

 {

  Error_Handler();

 }

 hsai_BlockB2.Instance = SAI2_Block_B;

 hsai_BlockB2.Init.Protocol = SAI_FREE_PROTOCOL;

 hsai_BlockB2.Init.AudioMode = SAI_MODESLAVE_TX;

 hsai_BlockB2.Init.DataSize = SAI_DATASIZE_16;

 hsai_BlockB2.Init.FirstBit = SAI_FIRSTBIT_MSB;

 hsai_BlockB2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;

 hsai_BlockB2.Init.Synchro = SAI_SYNCHRONOUS;

 hsai_BlockB2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;

 hsai_BlockB2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;

 hsai_BlockB2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;

 hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;

 hsai_BlockB2.Init.CompandingMode = SAI_NOCOMPANDING;

 hsai_BlockB2.Init.TriState = SAI_OUTPUT_NOTRELEASED;

 hsai_BlockB2.Init.PdmInit.Activation = DISABLE;

 hsai_BlockB2.Init.PdmInit.MicPairsNbr = 1;

 hsai_BlockB2.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;

 hsai_BlockB2.FrameInit.FrameLength = 64;

 hsai_BlockB2.FrameInit.ActiveFrameLength = 1;

 hsai_BlockB2.FrameInit.FSDefinition = SAI_FS_STARTFRAME;

 hsai_BlockB2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;

 hsai_BlockB2.FrameInit.FSOffset = SAI_FS_FIRSTBIT;

 hsai_BlockB2.SlotInit.FirstBitOffset = 0;

 hsai_BlockB2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;

 hsai_BlockB2.SlotInit.SlotNumber = 4;

 hsai_BlockB2.SlotInit.SlotActive = 0x0000000F;

 if (HAL_SAI_Init(&hsai_BlockB2) != HAL_OK)

 {

  Error_Handler();

 }

for DMA initialization i used the following code .

 GPIO_InitTypeDef GPIO_InitStruct;

/* SAI2 */

  if(hsai->Instance==SAI2_Block_A)

  {

  /* SAI2 clock enable */

  if (SAI2_client == 0)

  {

    __HAL_RCC_SAI2_CLK_ENABLE();

  /* Peripheral interrupt init*/

  HAL_NVIC_SetPriority(SAI2_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(SAI2_IRQn);

  }

  SAI2_client ++;

  /**SAI2_A_Block_A GPIO Configuration

  PI6   ------> SAI2_SD_A

  PI5   ------> SAI2_SCK_A

  PI7   ------> SAI2_FS_A

  */

  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_7;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;

  HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

  /* Peripheral DMA init*/

  hdma_sai2_a.Instance = DMA1_Stream3;

  hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;

  hdma_sai2_a.Init.Direction = DMA_PERIPH_TO_MEMORY;

  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);

  }

  if(hsai->Instance==SAI2_Block_B)

  {

   /* SAI2 clock enable */

   if (SAI2_client == 0)

   {

    __HAL_RCC_SAI2_CLK_ENABLE();

   /* Peripheral interrupt init*/

   HAL_NVIC_SetPriority(SAI2_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(SAI2_IRQn);

   }

  SAI2_client ++;

  /**SAI2_B_Block_B GPIO Configuration

  PE11   ------> SAI2_SD_B

  */

  GPIO_InitStruct.Pin = GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;

  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /* Peripheral DMA init*/

  hdma_sai2_b.Instance = DMA2_Stream4;

  hdma_sai2_b.Init.Request = DMA_REQUEST_SAI2_B;

  hdma_sai2_b.Init.Direction = DMA_MEMORY_TO_PERIPH;

  hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;

  hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;

  hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

  hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

  hdma_sai2_b.Init.Mode = DMA_NORMAL;

  hdma_sai2_b.Init.Priority = DMA_PRIORITY_HIGH;

  hdma_sai2_b.Init.FIFOMode = DMA_FIFOMODE_ENABLE;

  hdma_sai2_b.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;

  hdma_sai2_b.Init.MemBurst = DMA_MBURST_SINGLE;

  hdma_sai2_b.Init.PeriphBurst = DMA_PBURST_SINGLE;

  if (HAL_DMA_Init(&hdma_sai2_b) != 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_b);

  __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_b);

  }

please help us in this regards . I had wasted lot of time in this . i used the RAM address 0x24000000 in the linker settings .

2 REPLIES 2
TDK
Guru

> When iam trying to read in the DMA mode its giving an DMA error 

I don't see a call to read in DMA mode anywhere in the code you posted.

If you feel a post has answered your question, please click "Accept as Solution".
srikanth
Associate III

I had ​called a function .Hal_Sai-receive_dma function after initialisation .After executing this function it's going to dma error callback function. Any changes needed in the initialisation and memory settings .