cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Transmit_DMA problem

Min-Kyoung Kim
Associate III
Posted on February 06, 2017 at 14:22

I had problem for 'HAL_UART_Transmit_DMA', once I transmitted some data, I couldn't send any data after that.

I used this function,

'HAL_UART_Transmit_DMA' in 'USART1_IRQHander'.

(Because I should parse the data as soon as I receive any data. (N of data is not fixed.).)

So I found the solution in this forum. And I succeeded using'HAL_UART_Transmit_DMA'.

I attached one line(huart->gState = HAL_UART_STATE_READY;) in 'UART_DMATransmitCplt' like below.

static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
 /* DMA Normal mode*/
 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
 {
 huart->TxXferCount = 0U;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
 in the UART CR3 register */
 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
huart->gState = HAL_UART_STATE_READY; <- this!!!!
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?

But I wonder if I can use

'HAL_UART_Transmit_DMA' in'USART1_IRQHander'.

Does any problem happen later?

Please answer me,

#usart1 #dam
10 REPLIES 10
T J
Lead
Posted on February 06, 2017 at 21:58

Try this one...

void CheckTxDMABufferProgress(void){ if ( DMABufHasData ){ char uartState = HAL_UART_GetState(&huart1); if ((uartState == HAL_UART_STATE_READY) || (uartState == HAL_UART_STATE_BUSY_RX)) { DMABufHasData = false; // sending now if (HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Usart1TxDMABuffer + U1TxBufferPtrOUT ,U1TxBufferPtrIN - U1TxBufferPtrOUT) == HAL_OK){ HAL_UART_Transmit_DMA_Status = UartDMAsuccess; U1TxBufferPtrOUT = U1TxBufferPtrIN; } else{ Error_Handler(); /* Transfer error in transmission process */ HAL_UART_Transmit_DMA_Status = UartDMAfailed; } } }}�?�?�?�?�?�?

Davydenko.Sergey
Associate II
Posted on February 07, 2017 at 15:39

Good afternoon.

It seems I have encountered the same problem ...

There is no need to modify the HAL code.

You must enable global interrupt USART1

Good luck.
Gln
ST Employee
Posted on February 07, 2017 at 18:47

Hi

Min-Kyoung Kim,

The HAL code does not need to be modified. Make sure to call

HAL_UART_IRQHandler(&UartHandle)

inside your

USART1_IRQHander()

before doing another

HAL_UART_Transmit_DMA()

:

void USART1_IRQHandler(void)
{
 HAL_UART_IRQHandler(&UartHandle); // Should reset gState to HAL_UART_STATE_READY
 HAL_UART_Transmit_DMA(&UartHandle, buffer, BUFFER_SIZE);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Guillaume

Posted on February 09, 2017 at 13:02

- where can I put your function? 

- where can I get 'DMABufHasData' ?

Posted on February 09, 2017 at 13:13

I constantly check the 'DMABufHasData' code within the foreground main loop;

after I add bytes to the DMA buffer with puts(string), I set the flag 'DMABufHasData' true from anywhere in the code..

the foreground loop will send the data out instantly..

ie

while (1){

        

        delayCounter++;         // small delay loop

        

        if ( delayCounter > 0x0ff){      

            delayCounter = 0;

            checkBackgroundServices();        //  Uart1RxPort, TxDMA, RxDMA etc.

         }

}

Posted on February 09, 2017 at 14:13

you mean that i should  'SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);' after

'HAL_UART_Transmit_DMA

'

???
Posted on February 09, 2017 at 14:24

It works!!!!!

should I put your code before 'HAL_UART_Transmit_DMA'? 

Posted on February 09, 2017 at 21:34

Which part of my code exactly? In the example I posted, HAL_UART_Transmit_DMA() is called in the IRQHandler, you could also call that function in HAL_UART_TxCpltCallback() or in your main code if you look for a flag. Just make sure

HAL_UART_IRQHandler() is called BEFORE.

Posted on February 09, 2017 at 22:12

It is right that

HAL_UART_Transmit_DMA() is called in the IRQHandler.

I mean your code is below.

HAL_UART_IRQHandler(&UartHandle); 

I put this code in USART1_IRQHandler and put it before

HAL_UART_Transmit_DMA