AnsweredAssumed Answered

STM32 HAL UART Driver

Question asked by g.martin on Mar 16, 2015
Working with the STM32F439 UART and originally used DMA for TX and RX, and that was working.  For other reasons I wanted to change RX to use interrupt, and I had difficulty getting it to work...  I got things working by changing the HAL driver, but I am not sure if the fix is valid.

01.static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
02.{
03.  uint16_t* tmp;
04.  uint32_t tmp1 = 0;
05.    
06.  tmp1 = huart->State; 
07.  if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))
08.  {
09.    if(huart->Init.WordLength == UART_WORDLENGTH_9B)
10.    {
11.      tmp = (uint16_t*) huart->pRxBuffPtr;
12.      if(huart->Init.Parity == UART_PARITY_NONE)
13.      {
14.        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
15.        huart->pRxBuffPtr += 2;
16.      }
17.      else
18.      {
19.        *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
20.        huart->pRxBuffPtr += 1;
21.      }
22.    }
23.    else
24.    {
25.      if(huart->Init.Parity == UART_PARITY_NONE)
26.      {
27.        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
28.      }
29.      else
30.      {
31.        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
32.      }
33.    }
At line 7, the state of the UART is checked, and I think this logic is inverted.  The state is checked if the RX is BUSY, and in the case of the current code, if the RX is busy, it starts copying bytes from the receive register.  Whereas if the RX is not BUSY, this function returns HAL_BUSY (not shown in the snippet).

The list of states and their meanings.
1.HAL_UART_STATE_RESET             = 0x00,    /*!< Peripheral is not yet Initialized                  */
2.HAL_UART_STATE_READY             = 0x01,    /*!< Peripheral Initialized and ready for use           */
3.HAL_UART_STATE_BUSY              = 0x02,    /*!< an internal process is ongoing                     */   
4.HAL_UART_STATE_BUSY_TX           = 0x12,    /*!< Data Transmission process is ongoing               */ 
5.HAL_UART_STATE_BUSY_RX           = 0x22,    /*!< Data Reception process is ongoing                  */
6.HAL_UART_STATE_BUSY_TX_RX        = 0x32,    /*!< Data Transmission and Reception process is ongoing */  
7.HAL_UART_STATE_TIMEOUT           = 0x03,    /*!< Timeout state                                      */
8.HAL_UART_STATE_ERROR             = 0x04     /*!< Error                                              */

When I invert the logic of the if() on line 7, single wire mode works.  All other modes work with line as original.  Has anybody else tried single wire mode?

I assume the UART driver is pretty stable by now, so I assume I have got something else wrong...

Outcomes