cancel
Showing results for 
Search instead for 
Did you mean: 

UART_Start_Receive_IT error when using hardware flow control

gil_dobjanschi
Associate III

Hello,

 

I ran into an issue when testing a UART application on a STM32C562RE in loopback mode with RTS and CTS enabled. The app does the following:

1. Start receiving 1 character at a time by using HAL_UART_Receive_IT.

2. Send a string 

3. After the received character is printed out I issue another call HAL_UART_Receive_IT.

Everything works fine; the app prints out the string I sent.

 

I wanted to make sure the hardware flow control was running correctly so I placed a HAL_Delay(1) after I print out the character received and before I issue a new call  to HAL_UART_Receive_IT. This should stop the transmitter due to the CTS -> 1 (no more room in the Rx buffer) and it should restart it after I issue the HAL_UART_Receive_IT CTS -> 0 due to available room in the Rx buffer; and, it does. All the characters are received as expected however HAL_UART_Receive_IT returns HAL_ERROR. Everything seems normal except the error returned by HAL_UART_Receive_IT.

I debugged the code and it fails in UART_Start_Receive_IT:

  if (huart->rx_state != HAL_UART_RX_STATE_ACTIVE)
  {
    huart->p_rx_isr = NULL;
    return HAL_ERROR;
  }

The rx_state is HAL_UART_RX_STATE_IDLE and therefore the check above fails.

I also enabled 'Get last error' for UART in MX2 and the last_reception_error_codes is 0.

I cannot figure out why HAL_UART_Receive_IT returns an error.

I appreciate the help,

Gil

6 REPLIES 6
Pavel A.
Super User

The rx_state field is assigned HAL_UART_RX_STATE_ACTIVE  here: https://github.com/STMicroelectronics/stm32c5xx-drivers/blob/79b901285a7efeaf87c4c25db81d24cb5d8c9465/hal/stm32c5xx_hal_uart.c#L4534

and the check is here https://github.com/STMicroelectronics/stm32c5xx-drivers/blob/79b901285a7efeaf87c4c25db81d24cb5d8c9465/hal/stm32c5xx_hal_uart.c#L7408

Somewhere between these points the value changes. Try to set a breakpoint on value change in debugger.

 

Hi @Pavel A. 

I traced it to the line before the check: LL_USART_EnableIT_RXNE_RXFNE(p_uartx). 

    if ((reg_temp & USART_CR1_PCE) != LL_USART_PARITY_NONE)
    {
      LL_USART_EnableIT_PE(p_uartx);
    }
    LL_USART_EnableIT_RXNE_RXFNE(p_uartx);
  }

  if (huart->rx_state != HAL_UART_RX_STATE_ACTIVE)
  {
    huart->p_rx_isr = NULL;
    return HAL_ERROR;
  }

 

When I execute the line: LL_USART_EnableIT_RXNE_RXFNE(p_uartx) my interrupt callback is executed (I had a breakpoint on it) and rx_state was set to HAL_UART_RX_STATE_IDLE.

 

Regards,

-Gil

 

Pavel A.
Super User

Aha so there's a race between HAL_UART_Receive_IT and a RX byte arriving and causing interrupt, thus satisfying your request for one byte.

TL;DR using HAL_UART_Receive_IT for anything practical isn't a good idea, especially for receiving bytes one by one. People use a continuous DMA with cyclical buffer, or something equivalent.

 

gil_dobjanschi
Associate III

Thank you for acknowledging the issue @Pavel A.!

 

I am writing a book about STM32 and I develop multiple examples on one topic. I start from the simplest scenario and advance to practical ones. This is why I was testing this mode.

 

Regards,

Gil

@gil_dobjanschi A book? could you tell something on the idea - is it about practical projects based on STM32? If so, which STM32 type (CM0, CM7? CM33), which kind of applications, do you use any RTOS and HMI?

gil_dobjanschi
Associate III

Hi @Pavel A. 

 

Yes, it is a book about practical projects for Nucleo-C562RE. I thought that the C5 series presents an opportunity to write about STM32CubeMX2 and use HAL2. The examples will be in C and will not use RTOS. RTOS is reserved for a followup book should the first one be interesting to readers. For the first book the intended audience is the experienced C programmers that wants to get into STM32 and learn its capabilities and programming techniques. I want to present interesting examples and explain behavior and visualize it for readers with the use of the oscilloscope. I will not write chapters about C programming and elementary embedded programming. 

I only started two months ago and I have a long road ahead. It's a lot of work to write the code, write the chapters, develop hardware that speeds up switching between projects and keep the quality of the material high. As I work on the book I learn new things, sometimes I find minor issues in HAL but that's what keeps it interesting.

 

Regards,

-Gil