Showing results for 
Search instead for 
Did you mean: 

STM32CubeF4 __HAL_UART_CLEAR_FLAG macro is incorrect

Associate III
Posted on May 30, 2014 at 03:43

The STM32CubeF4 __HAL_UART_CLEAR_FLAG( ) macro is incorrect because it does a read-modify-write. If a status bit becomes set in the USART_SR register by the hardware between the read and the write, that change will be lost because the read-modify-write ANDing process will clear any bits that were cleared when the read occurred, clearing any newly set bits as well.

Likewise a similar problem exists with the __HAL_ADC_CLEAR_FLAG( ), __HAL_I2C_CLEAR_FLAG( ), __HAL_SPI_CLEAR_CRCERRFLAG( ), and __HAL_WWDG_CLEAR_FLAG( ).

In the case of the __HAL_SPI_CLEAR_CRCERRFLAG( ) macro, it has a hidden side effect of always clearing the FRE bit during the read step in the read-modify-write process.

These problems were uncovered when investigating a similar problem with the TIMx interrupts.

See: [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/STM32F4xx%20HAL_TIM_IRQHandler%20misses%20interrupts%20on%20nearly%20overlapping%20TIM%20interrupts&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21]STM32F4xx HAL_TIM_IRQHandler misses interrupts on nearly overlapping TIM interrupts


Associate II
Posted on May 30, 2014 at 14:02

I think that is why we should freeze the hardware state by disabling interrupt/dma etc before calling this operation. 

Associate III
Posted on May 30, 2014 at 14:57

No, that does not keep the underlying hardware from changing status bits as conditions occur.

Instead, the following are proposed for these macros:

#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__)   ((__HANDLE__)->Instance->SR = ~(__FLAG__))

#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__)    ((__HANDLE__)->Instance->SR = ~(__FLAG__))

#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__)    ((__HANDLE__)->Instance->SR1 = ~(__FLAG__))

#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__)        ((__HANDLE__)->Instance->SR = ~(SPI_FLAG_CRCERR))

#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__)   ((__HANDLE__)->Instance->SR = ~(__FLAG__))

#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))

The difference is very subtle; ''='' is used instead of ''&='' in the assignment to the status register!

Posted on May 30, 2014 at 17:09


We have already the limitation in the STM32Cube HAL bugs list, and it will be fixed in next releases of F4 (early July) , L0 (e/o June) and F2 (14Q3). This limitation impacts the following HAL drivers: ADC, I2C, SPI, TIM, UART, USART, WWDG.

Thanks for the report.

With regards.