cancel
Showing results for 
Search instead for 
Did you mean: 

(HAL) Sending UART strings using DMA

rajpaged
Associate II
Posted on February 12, 2015 at 11:51

Hi, I'm having a problem that when calling HAL_UART_TRANSMIT_DMA() I require a delay between consecutive calls of the function for it to accept new data into the DMA. I've found adding a HAL_Delay between calls fixes the problem so I must be trying to call the transmit too often.

How do I go about creating a while(dma_busy_flag){} for the DMA here? I'm using these settings:

stm32f4xx_hal_msp.c (some code not shown)

   extern DMA_HandleTypeDef hdma_usart1_tx;

   hdma_usart1_tx.Instance = DMA2_Stream7;

   hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;

   hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

   hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;

   hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

   hdma_usart1_tx.Init.Mode = DMA_NORMAL;

   hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;

   hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

   hdma_usart1_tx.Init.MemBurst = DMA_MBURST_SINGLE;

   hdma_usart1_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;

   HAL_DMA_Init(&hdma_usart1_tx);

   __HAL_LINKDMA(huart, hdmatx, hdma_usart1_tx);

 

stm32f4xx_it.c (some code not shown)

   void DMA2_Stream7_IRQHandler(void)

   {

   HAL_NVIC_ClearPendingIRQ(DMA2_Stream7_IRQn);

   HAL_DMA_IRQHandler(&hdma_usart1_tx);

   }

serial.c  (some code not shown)

   HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 5, 0);

   HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);

   /* Prints the supplied string to uart */ void print(char string[])

   {

// Do we need a ''while(dma_busy){}''?

   HAL_UART_Transmit_DMA(&huart1, (uint8_t*)string, strlen(string));

   }

   /* UART TX complete callback */

   void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

   {

// Do we need a ''clear_dma_busy_flag''?

   }

I've tried using the macros:

__HAL_DMA_GET_FLAG(&hdma_usart1_tx, DMA_FLAG_TCIF3_7)

__HAL_DMA_CLEAR_FLAG(&hdma_usart1_tx, DMA_FLAG_TCIF3_7)

but haven't had any luck. Is there somewhere I'm messing up?

(Also unrelated, how do i format posts on this forum for code?)

#brought-to-you-by-microsoft(tm) #i-can''t-help-you-with-that
3 REPLIES 3
rajpaged
Associate II
Posted on February 12, 2015 at 15:51

I've managed to get a bit further by using

while(HAL_UART_Transmit_DMA(....) != HAL_OK) {}

in my print function. The problem is that now after a few transfers, the function gets stuck as not_ok and sits in the loop forever.

my problem could simply be that im calling transmit too often and i could just join strings together before sending them out. Though I don't want to use this as a work around if I'm not using the DMA in a robust manner.

If I use HAL_UART_Transmit_IT, the same thing happens. The UART transmit seems to get stuck because ''HAL_UART_STATE_BUSY_RX_TX''.

Posted on February 12, 2015 at 17:58

With the SPL we either spin on the DMA TC, or chain the next string at the DMA TC interrupt.

The HAL adds a level of awkwardness I'm not willing to buy into.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 12, 2015 at 18:00

(Also unrelated, how do i format posts on this forum for code?)

It's that obvious ''Paintbrush [<>]'' icon with the ''Format Code Block'' hover tip, in the top left of the Word-in-a-Box(tm) interface.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..