cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405RG USART DMA FIFO Error Problem

LLOLO.1
Associate II

Hello, I am trying to use DMA with USART to transmit and receive data to buffers in internal RAM.

I setup my DMA1_Stream4 as USART3_TX. However, after setting DMA control register, Peripheral address, memory address, number of data to transfer, Enabling DMA causes FEIF4 to set. I cannot transmit anything.

I shared my whole code below.

#include "main.h"
#include "SysClkConfiguration.h"
 
uint8_t USART3_Transmit_Buffer1[4] = {"Test"};
uint8_t USART3_Receive_Buffer[3];
 
void Initialization()
{
	//----------RCC Configuration----------//
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; //Enable GPIOC Clock
	RCC->APB1ENR |= RCC_APB1ENR_USART3EN; //Enable USART Peripheral Clock
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; //Enable DMA1 Clock
 
	//----------GPIO Configuration----------//
	GPIOC->MODER |= (0b10<<GPIO_MODER_MODE10_Pos) | (0b10<<GPIO_MODER_MODE11_Pos); //Set PC11/10 as Alternate Function
	GPIOC->OSPEEDR |= (0b10<<GPIO_OSPEEDR_OSPEED10_Pos) | (0b10<<GPIO_OSPEEDR_OSPEED10_Pos); //Set PC10/11 Output Speed as High Speed
	GPIOC->AFR[1] |= (0b0111<<GPIO_AFRH_AFSEL10_Pos) | (0b0111<<GPIO_AFRH_AFSEL11_Pos); //Set PC10/11 as USART3 RX/TX
 
	//----------USART Configuration----------//
	USART3->CR1 &= ~(USART_CR1_UE); //USART Disabled
	USART3->BRR = 0x0020; //Baudrate is set 2Mbps
	USART3->CR1 |= USART_CR1_OVER8 | USART_CR1_TE | USART_CR1_RE; //Oversampling Mode, Transmit Enable, Receive Enable
	USART3->CR3 |= USART_CR3_DMAT | USART_CR3_DMAR; //DMA Enable Transmitter, DMA Enable Receiver
 
	//----------DMA Configuration----------//
	DMA1_Stream1-> CR &= ~(DMA_SxCR_EN); //Disable DMA1_Stream1
	//							Channel 4 				High Priority		  Memory Inc.		Circular	 Transmit Comp. Interrupt
	DMA1_Stream1-> CR |= (4<<DMA_SxCR_CHSEL_Pos) | (0b10<<DMA_SxCR_PL_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE;
	DMA1_Stream1-> PAR  = (uint32_t) &USART3->DR;
	DMA1_Stream1-> M0AR = (uint32_t) USART3_Receive_Buffer;
	DMA1_Stream1-> NDTR = 3;
	DMA1_Stream1-> CR |= DMA_SxCR_EN; //Enable DMA1_Stream1
 
	DMA1_Stream4-> CR &= ~(DMA_SxCR_EN); //Disable DMA1_Stream4
	//							Channel 7 				Medium Priority		  Memory Inc.		Memory-to-peripheral	Transmit Comp. Interrupt
	DMA1_Stream4-> CR |= (7<<DMA_SxCR_CHSEL_Pos) | (0b01<<DMA_SxCR_PL_Pos) | DMA_SxCR_MINC | (0b01<<DMA_SxCR_DIR_Pos) | DMA_SxCR_TCIE;
	DMA1_Stream4-> PAR  = (uint32_t) &USART3->DR;
	DMA1_Stream4-> M0AR = (uint32_t) USART3_Transmit_Buffer1;
	DMA1_Stream4-> NDTR = 4;
	DMA1_Stream4-> CR |= DMA_SxCR_EN; //Enable DMA1_Stream4 (Transmit Buffer through USART3)
 
	//----------NVIC Configuration----------//
	NVIC_EnableIRQ(DMA1_Stream1_IRQn); //Enable DMA1 Stream1
	NVIC_EnableIRQ(DMA1_Stream4_IRQn); //Enable DMA1 Stream4
 
 
	//----------Peripheral Activation----------//
	USART3->CR1 |= USART_CR1_UE; //USART Enabled
}
 
 
 
void DummyDelay(uint32_t x)
{
	while(x)
	{
		x--;
	}
}
 
int main(void)
{
 
  HAL_Init();
  SystemClock_Config();
  Initialization();
 
 
  while (1)
  {
	  DMA1_Stream4-> CR |= DMA_SxCR_EN; //Enable DMA1_Stream4 (Transmit Buffer through USART3)
	  DummyDelay(1000000);
	  DMA1_Stream4-> CR |= DMA_SxCR_EN; //Enable DMA1_Stream4 (Transmit Buffer through USART3)
	  DummyDelay(1000000);
  }
 
}
 
void DMA1_Stream1_IRQHandler()
{
	if(DMA1->LISR & DMA_LISR_TCIF1)
	{
		DMA1->LIFCR |= DMA_LIFCR_CTCIF1; //Clear Transmission Complete Flag
 
 
	}
 
}
 
void DMA1_Stream4_IRQHandler()
{
	if(DMA1->HISR & DMA_HISR_TCIF4)
	{
		DMA1->HIFCR |= DMA_HIFCR_CTCIF4; //Clear Transmission Complete Flag
 
 
	}
 
}

What could be the problem? What am I setting wrong?

2 REPLIES 2
TDK
Guru

One typo here:

> GPIOC->OSPEEDR |= (0b10<<GPIO_OSPEEDR_OSPEED10_Pos) | (0b10<<GPIO_OSPEEDR_OSPEED10_Pos); //Set PC10/11 Output Speed as High Speed

Are the two pins connected to each other? How do you know data is being received?

The compiler is allowed to completely optimize out your DummyDelay function. You can make the variable volatile, or (better) use an actual delay such as HAL_Delay or similar.

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

> Enabling DMA causes FEIF4 to set. I cannot transmit anything.

Why? Your setup ignores FIFO error - and rightly so, in Direct mode you are using.

You can avoid it by setting USART_CR3_DMAT *after* you enable the respective DMA.

For explanation, see AN4031, chapter 4.3 Software sequence to enable DMA.

JW