STM32 DMA Transmission Error

I am using the STM32F407VTG6 controller and trying to get data from SPI using DMA. Then I want to process data about the complete interruption of DMA transmission. But when a complete transmission interrupt occurred, I see that the TEIF flag (transmission interrupt flag) is set. After that, DMA cannot be started. This is part of my code:

static void DmaInit() { DMA_InitTypeDef dma; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA for Rx dma.DMA_Channel = DMA_Channel_3; dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; dma.DMA_Memory0BaseAddr = 0; // will be set later dma.DMA_DIR = DMA_DIR_PeripheralToMemory; dma.DMA_BufferSize = 1; // will be set later dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_Priority = DMA_Priority_High; dma.DMA_FIFOMode = DMA_FIFOMode_Disable; dma.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; dma.DMA_MemoryBurst = DMA_MemoryBurst_Single; dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_DeInit(DMA2_Stream2); DMA_Init(DMA2_Stream2, &dma); // Enable DMA Interrupt on complete transfer NVIC_EnableIRQ(DMA2_Stream2_IRQn); DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE); } // It run on external interrupt static void DmaStart(uint32_t bufferSize, uint32_t* rxBuffer) { // Start DMA for reading DMA2_Stream2->NDTR = bufferSize; DMA2_Stream2->M0AR = (uint32_t)rxBuffer; DMA_Cmd(DMA2_Stream2, ENABLE); } static void SpiInit() { SPI_InitTypeDef spi; // Enable clock for SPI RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI settings SPI_StructInit(&spi); spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi.SPI_Mode = SPI_Mode_Master; spi.SPI_DataSize = SPI_DataSize_8b; spi.SPI_CPOL = SPI_CPOL_Low; spi.SPI_CPHA = SPI_CPHA_2Edge; spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; spi.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); } 
+6
source share
1 answer

These days I just finished my SDIO + DMA, some notes may be useful for you:

  • Clear flags before turning on the stream

     DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2); 
  • Clear the EN bit in the DMA_SxCR register, wait until the EN bit is read as 0 until DMA_Init ()

     DMA_Cmd(DMA2_Stream2, DISABLE); while (DMA2_Stream2->CR & DMA_SxCR_EN); 
  • When using DMA_FIFOMode_Disable (Direct Mode), the data width is determined by DMA_PeripheralDataSize (PSIZE), DMA_MemoryDataSize (MSIZE) is ignored

  • The memory address should be aligned with the selected data width (HalfWord)

Link:

+6
source

All Articles