summaryrefslogtreecommitdiff
path: root/nuttx/arch/z16/src/z16f
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-01-28 02:07:33 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-01-28 02:07:33 +0000
commitbcf2f7469abf0d42552c2c744bf988639515c83d (patch)
treed592c2f0f0003d13369e0e87f6e1ce73fdc181f4 /nuttx/arch/z16/src/z16f
parent53cb9f23346c4969c5d9cc30de45840391ce5d78 (diff)
downloadpx4-nuttx-bcf2f7469abf0d42552c2c744bf988639515c83d.tar.gz
px4-nuttx-bcf2f7469abf0d42552c2c744bf988639515c83d.tar.bz2
px4-nuttx-bcf2f7469abf0d42552c2c744bf988639515c83d.zip
Code complete
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@572 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/z16/src/z16f')
-rw-r--r--nuttx/arch/z16/src/z16f/z16f_serial.c192
1 files changed, 112 insertions, 80 deletions
diff --git a/nuttx/arch/z16/src/z16f/z16f_serial.c b/nuttx/arch/z16/src/z16f/z16f_serial.c
index 80292c03b..38d7492af 100644
--- a/nuttx/arch/z16/src/z16f/z16f_serial.c
+++ b/nuttx/arch/z16/src/z16f/z16f_serial.c
@@ -94,7 +94,8 @@ static int z16f_setup(struct uart_dev_s *dev);
static void z16f_shutdown(struct uart_dev_s *dev);
static int z16f_attach(struct uart_dev_s *dev);
static void z16f_detach(struct uart_dev_s *dev);
-static int z16f_interrupt(int irq, void *context);
+static int z16f_rxinterrupt(int irq, void *context);
+static int z16f_txinterrupt(int irq, void *context);
static int z16f_ioctl(struct file *filep, int cmd, unsigned long arg);
static int z16f_receive(struct uart_dev_s *dev, uint32 *status);
static void z16f_rxint(struct uart_dev_s *dev, boolean enable);
@@ -195,7 +196,7 @@ static uart_dev_t g_uart1port =
0, /* open_count */
FALSE, /* xmitwaiting */
FALSE, /* recvwaiting */
-#ifdef CONFIG_UART0_SERIAL_CONSOLE
+#ifdef CONFIG_UART1_SERIAL_CONSOLE
TRUE, /* isconsole */
#else
FALSE, /* isconsole */
@@ -238,44 +239,49 @@ static uart_dev_t g_uart1port =
****************************************************************************/
/****************************************************************************
- * Name: z16f_serialout
+ * Name: z16f_disableuartirq
****************************************************************************/
-static void z16f_serialout(struct z16f_uart_s *priv, int offset, ubyte value)
+static ubyte z16f_disableuartirq(struct uart_dev_s *dev)
{
- putreg8(value, priv->uartbase + offset);
-}
+ struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
+ irqstate_t flags = irqsave();
+ ubyte state = priv->rxdisabed ? 0 : 1 | priv->txdisabled ? 0 : 2;
-/****************************************************************************
- * Name: z16f_disableuartirq
- ****************************************************************************/
+ z16f_txint(dev, FALSE);
+ z16f_rxint(dev, FALSE);
-static ubyte z16f_disableuartirq(struct z16f_uart_s *priv)
-{
-/* REVISIT */
- return 0;
+ irqrestore(flags);
+ return state;
}
/****************************************************************************
* Name: z16f_restoreuartirq
****************************************************************************/
-static void z16f_restoreuartirq(struct z16f_uart_s *priv, ubyte state)
+static void z16f_restoreuartirq(struct uart_dev_s *dev, ubyte state)
{
-/* REVISIT */
+ struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
+ irqstate_t flags = irqsave();
+
+ z16f_txint(dev, (state & 2) ? TRUE : FALSE);
+ z16f_rxint(dev, (state & 1) ? TRUE : FALSE);
+
+ irqrestore(flags);
+ return state;
}
/****************************************************************************
- * Name: z16f_waittrde
+ * Name: z16f_waittx
****************************************************************************/
-static void z16f_waittrde(struct z16f_uart_s *priv)
+static void z16f_waittx(struct z16f_uart_s *priv, void (*status)(struct z16f_uart_s *))
{
int tmp;
for (tmp = 1000 ; tmp > 0 ; tmp--)
{
- if ((getreg8(priv->uartbase + Z16F_UART_STAT0) & Z16F_UARTSTAT0_TDRE) != 0)
+ if (status(priv) != 0)
{
break;
}
@@ -299,7 +305,6 @@ static int z16f_setup(struct uart_dev_s *dev)
ubyte ctl0;
ubyte ctl1;
-
/* Calculate and set the baud rate generation register.
* BRG = (freq + baud * 8)/(baud * 16)
*/
@@ -349,7 +354,7 @@ static int z16f_setup(struct uart_dev_s *dev)
static void z16f_shutdown(struct uart_dev_s *dev)
{
struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
- (void)z16f_disableuartirq(priv);
+ (void)z16f_disableuartirq(dev);
}
/****************************************************************************
@@ -415,32 +420,25 @@ static void z16f_detach(struct uart_dev_s *dev)
}
/****************************************************************************
- * Name: z16f_interrupt
+ * Name: z16f_rxinterrupt
*
* Description:
- * This is the UART interrupt handler. It will be invoked
- * when an interrupt received on the 'irq' It should call
- * uart_transmitchars or uart_receivechar to perform the
- * appropriate data transfers. The interrupt handling logic\
- * must be able to map the 'irq' number into the approprite
- * uart_dev_s structure in order to call these functions.
+ * This is the UART interrupt handler. It will be invoked when an RX
+ * event occurs at the Z16F's LIN-UART.
*
****************************************************************************/
-static int z16f_interrupt(int irq, void *context)
+static int z16f_rxinterrupt(int irq, void *context)
{
struct uart_dev_s *dev = NULL;
struct z16f_uart_s *priv;
ubyte status;
- int passes;
-
-/* REVISIT */
- if (g_uart1priv.txirq == irq || g_uart1priv.rxirq == irq)
+ if (g_uart1priv.rxirq == irq)
{
dev = &g_uart1port;
}
- else if (g_uart0priv.txirq == irq || g_uart0priv.rxirq == irq)
+ else if (g_uart0priv.rxirq == irq)
{
dev = &g_uart0port;
}
@@ -451,42 +449,62 @@ static int z16f_interrupt(int irq, void *context)
priv = (struct z16f_uart_s*)dev->priv;
- /* Loop while there is something to do */
+ /* Check the LIN-UART status 0 register to determine whether the source of
+ * the interrupt is error, break, or received data
+ */
+
+ status = getreg8(priv->uartbase + Z16F_UART_STAT0);
+
+ /* REVISIT error and break handling */
+
+ /* Check if received data is available */
- for (;;)
+ if (status & Z16F_UARTSTAT0_RDA)
{
- /* Get the current UART status */
+ /* Handline an incoming, receive byte */
- status = getreg8(priv->uartbase + Z16F_UART_STAT0);
- if ((status & (Z16F_UARTSTAT0_RDA|Z16F_UARTSTAT0_TDRE)) == 0)
- {
- break;
- }
- else
- {
- /* Handline incoming, receive bytes */
+ uart_recvchars(dev);
+ }
+}
+
+/****************************************************************************
+ * Name: z16f_txinterrupt
+ *
+ * Description:
+ * This is the UART TX interrupt handler. This interrupt handler will
+ * be invoked when the X16F LIN UART transmit data register is empty.
+ *
+ ****************************************************************************/
+
+static int z16f_txinterrupt(int irq, void *context)
+{
+ struct uart_dev_s *dev = NULL;
+ struct z16f_uart_s *priv;
+ ubyte status;
- if (status & Z16F_UARTSTAT0_RDA)
- {
- uart_recvchars(dev);
- }
+ if (g_uart1priv.txirq == irq)
+ {
+ dev = &g_uart1port;
+ }
+ else if (g_uart0priv.txirq == irq)
+ {
+ dev = &g_uart0port;
+ }
+ else
+ {
+ PANIC(OSERR_INTERNAL);
+ }
- /* Handle outgoing, transmit bytes */
+ priv = (struct z16f_uart_s*)dev->priv;
- if (status & Z16F_UARTSTAT0_TDRE)
- {
- uart_xmitchars(dev);
- }
+ /* Verify that the transmit data register is empty */
- /* Keep track of how many times we do this in case there
- * is some hardware failure condition.
- */
+ status = getreg8(priv->uartbase + Z16F_UART_STAT0);
+ if (status & Z16F_UARTSTAT0_TDRE)
+ {
+ /* Handle outgoing, transmit bytes */
- if (++passes > 256)
- {
- break;
- }
- }
+ uart_xmitchars(dev);
}
}
@@ -536,9 +554,9 @@ static int z16f_receive(struct uart_dev_s *dev, uint32 *status)
static void z16f_rxint(struct uart_dev_s *dev, boolean enable)
{
- struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
-/* REVISIT */
-#if 0
+ struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
+ irqstate_t flags = irqsave();
+
if (enable)
{
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
@@ -550,6 +568,9 @@ static void z16f_rxint(struct uart_dev_s *dev, boolean enable)
up_disable_irq(priv->rxirq);
}
#endif
+
+ priv->rxenable = enable;
+ irqrestore(flags);
}
/****************************************************************************
@@ -590,9 +611,9 @@ static void z16f_send(struct uart_dev_s *dev, int ch)
static void z16f_txint(struct uart_dev_s *dev, boolean enable)
{
- struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
-/* REVISIT */
-#if 0
+ struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;
+ irqstate_t flags = irqsave();
+
if (enable)
{
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
@@ -603,7 +624,9 @@ static void z16f_txint(struct uart_dev_s *dev, boolean enable)
{
up_disable_irq(priv->txirq);
}
-#endif
+
+ priv->txenable = enable;
+ irqrestore(flags);
}
/****************************************************************************
@@ -639,7 +662,7 @@ static boolean z16f_txempty(struct uart_dev_s *dev)
****************************************************************************/
/****************************************************************************
- * Name: z16f_serialinit
+ * Name: up_earlyserialinit
*
* Description:
* Performs the low level UART initialization early in
@@ -650,8 +673,8 @@ static boolean z16f_txempty(struct uart_dev_s *dev)
void up_earlyserialinit(void)
{
- (void)z16f_disableuartirq(TTYS0_DEV.priv);
- (void)z16f_disableuartirq(TTYS1_DEV.priv);
+ (void)z16f_disableuartirq(TTYS0_DEV);
+ (void)z16f_disableuartirq(TTYS1_DEV);
CONSOLE_DEV.isconsole = TRUE;
z16f_setup(&CONSOLE_DEV);
@@ -687,21 +710,32 @@ int up_putc(int ch)
struct z16f_uart_s *priv = (struct z16f_uart_s*)CONSOLE_DEV.priv;
ubyte state;
- state = z16f_disableuartirq(priv);
- z16f_waittrde(priv);
- z16f_serialout(priv, UART_DTRR, (uint16)ch);
+ /* Keep interrupts disabled so that we do not interfere with normal
+ * driver operation
+ */
+
+ state = z16f_disableuartirq(&CONSOLE_DEV);
/* Check for LF */
if (ch == '\n')
{
- /* Add CR */
+ /* Add CR before LF */
- z16f_waittrde(priv);
- z16f_serialout(priv, UART_DTRR, '\r');
+ z16f_waittx(priv, z16f_txready);
+ putreg8('\r', priv->uartbase + Z16F_UART_TXD);
}
- z16f_waittrde(priv);
+ /* Output the character */
+
+ z16f_waittx(priv, z16f_txready);
+ putreg8((ubyte)ch, priv->uartbase + Z16F_UART_TXD);
+
+ /* Now wait for all queue TX data to drain before restoring interrupts. The
+ * driver should receive one txdone interrupt which it may or may not ignore.
+ */
+
+ z16f_waittx(priv, z16f_txempty);
z16f_restoreuartirq(priv, state);
return ch;
}
@@ -756,5 +790,3 @@ int up_putc(int ch)
}
#endif /* CONFIG_NFILE_DESCRIPTORS > 0 */
-
-