cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in USART_GetITStatus() re/ USART_IT_ORE?

alexandre
Associate
Posted on June 18, 2014 at 20:24

Could someone please confirm the following issue ?

, p.706/914 states that:

''ORE: Overrun error (...) An interrupt is generated if RXNEIE=1 or EIE = 1 in the USARTx_CR1 register.''

The hardware indeed appears to work that way, as I do indeed get ORE interrupts when only RXNEIE is enabled.

Now, in stm32f0xx_usart.c/.h:

since USART_IT_ORE is defined as 0x00030300, USART_GetITStatus() gets its itmask from USARTx->CR3, bit 0 (which corresponds to EIE).

Therefore, contrary to what is stated in the documentation, RXNEIE is never checked, and USART_GetITStatus(..., USART_IT_ORE) will always return RESET when called from an ISR triggered by an ORE condition while EIE is disabled, even if RXNEIE is enabled.

Now, if EIE=0 and RXNEIE=1, this is a big problem if USART_GetITStatus(..., USART_IT_ORE) is used to detect and reset the pending ORE interrupt: it will never catch the interrupt condition and the ISR will keep being called, freezing the MCU.

I believe this is the problem being encountered in the following threads:

- [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/USART%20ORE%3D1%2c%20but%20RXNE%3D0&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1049]thread 1

- [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/two%20usart%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=3891]thread 2
4 REPLIES 4
thln47
Associate III
Posted on September 01, 2014 at 14:37

Hello, I'm working on a STM32F303, and I also found this bug in the library ST version V1.0.1.

Actually the USART_GetITStatus(USARTx, USART_IT_ORE) routine does not detect the flag of the overrun.

This flag is never cleared.

This has the effect of to loop permanently in the IRQ.

printf(''USART_IT_ORE:'');

if (USART_GetITStatus(USARTx, USART_IT_ORE) != RESET)

  {

    printf(''Yes'');

    USART_ClearITPendingBit(USARTx, USART_IT_ORE);

    /* mon traitement */

  }

printf(''\n'');

I modified my code as below to validated dectection the overrun:

if ((USARTx->ISR & 0x8)!=0)

    {

    USARTx->ICR |= 0x8;    

    /* mon traitement */

    }

Otherwise modifying the following definition in the stm32f30x_usart.h file, it works.

//#define USART_IT_ORE                         ((uint32_t)0x00030300)

#define USART_IT_ORE                         ((uint32_t)0x00030105)

Indeed, if EIE=0 and RXNEIE=1, the test is not performed on the right interrupt enable flag!

 

It seems that ST saw the problem on st32f4xx_usart library, and they defined the two cases:

#define USART_IT_ORE_RX                      ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */

and

#define USART_IT_ORE_ER                      ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */

Looking at these definitions, we can easily correct the problem:

#define USART_IT_ORE_ER                      ((uint32_t)0x00030300)

#define USART_IT_ORE_RX                      ((uint32_t)0x00030105)

printf(''USART_IT_ORE:'');

if (USART_GetITStatus(USARTx, USART_IT_ORE_RX) != RESET)

  {

    printf(''Yes'');

    USART_ClearITPendingBit(USARTx, USART_IT_ORE_RX);

    /* mon traitement */

  }

printf(''\n'');

Hoping that ST fixes the problem and provide a new revision of their library!

Sorry for my poor English ;)

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/two%20usart%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=3891]

Juozas_k_g
Associate
Posted on September 06, 2014 at 09:04

The post is very useful - thank you.

On my STM32F051 :

not working:

if (USART_GetFlagStatus(USART1, USART_IT_ORE) != RESET)

    {

                USART_ClearFlag(USART1, USART_IT_ORE);

    }

good working:

        if ((USART1->ISR & 0x8)!=0)

            {

                USART1->ICR |= 0x8;

            }

Posted on September 09, 2014 at 13:06

Hi raymond.alexandre,

After discussion with development team, it turned out that this behavior is confirmed. Thus the ORE interrupt is generated only if the EIE interrupt is enabled (not when RXNEIE interrupt)

Thanks for the feedback.

Regards.

Posted on September 30, 2014 at 09:29

> After discussion with development team, it turned out that this behavior is confirmed.

> Thus the ORE interrupt is generated only if the EIE interrupt is enabled (not when RXNEIE interrupt)

IMO, Alexandre said exactly the opposite:

> The hardware indeed appears to work that way, as I do indeed get ORE interrupts when only RXNEIE is enabled.

So, can you please go back to your development team and ask them, which one of these is true?

JW

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/two%20usart%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=3891]