Skip to main content
Nissan Aloni
Associate II
July 15, 2018
Question

Spurious IDLE LINK indication over UART2

  • July 15, 2018
  • 1 reply
  • 1188 views
Posted on July 15, 2018 at 12:35

Hi,

I'm working with STM32L151 and using 2 UART interfaces.

UART1 is configured with IDLE LINK indication and DMA for reception.

UART2 is configured without IDLE LINK indication.

I've used STMCubeMX to generate the HALs.

In the UART IQRHandler i've added the following code:

tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);

if (tmp_flag != RESET) {

   handle_idle_link_interrupt(huart);

}

Here are the first lines of code of 

handle_idle_link_interrupt():

uint8_t uart_id = (huart == &huart1) ? UART_1 : UART;

if (uart_id == UART_2)

{

   g_dbg_idle_link_configured1 = __HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_IDLE);

   g_dbg_idle_link_configured2 = __HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_IDLE);

   assert(0);

}

This code crashes - as can be seen from the above - I'm getting IDLE_LINK indication on UART2.

When i connect with the debugger i see that:

g_dbg_idle_link_configured1 = 0x10

g_dbg_idle_link_configured2 = 0x0

My question is - how come I'm getting IDLE LINK indication on UART2 which is not configured to generate this interrupt?

BTW - I'm not changing configurations on the fly. So this is not a race between configuration and interrupt generation.

Cheers.♯

#uart2-spurious-idle-link
This topic has been closed for replies.

1 reply

Tilen MAJERLE
ST Employee
July 15, 2018
Posted on July 15, 2018 at 13:39

When you handle many different interrupt flags, you have to check if interrupt flag is active and also if you set your flag to trigger interrupt. You have 'Interrupt control register' and 'Interrupt status register'. Both bits for IDLE must be set to 1 if you want to process IDLE interrupt.

IDLE flag is set always, even when interrupt is not enabled. Most probably, some other interrupt flag triggered your USART interrupt.

Nissan Aloni
Associate II
July 15, 2018
Posted on July 15, 2018 at 13:48

Hi TIlen,

Thanks for the quick response.

I didn't understand what you mean...

As far as I understand - CR register is for configuration and SR register shows the status.

When I enable/disable an interrupt - I write to CR1/2/3 using a macro like:

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);

When I get an interrupt - the IRQ handler is called - HAL_UART_IRQHandler()

In it I can check the interrupt cause by reading the SR , using:

__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE);

How can it be that the get flag macro returns something other than 0 when the CR register is not even configured to enable this interrupt?

Thanks again!!!

Tilen MAJERLE
ST Employee
July 15, 2018
Posted on July 15, 2018 at 13:55

Status register always holds actual value, regardless of your interrupt control register. Somebody may check flags outside interrupts, so they must always be valid. Interrupt control register controls which flags may trigger interrupt.

So inside interrupt, you have to check if interrupt was enabled for this flag and if flag itself is set.

Please refer to HAL_UART_IRQHandler function for reference. You will see how it checks control and status bits to determine if interrupt is valid or not.