2015-11-02 03:53 AM
STM32CubeMX V4.11
STM32Cube FW_F4 V1.9.0/** ****************************************************************************** * @file stm32f4xx_hal_uart.c * @author MCD Application Team * @version V1.4.1 * @date 09-October-2015 * @brief UART HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral: * + Initialization and de-initialization functions * + IO operation functions * + Peripheral Control functions * + Peripheral State and Errors functions * @verbatim.......
/** * @brief DMA UART transmit process complete callback. * @param hdma: DMA handle * @retval None */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) == 0) { huart->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); /* Enable the UART Transmit Complete Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TC); } /* DMA Circular mode */ else { HAL_UART_TxCpltCallback(huart); }}very similar to that lacks the following code fragment:
if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_RX; } else { huart->State = HAL_UART_STATE_READY; }as in
/** * @brief DMA UART receive process complete callback. * @param hdma: DMA handle * @retval None */static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode*/ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) { huart->RxXferCount = 0; /* Disable the DMA transfer for the receiver request by setting the DMAR bit in the UART CR3 register */ huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); /* Check if a transmit process is ongoing or not */ if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_TX; } else { huart->State = HAL_UART_STATE_READY; } } HAL_UART_RxCpltCallback(huart);}2015-11-02 07:14 AM
Hi davydenko.sergey,
Did you face any problem when running this code? Could you please explain the reason for giving your proposal?Kind regards,-Shahrzad-2015-11-04 09:25 AM
Hello Shahrzad
Yes, I have encountered this problem.
When the DMA USART used in normal mode and a data packet sent by the DMA periodically.
Dispatched only the first packet and a single.
HAL_UART_Transmit_DMA (...)All subsequent attempts to send a packet, return status HAL_BUSY.
When sending a packet status is set
huart-> State = HAL_UART_STATE_BUSY_TX_RX
or
huart-> State = HAL_UART_STATE_BUSY_TX
This status after completion of sending must be changed to
HAL_UART_STATE_BUSY_RX
or
HAL_UART_STATE_READY
Otherwise, the next attempt to send the packet does not lead to the desired result.
It is necessary to fix the problem in the procedure
UART_DMATransmitCpltand also the procedure
HAL_UART_TxCpltCallback (huart)It will be carried out only in the case of circular DMA that is not right ...
May be next:static void USER_UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode*/ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) { huart->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the UART CR3 register */ huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); /* Check if a recieve process is ongoing or not */ if(huart->State == HAL_UART_STATE_BUSY_TX_RX) { huart->State = HAL_UART_STATE_BUSY_RX; } else { huart->State = HAL_UART_STATE_READY; } } HAL_UART_TxCpltCallback(huart);}It worked!!!But maybe I'm wrong ...Kind regards,Sergei Davydenko
2016-01-28 06:14 AM
Hi davydenko.sergey,
The issue is already treated by our development team, and modifications will be delivered in next releases of STM32Cube.-Shahrzad-2016-06-08 07:10 AM
Hello Shahrzad
, using the current version of STM32CubeMX 4.15.0 and FWV 1.12.0 the problem is still there (stm32f4xx_hal_uart.c, MCD Application Team, version V1.5.0). I fixed the UART_DMATransmitCplt function in the same way as Sergey did (just replaced huart->state by huart->gstate) ...and DMA transmit works. I wonder what is the intended way to make the ''normal DMA'' mode work from scratch? Or did you just missed to fix this bug in this release? Best regards, Kai2016-06-08 07:24 AM
Hi hofmann.kai,
This is not a bug, but you need to enable the USART handler in the it.c file to handle the transfer complete.You may find more explanation in [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/HAL%20Without%20USART%20interrupt%2c%20HAL_UART_Transmit_DMA%28%29%20will%20work%20only%20once&FolderCTID¤tviews=64]this discussion.-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-06-09 02:36 AM
Hi Mayla,
thank you Mayla, for your fast reply. I read the article, but honestly I do not understand where to enable/realize the handler exactly. Could you please give me some example code? Thanks in advance. Kai2016-06-09 06:37 AM
Hihofmann.kai,
I suggest you refer to any USART example using DMA (Ex:STM32Cube_FW_F4_V1.0\Projects\STM32F4-Discovery\Examples\UART\UART_TwoBoards_ComDMA). You can see that in the file stm32f4xx_it.c we have:/**
* @brief This function handles DMA RX interrupt request. * @param None * @retval None */ voidUSARTx_DMA_RX_IRQHandler(
void)
{ HAL_DMA_IRQHandler(UartHandle.hdmarx); } /** * @brief This function handles DMA TX interrupt request. * @param None * @retval None */ voidUSARTx_DMA_TX_IRQHandler(
void)
{ HAL_DMA_IRQHandler(UartHandle.hdmatx); } /** * @brief This function handles USARTx interrupt request. * @param None * @retval None */void
USARTx_IRQHandler(
void)
{
HAL_UART_IRQHandler(&UartHandle);
}
-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.