summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-13 20:16:07 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-13 20:16:07 +0000
commit91ae30d69e0b1cfa5e5758d10776b06fc88ff5cc (patch)
tree8879762793e2677725bd24c1ecd2fcc4267c883a
parentadffccfe23e60bbe39b71a0011dfd1726c44102a (diff)
downloadnuttx-91ae30d69e0b1cfa5e5758d10776b06fc88ff5cc.tar.gz
nuttx-91ae30d69e0b1cfa5e5758d10776b06fc88ff5cc.tar.bz2
nuttx-91ae30d69e0b1cfa5e5758d10776b06fc88ff5cc.zip
Fix some hanlding of TIE and RIE interrupt
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1224 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/sh/src/sh1/sh1_serial.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/nuttx/arch/sh/src/sh1/sh1_serial.c b/nuttx/arch/sh/src/sh1/sh1_serial.c
index 4fb501053..d6708d5fa 100644
--- a/nuttx/arch/sh/src/sh1/sh1_serial.c
+++ b/nuttx/arch/sh/src/sh1/sh1_serial.c
@@ -562,8 +562,6 @@ static int up_interrupt(int irq, void *context)
{
struct uart_dev_s *dev = NULL;
struct up_dev_s *priv;
- int passes;
- boolean handled;
#ifdef CONFIG_SH1_SCI0
if ((irq >= g_sci0priv.irq) &&
@@ -586,18 +584,18 @@ static int up_interrupt(int irq, void *context)
}
priv = (struct up_dev_s*)dev->priv;
- /* Loop until there are no characters to be transferred or,
- * until we have been looping for a long time.
- */
-
- for (passes = 0, handled = TRUE; passes < 256 && handled; passes++)
- {
- handled = FALSE;
+ /* Get the current SCI status */
- /* Get the current SCI status */
+ priv->ssr = up_serialin(priv, SH1_SCI_SSR_OFFSET);
- priv->ssr = up_serialin(priv, SH1_SCI_SSR_OFFSET);
+ /* Handle receive-related events with RIE is enabled. RIE is enabled at
+ * times that driver is open EXCEPT when the driver is actively copying
+ * data from the circular buffer. In that case, the read events must
+ * pend until RIE is set
+ */
+ if ((priv->scr & SH1_SCISCR_RIE) != 0)
+ {
/* Handle incoming, receive bytes (RDRF: Receive Data Register Full) */
if ((priv->ssr & SH1_SCISSR_RDRF) != 0)
@@ -605,29 +603,38 @@ static int up_interrupt(int irq, void *context)
/* Rx data register not empty ... process incoming bytes */
uart_recvchars(dev);
- handled = TRUE;
}
- /* Handle outgoing, transmit bytes (TDRE: Transmit Data Register Empty) */
+ /* Clear all read related events (probably already done in up_receive)) */
- if ((priv->ssr & SH1_SCISSR_TDRE) != 0)
- {
- /* Tx data register empty ... process outgoing bytes */
+ priv->ssr &= ~(SH1_SCISSR_RDRF|SH1_SCISSR_ORER|SH1_SCISSR_FER|SH1_SCISSR_PER);
+ }
- uart_xmitchars(dev);
- handled = TRUE;
- }
+ /* Handle outgoing, transmit bytes (TDRE: Transmit Data Register Empty)
+ * when TIE is enabled. TIE is only enabled when the driver is waiting with
+ * buffered data. Since TDRE is usually true,
+ */
- /* Clear all (clear-able) status flags. Note that that SH-1 requires
- * that you read the bit in the "1" then write "0" to the bit in order
- * to clear it. Any bits in the SSR that transitioned from 0->1 will
- * not be effected by the following:
- */
+ if ((priv->ssr & SH1_SCISSR_TDRE) != 0 && (priv->scr & SH1_SCISCR_TIE) != 0)
+ {
+ /* Tx data register empty ... process outgoing bytes */
+
+ uart_xmitchars(dev);
- priv->ssr &= ~(SH1_SCISSR_TDRE|SH1_SCISSR_RDRF|SH1_SCISSR_ORER|\
- SH1_SCISSR_FER|SH1_SCISSR_PER|SH1_SCISSR_TEND);
- up_serialout(priv, SH1_SCI_SSR_OFFSET, priv->ssr);
+ /* Clear the TDR empty flag (Possibly done in up_send, will have not
+ * effect if the TDR is still empty)
+ */
+
+ priv->ssr &= ~SH1_SCISSR_TDRE;
}
+
+ /* Clear all (clear-able) status flags. Note that that SH-1 requires
+ * that you read the bit in the "1" then write "0" to the bit in order
+ * to clear it. Any bits in the SSR that transitioned from 0->1 after
+ * we read the SR will not be effected by the following:
+ */
+
+ up_serialout(priv, SH1_SCI_SSR_OFFSET, priv->ssr);
return OK;
}