Skip to main content
noobmaster69
Associate III
May 6, 2022
Question

USART2_IRQHandler called continuously for DMA reception on STM32L031K6T6 with hardware flow control

  • May 6, 2022
  • 6 replies
  • 2616 views

Hi. I am using UART with DMA for TX and RX on STM32L031. It communicates with nRF52833 over UART with hwfc enabled. My problem is, when I receive data from nRF52, USART2_IRQHandler is called continuously. Below is the screenshot of all the flags that are set. Transmission from ST to Nordic works properly(tested 65535+ times). I receive around 3 data packets from nordic to ST and then the communication stops because USART2_IRQHandler is called contiuously. Why is this happening? Is there any workaroound for this? I am using STM32CubeIDE and HAL libraries on linux.

(NOTE: without HWFC it was working properly but for more reliabilty, I need HWFC. It so happend that Nrodic would drop data packets whenever it was busy transmitting bluetooth beacon)

Below is the debug log from Nordic. You can see that CTS pin is toggling continuously.

<info> app: NRF_UARTE_EVENT_CTS...
<info> app_timer: RTC: initialized.
<info> app: Debug logging for UART over RTT started.
<info> app: NRF_UARTE_EVENT_RXSTARTED...
<info> app: tx_data[0] = 01
<info> app: EVT:NRF_UARTE_EVENT_TXSTARTED
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: tx_data[0] = 02
<info> app: EVT:NRF_UARTE_EVENT_TXSTARTED
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: tx_data[0] = 03
<info> app: EVT:NRF_UARTE_EVENT_TXSTARTED
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...
<info> app: NRF_UARTE_EVENT_CTS...
<info> app: NRF_UARTE_EVENT_NCTS...

This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
May 6, 2022

Suggests you're not servicing the source of the interrupt.

For example TXE, but not providing data​, or restarting DMA.

The UART typically has little internal buffering, so in flow control might help to monitor that before cramming more data across interface.​

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
noobmaster69
Associate III
May 6, 2022

I tried clearing all the flags which were set using the following code. But no success.

	if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_REACK) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_REACK);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TEACK) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TEACK);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_CTS) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_CTS);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_CTSIF) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_CTSIF);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TXE);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TC) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TC);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_RXNE);
	}
	else if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) == SET)
	{
		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_IDLE);
	}

Guenael Cadier
ST Employee
May 6, 2022

Dear @Community member​ 

In your attempt to clear all flags that could raise continuous USART2 IRQ, please note that some flags could not be cleared using __HAL_UART_GET_FLAG macro.

Examples :

RXNE flag is cleared by reading RDR register

TXE flag is cleared by writing some data in TDR register.

For getting a continuous interrupt, you must have a flag set in ICR, AND corresponding Interrupt Enable bit set in CRx registers.

What you could check is which flag is set in your ICR that corresponds to an enabled interrupt in CR1/CR2/CR3.

Example : having RXNE flag and RXNEIE both set.

Regards