cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Transmit_DMA issues

Posted on June 02, 2015 at 19:39

I am trying a simple test. I want to output a single character to the UART using DMA.

I am using system workbench for stm32 First I tried configuring the DMA in normal mode.

huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart2_tx);
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);

The only code I have added is this and code to blink LEDs in the while (1) loop:

/* USER CODE BEGIN 2 */
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''a''
,1);
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''b''
,1);
/* USER CODE END 2 */

In normal mode it outputs the character 'a' once then the lights begin to blink. The character 'b' is never put out to the uart. If I do something like this

char
testMessage[] = 
''test output of a longer string\r\n''
;

HAL_UART_Transmit_DMA(&huart2,(uint8_t*)&testMessage,
sizeof
(testMessage)-1);

HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''a''
,1);
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''b''
,1);

I only get the testMessage array output. 'a' and 'b' are never put out to the uart If I setup my code to use the DMA in circular mode as follows:

huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart2_tx);
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);

Then run the first set out outputs again:

HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''a''
,1);
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''b''
,1);

It outputs a continuous stream of the letter 'a' continuing while the lights are being blinked. 'b' is never output When I output the string as well:

char
testMessage[] = 
''test output of a longer string\r\n''
;
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)&testMessage,
sizeof
(testMessage)-1);
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''a''
,1);
HAL_UART_Transmit_DMA(&huart2,(uint8_t*)
''b''
,1);

The testMessage array is sent repeatedly while the leds blink. 'a' and 'b are never output Clearly I am missing something minor here. Reading document UM1725 ''Description of STM32F4xx HAL drivers'' page 846 has this to say about DMA on the uart: ''Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxCpltCallback'' So what am I missing here? Why does circular mode just keep repeating the output and normal mode simply output once then stop all other outputs? Thank you for your assistance in this matter #dma-uart-usart-hal #hal_uart_transmit_dma
20 REPLIES 20

Thanks for the info. I haven't been in this business for a long time. Are there any reasonable alternatives or the only way is to do everything lowlevel?