From 9d19282875e3b89596135984bb30c11589c418b8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 22 Nov 2013 10:19:47 +0000 Subject: 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 ++++ 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'os') 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(); -- cgit v1.2.3