stm32: fix USART ORE status flag handling

If an USART RX overrun happened on a stm32g0/f0/h7, the ORE flag
would get set by hardware. This flag would also trigger an interrupt.
The problem was that this flag was never cleared on these 3 mcu families
since the ORE flag clear sequence is different to all of the older
chips.
Since the ORE flag is not used in any meaningful way anyway, it was
disabled during the init sequence.

Signed-off-by: Alex Voinea <voinea.dragos.alexandru@gmail.com>
This commit is contained in:
Alex Voinea 2022-10-31 18:03:11 +01:00 committed by KevinOConnor
parent 96ea871b35
commit 26e6ade175
3 changed files with 8 additions and 3 deletions

View File

@ -57,8 +57,11 @@ void
USARTx_IRQHandler(void)
{
uint32_t sr = USARTx->SR;
if (sr & (USART_SR_RXNE | USART_SR_ORE))
if (sr & (USART_SR_RXNE | USART_SR_ORE)) {
// The ORE flag is automatically cleared by reading SR, followed
// by reading DR.
serial_rx_byte(USARTx->DR);
}
if (sr & USART_SR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data;
int ret = serial_get_tx_byte(&data);

View File

@ -66,7 +66,7 @@ void
USARTx_IRQHandler(void)
{
uint32_t sr = USARTx->ISR;
if (sr & (USART_ISR_RXNE | USART_ISR_ORE))
if (sr & USART_ISR_RXNE)
serial_rx_byte(USARTx->RDR);
if (sr & USART_ISR_TXE && USARTx->CR1 & USART_CR1_TXEIE) {
uint8_t data;
@ -93,6 +93,7 @@ serial_init(void)
uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD);
USARTx->BRR = (((div / 16) << USART_BRR_DIV_MANTISSA_Pos)
| ((div % 16) << USART_BRR_DIV_FRACTION_Pos));
USARTx->CR3 = USART_CR3_OVRDIS; // disable the ORE ISR
USARTx->CR1 = CR1_FLAGS;
armcm_enable_irq(USARTx_IRQHandler, USARTx_IRQn, 0);

View File

@ -68,7 +68,7 @@ void
USARTx_IRQHandler(void)
{
uint32_t isr = USARTx->ISR;
if (isr & (USART_ISR_RXNE_RXFNE | USART_ISR_ORE))
if (isr & USART_ISR_RXNE_RXFNE)
serial_rx_byte(USARTx->RDR);
//USART_ISR_TXE_TXFNF only works with Fifo mode disabled
if (isr & USART_ISR_TXE_TXFNF && USARTx->CR1 & USART_CR1_TXEIE) {
@ -96,6 +96,7 @@ serial_init(void)
uint32_t div = DIV_ROUND_CLOSEST(pclk, CONFIG_SERIAL_BAUD);
USARTx->BRR = (((div / 16) << USART_BRR_DIV_MANTISSA_Pos)
| ((div % 16) << USART_BRR_DIV_FRACTION_Pos));
USARTx->CR3 = USART_CR3_OVRDIS; // disable the ORE ISR
USARTx->CR1 = CR1_FLAGS;
armcm_enable_irq(USARTx_IRQHandler, USARTx_IRQn, 0);