aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Voinea <voinea.dragos.alexandru@gmail.com>2022-10-31 18:03:11 +0100
committerKevinOConnor <kevin@koconnor.net>2022-10-31 13:50:15 -0400
commit26e6ade1757e20ce3a1253c4c4d0a915960a38d8 (patch)
treec7ee1c259cb4eaaf21cb5a809a5fb884666c4239 /src
parent96ea871b355d69ae00220d14c3a9f9c4b8754337 (diff)
downloadkutter-26e6ade1757e20ce3a1253c4c4d0a915960a38d8.tar.gz
kutter-26e6ade1757e20ce3a1253c4c4d0a915960a38d8.tar.xz
kutter-26e6ade1757e20ce3a1253c4c4d0a915960a38d8.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/stm32/serial.c5
-rw-r--r--src/stm32/stm32f0_serial.c3
-rw-r--r--src/stm32/stm32h7_serial.c3
3 files changed, 8 insertions, 3 deletions
diff --git a/src/stm32/serial.c b/src/stm32/serial.c
index 5806eaab..19aa048e 100644
--- a/src/stm32/serial.c
+++ b/src/stm32/serial.c
@@ -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);
diff --git a/src/stm32/stm32f0_serial.c b/src/stm32/stm32f0_serial.c
index c214ed01..da76be42 100644
--- a/src/stm32/stm32f0_serial.c
+++ b/src/stm32/stm32f0_serial.c
@@ -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);
diff --git a/src/stm32/stm32h7_serial.c b/src/stm32/stm32h7_serial.c
index 1cb93e9b..b5070290 100644
--- a/src/stm32/stm32h7_serial.c
+++ b/src/stm32/stm32h7_serial.c
@@ -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);