STM32F4 HAL DMA UART TX

HammerFet picture HammerFet · Feb 12, 2015 · Viewed 25.1k times · Source

I'm trying to get UART transmit working over DMA on an stm32f405. This part of my application is designed to send out text strings as a command line interface. I have the RX part of the UART working with DMA fine (using 1 byte circular DMA to handle anything that comes in) but the TX side is proving a little more tricky.

I'm able to send out strings of data using: HAL_UART_Transmit_DMA(&handle, pData[], strlen(pData)) provided there is a delay between consecutive calls of the function. As soon as my program decides to send two strings one after another, the new data pointer is ignored.

By using while(HAL_UART_Transmit_DMA(...) != HAL_OK){} I'm able to have the program wait the required time and send out consecutive strings.

This works for a while (few tens of transfers), then gets stuck due to HAL_NOT_OK.

For reference, my DMA settings are: DMA2 stream 7, channel 4, mem to periph, periph inc disabled, mem inc enabled, mem and periph align byte, normal mode (not circular), low priority, fifo disabled.

UART set to 9600 baud, 8 bit word, 1 stop bit, no parity, no hw control, 16 oversampling.

I'm trying to figure out if using FIFO will help me out here, though I'm not totally sure if i understand it yet. If i wanted to send out a single byte of data, could i do it with FIFO? is there a 1 word min limit here?

I have set up a tx complete callback that im not currently using. I did wonder if there are any flags I'd need to clear during this interrupt but not sure..

Any help appreciated!

Answer

ECO picture ECO · Aug 18, 2015

I have set up a tx complete callback that im not currently using. I did wonder if >there are any flags I'd need to clear during this interrupt but not sure.

You SHOULD wait for the tx complete callback before using HAL_UART_Transmit_DMA again. Something like:

bool txDoneFlag = false;
HAL_UART_Transmit_DMA(...)
while(!txDoneFlag);
txDoneFlag = false;
...
...


void HAL_UART_TxCpltCallback(){
    txDoneFlag = true;
}