cancel
Showing results for 
Search instead for 
Did you mean: 

Error using UART and DMA

Noname1937
Associate III
Posted on February 27, 2018 at 23:00

Hello, 

I am building an application in olimex e407. It's running FreeRTOS, lwIP, I'm running the ADC @10kHz triggered by timer and getting the data via DMA and I also want to communicate with an external uC via UART and DMA. 

For the solo UART implementation I did everything according to the reference manual and I also compared my code with some codes I found on the internet that were supposedly working. I can get to the point that I can send the UART transmission via DMA, then somewhere during the DMA reception an error occurred and it wouldn't work anymore. 

After a little bit of manually messing with the registers I noticed that I needed to clear the SR, more specifically, the idle flag and it started working. I could create a task that would send and receive data every second. 

When I tried putting everything together, the DMA would lock upt the entire system and FreeRTOS could no longer run anymore tasks. I can see, from what I've read on the internet that there is something wrong with the way I'm handling the error, but I have no idea how to proceed with this. 

PS: I also noticed that the uart handle has a rState of busy and a gState of ready, as well as the problem with the registers. I'm also communicating at 9600, nothing that should cause an overrun, at least in my opinion. 

huart.Instance = USART6;

huart.Init.BaudRate = 9600;

huart.Init.WordLength = UART_WORDLENGTH_8B;

huart.Init.StopBits = UART_STOPBITS_1;

huart.Init.Parity = UART_PARITY_NONE;

huart.Init.Mode = UART_MODE_TX_RX;

huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart.Init.OverSampling = UART_OVERSAMPLING_16;

hdma_usart_tx.Instance = DMA2_Stream6;

hdma_usart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_usart_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_usart_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_usart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_usart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_usart_tx.Init.Mode = DMA_NORMAL;

hdma_usart_tx.Init.Priority = DMA_PRIORITY_LOW;

hdma_usart_tx.Init.Channel = DMA_CHANNEL_5;

hdma_usart_rx.Instance = DMA2_Stream1;

hdma_usart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_usart_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_usart_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_usart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_usart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_usart_rx.Init.Mode = DMA_NORMAL;

hdma_usart_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;

hdma_usart_rx.Init.Channel = DMA_CHANNEL_5;

This is my configuration, obviously I call the LINK macro, the proper init functions and finally HAL_UART_Receive_DMA and HAL_UART_Transmit_DMA. 

My error handling function basically consists on forcing a Ready state and clearing SR bits. I even clear bits in the USART6 IRQhandler. 

Can anyone point me in the right direction? Is it maybe a bug in the HAL library? Probably not, but I'd really like to make sure. Tomorrow I'll try new things and update the question, but if anyone is feeling generous and knows what's wrong, please let me know

#uart-dma #stm32f4 #dma-problem #freertos+hal
1 REPLY 1
T J
Lead
Posted on February 28, 2018 at 00:25

There are many other posts on this issue...

I use a circular DMA Rx buffer and a Normal DMA Tx buffer.

Then I poll the buffer depths from the foreground process.

You may want to test some examples first, to see how the HAL interface runs.