2
\$\begingroup\$

enter image description here I'm facing a strange behaviour of DMA which I cannot explain myself. I just want DMA to send a data block (i.e. one 32bit word) to the SAI peripherie and quit then and give a "transfer complete callback". The normal/blocking mode sends data block and exits then. But in DMA transfer mode, DMA sends the data block continuously so SAI peripherie outputs the word in loop. No exit, no callbacks...

What am I doing / configuring or understanding wrong?

Here's a simplified code, which outputs the looped signal above:

//main function
uint32_t buf=0b10101010101010101100110011001100;
HAL_SAI_Transmit_DMA2(&hsai_BlockA1, (uint8_t*)&buf, 1);

//DMA Transmit Funktion

HAL_StatusTypeDef HAL_SAI_Transmit_DMA2(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size){

    HAL_DMA_Start(hsai->hdmatx, (uint32_t)pData, (uint32_t)&hsai->Instance->DR, Size);

    // Enable SAI
    __HAL_SAI_ENABLE(hsai);

    /* Enable SAI Tx DMA Request */
    hsai->Instance->CR1 |= SAI_xCR1_DMAEN;

    return HAL_OK;

}

Configurations

//Configuration SAI

  hsai_BlockA1.Instance = SAI1_Block_A;
  hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX;
  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_HF;
  hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
  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;
  HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_MSBJUSTIFIED, SAI_PROTOCOL_DATASIZE_32BIT, 2);

//Configuration DMA

__HAL_RCC_DMA2_CLK_ENABLE();

 hdma_sai1_a.Instance=DMA2_Stream1;
 hdma_sai1_a.Init.Channel = DMA_CHANNEL_0;// Channel 0, Stream 0
 hdma_sai1_a.Init.Direction=DMA_PERIPH_TO_MEMORY;
 hdma_sai1_a.Init.PeriphInc=DMA_PINC_DISABLE;
 hdma_sai1_a.Init.MemInc=DMA_MINC_DISABLE;
 hdma_sai1_a.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;
 hdma_sai1_a.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;
 hdma_sai1_a.Init.Mode=DMA_NORMAL;
 hdma_sai1_a.Init.Priority=DMA_PRIORITY_HIGH;
 hdma_sai1_a.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
 hdma_sai1_a.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL;
 hdma_sai1_a.Init.MemBurst=DMA_MBURST_SINGLE;
 hdma_sai1_a.Init.PeriphBurst=DMA_PBURST_SINGLE;
 hdma_sai1_a.XferCpltCallback  = HAL_DMA_XFER_HALFCPLT_CB_ID;

//Initialize DMA
HAL_DMA_Init(&hdma_sai1_a);
\$\endgroup\$
3
\$\begingroup\$

The "Circular mode" is responsible for this behaviour.

(I have overseen that the same DMA instance was initialized by HAL library in the file "the stm32f7xx_hal_msp.c" in the function "HAL_SAI_MspInit()". So my configuration was being overwritten.)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.