cancel
Showing results for 
Search instead for 
Did you mean: 

Spurious IDLE LINK indication over UART2

Nissan Aloni
Associate II
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
4 REPLIES 4
Tilen MAJERLE
ST Employee
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.

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!!!

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.

Posted on July 15, 2018 at 13:58

Ok, I think now I understand.

Status register is unmasked. I assumed that it is masked by the configuration register.

So the status is the raw interrupt. And the configuration is used as a 'SW mask' inside the IRQ.