From 9d19282875e3b89596135984bb30c11589c418b8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 22 Nov 2013 10:19:47 +0000 Subject: [PATCH] Fixed bug #442. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6503 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/USARTv1/serial_lld.c | 23 +++++++++++---------- os/hal/platforms/STM32/USARTv2/serial_lld.c | 4 ++++ readme.txt | 2 ++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/os/hal/platforms/STM32/USARTv1/serial_lld.c b/os/hal/platforms/STM32/USARTv1/serial_lld.c index a8333bf77..9a9596424 100644 --- a/os/hal/platforms/STM32/USARTv1/serial_lld.c +++ b/os/hal/platforms/STM32/USARTv1/serial_lld.c @@ -143,9 +143,7 @@ static void set_error(SerialDriver *sdp, uint16_t sr) { sts |= SD_FRAMING_ERROR; if (sr & USART_SR_NE) sts |= SD_NOISE_ERROR; - chSysLockFromIsr(); chnAddFlagsI(sdp, sts); - chSysUnlockFromIsr(); } /** @@ -156,12 +154,8 @@ static void set_error(SerialDriver *sdp, uint16_t sr) { static void serve_interrupt(SerialDriver *sdp) { USART_TypeDef *u = sdp->usart; uint16_t cr1 = u->CR1; - uint16_t sr = u->SR; /* SR reset step 1.*/ - uint16_t dr = u->DR; /* SR reset step 2.*/ + uint16_t sr = u->SR; - /* Error condition detection.*/ - if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) - set_error(sdp, sr); /* Special case, LIN break detection.*/ if (sr & USART_SR_LBD) { chSysLockFromIsr(); @@ -169,12 +163,18 @@ static void serve_interrupt(SerialDriver *sdp) { chSysUnlockFromIsr(); u->SR &= ~USART_SR_LBD; } + /* Data available.*/ - if (sr & USART_SR_RXNE) { - chSysLockFromIsr(); - sdIncomingDataI(sdp, (uint8_t)dr); - chSysUnlockFromIsr(); + chSysLockFromIsr(); + while (sr & USART_SR_RXNE) { + /* Error condition detection.*/ + if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) + set_error(sdp, sr); + sdIncomingDataI(sdp, u->DR); + sr = u->SR; } + chSysUnlockFromIsr(); + /* Transmission buffer empty.*/ if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { msg_t b; @@ -188,6 +188,7 @@ static void serve_interrupt(SerialDriver *sdp) { u->DR = b; chSysUnlockFromIsr(); } + /* Physical transmission end.*/ if (sr & USART_SR_TC) { chSysLockFromIsr(); diff --git a/os/hal/platforms/STM32/USARTv2/serial_lld.c b/os/hal/platforms/STM32/USARTv2/serial_lld.c index 5209c499b..44f02af1d 100644 --- a/os/hal/platforms/STM32/USARTv2/serial_lld.c +++ b/os/hal/platforms/STM32/USARTv2/serial_lld.c @@ -156,18 +156,21 @@ static void serve_interrupt(SerialDriver *sdp) { /* Error condition detection.*/ if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE)) set_error(sdp, isr); + /* Special case, LIN break detection.*/ if (isr & USART_ISR_LBD) { chSysLockFromIsr(); chnAddFlagsI(sdp, SD_BREAK_DETECTED); chSysUnlockFromIsr(); } + /* Data available.*/ if (isr & USART_ISR_RXNE) { chSysLockFromIsr(); sdIncomingDataI(sdp, (uint8_t)u->RDR); chSysUnlockFromIsr(); } + /* Transmission buffer empty.*/ if ((cr1 & USART_CR1_TXEIE) && (isr & USART_ISR_TXE)) { msg_t b; @@ -181,6 +184,7 @@ static void serve_interrupt(SerialDriver *sdp) { u->TDR = b; chSysUnlockFromIsr(); } + /* Physical transmission end.*/ if (isr & USART_ISR_TC) { chSysLockFromIsr(); diff --git a/readme.txt b/readme.txt index b9f820337..89dcc9460 100644 --- a/readme.txt +++ b/readme.txt @@ -89,6 +89,8 @@ ***************************************************************************** *** 2.7.0 *** +- FIX: Fixed lost incoming characters in STM32 USARTv1 driver (bug #442) + (backported to 2.4.6 and 2.6.2). - FIX: Fixed UART4/5-related bugs in STM32 USARTv1 UART driver (bug #440) (backported to 2.6.2). - FIX: Fixed race condition in STM32 DMA interrupt (bug #439)(backported