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