STM32 DMA transfer error
15,154
I just finished my SDIO+DMA this days, some notes maybe useful for you:
-
Clear Flags before enabling the stream
DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
-
Clear EN bit in the DMA_SxCR Register, Wait Until the EN bit is read as 0 before DMA_Init()
DMA_Cmd(DMA2_Stream2, DISABLE); while (DMA2_Stream2->CR & DMA_SxCR_EN);
When use DMA_FIFOMode_Disable (Direct Mode), data width is determined by DMA_PeripheralDataSize (PSIZE), DMA_MemoryDataSize (MSIZE) is ignored
Memory address must be aligned to your selected data width (HalfWord)
Reference:
- STM32F407XX Reference Manual - Chapter 10 DMA Controller
- STM32F4XX Standard Peripheral Library
Author by
Goshik
Updated on June 08, 2022Comments
-
Goshik about 2 years
I use STM32F407VTG6 controller and try to receive data from SPI using DMA. Then I want to process data on DMA Complete Transfer Interrupt. But when Complete Transfer Interrupt is occurred I see that TEIF (transfer error interrupt flag) is set. After this DMA can't 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); }