summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/stm32/stm32_serial.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-02 01:02:41 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-02 01:02:41 +0000
commitdd4f93db606a1360efef7b59a97bd4a0bd8c6ad0 (patch)
tree09af0046e3d702c013359820c0115c36e370bdb6 /nuttx/arch/arm/src/stm32/stm32_serial.c
parent67a850ba575659cb195e67aa8357a70dece9c418 (diff)
downloadpx4-nuttx-dd4f93db606a1360efef7b59a97bd4a0bd8c6ad0.tar.gz
px4-nuttx-dd4f93db606a1360efef7b59a97bd4a0bd8c6ad0.tar.bz2
px4-nuttx-dd4f93db606a1360efef7b59a97bd4a0bd8c6ad0.zip
A couple of fixes to common and STM32 serial handling to fix some data overrun conditions
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4550 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_serial.c')
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_serial.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_serial.c b/nuttx/arch/arm/src/stm32/stm32_serial.c
index de918efbe..680a77216 100644
--- a/nuttx/arch/arm/src/stm32/stm32_serial.c
+++ b/nuttx/arch/arm/src/stm32/stm32_serial.c
@@ -799,8 +799,8 @@ static void up_detach(struct uart_dev_s *dev)
static int up_interrupt_common(struct up_dev_s *priv)
{
- int passes;
- bool handled;
+ int passes;
+ bool handled;
/* Loop until there are no characters to be transferred or,
* until we have been looping for a long time.
@@ -811,7 +811,7 @@ static int up_interrupt_common(struct up_dev_s *priv)
{
handled = false;
- /* Get the masked USART status and clear the pending interrupts. */
+ /* Get the masked USART status word. */
priv->sr = up_serialin(priv, STM32_USART_SR_OFFSET);
@@ -837,16 +837,35 @@ static int up_interrupt_common(struct up_dev_s *priv)
* being used.
*/
- /* Handle incoming, receive bytes (with or without timeout) */
+ /* Handle incoming, receive bytes. */
if ((priv->sr & USART_SR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0)
{
- /* Received data ready... process incoming bytes */
+ /* Received data ready... process incoming bytes. NOTE the check for
+ * RXNEIE: We cannot call uart_recvchards of RX interrupts are disabled.
+ */
uart_recvchars(&priv->dev);
handled = true;
}
+ /* We may still have to read from the DR register to clear any pending
+ * error conditions.
+ */
+
+ else if ((priv->sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE)) != 0)
+ {
+ /* If an error occurs, read from DR to clear the error (data has
+ * been lost). If ORE is set along with RXNE then it tells you
+ * that the byte *after* the one in the data register has been
+ * lost, but the data register value is correct. That case will
+ * be handled above if interrupts are enabled. Otherwise, that
+ * good byte will be lost.
+ */
+
+ (void)up_serialin(priv, STM32_USART_DR_OFFSET);
+ }
+
/* Handle outgoing, transmit bytes */
if ((priv->sr & USART_SR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0)
@@ -962,23 +981,25 @@ static int up_receive(struct uart_dev_s *dev, uint32_t *status)
static void up_rxint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
+ irqstate_t flags;
uint16_t ie;
- /* USART receive interrupts:
- *
- * Enable Bit Status Meaning Usage
- * ------------------ --- --------------- ------------------------------- ----------
- * USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
- * USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
- * " " USART_SR_ORE Overrun Error Detected
- * USART_CR1_PEIE 8 USART_SR_PE Parity Error
- *
- * USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
- * USART_CR3_EIE 0 USART_SR_FE Framing Error
- * " " USART_SR_NE Noise Error
- * " " USART_SR_ORE Overrun Error Detected
- */
+ /* USART receive interrupts:
+ *
+ * Enable Bit Status Meaning Usage
+ * ------------------ --- --------------- ------------------------------- ----------
+ * USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
+ * USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
+ * " " USART_SR_ORE Overrun Error Detected
+ * USART_CR1_PEIE 8 USART_SR_PE Parity Error
+ *
+ * USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
+ * USART_CR3_EIE 0 USART_SR_FE Framing Error
+ * " " USART_SR_NE Noise Error
+ * " " USART_SR_ORE Overrun Error Detected
+ */
+ flags = irqsave();
ie = priv->ie;
if (enable)
{
@@ -1002,6 +1023,7 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
/* Then set the new interrupt state */
up_restoreusartint(priv, ie);
+ irqrestore(flags);
}
/****************************************************************************