Skip to main content
JulienD
Associate III
September 26, 2018
Question

CubeF4, when is a UART DMA transmission over ?

  • September 26, 2018
  • 6 replies
  • 1060 views

Hello,

I'm sending data on UART using DMA with HAL_UART_Transmit_DMA().

As sometimes I need to send two messages consecutively, I'm testing if the previous

message is sent before preparing the new one. I do something like this:

void sendData(){
 uint8_t toSendCount;
 while (HAL_UART_GetState(usart) != HAL_UART_STATE_READY)
 ;
 s->size = 12;
 s->code = CommandConsts::GET_PARAMS;
 protocol->initTxFrame((uint8_t*)s, counter, txBuffer, &toSendCount);
 HAL_UART_Transmit_DMA(usart, txBuffer, toSendCount);
}

Generaly it works but sometimes, HAL_UART_GetState() never stop returning HAL_UART_STATE_BUSY_TX  

I'm using F446.

What should I do ? Which function(s) should I call? Which register should I check?

This topic has been closed for replies.

6 replies

AvaTar
Senior III
September 26, 2018

A DMA transmission is over when the last item (byte) is placed at the target address - the UART TX register in your case.

This, in turn, might depend on the hardware and your UART settings. If you use flow control, the other site can delay the transmissions.

Or you just run in one of Cube's randomly determined timeouts.

T J
Senior III
September 26, 2018

this is how I check if the Tx DMA has completed,

works on F7 and F0 processors

void CheckTxDMABufferProgress(void) {
 if (TxDMABufHasData) {
 char uartState = HAL_UART_GetState(&huart7);
 if ((uartState == HAL_UART_STATE_READY) || (uartState == HAL_UART_STATE_BUSY_RX)) 
 {
 TxDMABufHasData = false;	// sending now
 if (HAL_UART_Transmit_DMA(&huart7, (uint8_t *)Usart1TxDMABuffer + U1TxBufferPtrOUT, 
 U1TxBufferPtrIN - U1TxBufferPtrOUT) == HAL_OK) {
 		HAL_UART_Transmit_DMA_Status = UartDMAsuccess;
 		U1TxBufferPtrOUT = U1TxBufferPtrIN;
 	}

JulienD
JulienDAuthor
Associate III
September 26, 2018

@Community member​  Thanks, your method is a bit better than mine by chekcing busy_rx (but btw, I'm not using DMA for rx...)

T J
Senior III
September 29, 2018

why not ?

the Rx DMA works very well and its endless.

Werner Dähn
Associate III
October 1, 2018

Is RX endless?

First, only if you set it to CIRCULAR, obviously.

Second, per my observation any error, even the slightest stops the "endless". Noise error, frame error, parity error.

So you need a place where you restart it. Agreed? Or is my observation wrong?

(I am still in the learning phase in regards to DMA, hence asking)

T J
Senior III
October 1, 2018

I am not sure why my code is so stable.

I am not sure why I never fall into any error interrupt, probably not enabled.

I only initialise the DMA on startup, I have boards running here on test for over a year now.

Yes, you could probably check for the DMA "not ok" and restart it.

what that flag is, I am not sure, I never needed it.

I have a foreground process that checks some flags every mS and others every Second