2014-05-29 06:43 PM
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 #stm32cubef42014-05-30 05:02 AM
I think that is why we should freeze the hardware state by disabling interrupt/dma etc before calling this operation.
2014-05-30 05:57 AM
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!2014-05-30 08:09 AM
Hi,
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.