[rtems commit] bsp/virtex: Add VIRTEX_CONSOLE_USE_INTERRUPTS

Sebastian Huber sebh at rtems.org
Tue Jul 9 14:36:12 UTC 2013


Module:    rtems
Branch:    master
Commit:    0a697dd92c0c5f3de84448236e9c709a75336896
Changeset: http://git.rtems.org/rtems/commit/?id=0a697dd92c0c5f3de84448236e9c709a75336896

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jul  9 11:24:27 2013 +0200

bsp/virtex: Add VIRTEX_CONSOLE_USE_INTERRUPTS

Add interrupt support for console driver.

---

 c/src/lib/libbsp/powerpc/virtex/configure.ac       |    3 +
 .../libbsp/powerpc/virtex/console/consolelite.c    |  141 ++++++++++++++-----
 2 files changed, 107 insertions(+), 37 deletions(-)

diff --git a/c/src/lib/libbsp/powerpc/virtex/configure.ac b/c/src/lib/libbsp/powerpc/virtex/configure.ac
index fbf8ed1..201be24 100644
--- a/c/src/lib/libbsp/powerpc/virtex/configure.ac
+++ b/c/src/lib/libbsp/powerpc/virtex/configure.ac
@@ -25,6 +25,9 @@ RTEMS_BSPOPTS_HELP([RTEMS_XPARAMETERS_H],
 [This defines the location of the hardware specific "xparameters.h" file.
  in the file system. Specify an absolute path. Do not forget the double quotes])
 
+RTEMS_BSPOPTS_SET([VIRTEX_CONSOLE_USE_INTERRUPTS],[*],[1])
+RTEMS_BSPOPTS_HELP([VIRTEX_CONSOLE_USE_INTERRUPTS],[if defined use interrupt driven Termios mode])
+
 AC_DEFUN([VIRTEX_REGION],[
 AC_ARG_VAR([$1],[$2; default $3])dnl
 [$1]=[$]{[$1]:-[$3]}
diff --git a/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c b/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
index 513d289..f50454b 100644
--- a/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
+++ b/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
@@ -15,6 +15,8 @@
  *
  */
 
+#include <assert.h>
+
 #include <rtems.h>
 #include <rtems/libio.h>
 #include <bsp/irq.h>
@@ -109,27 +111,33 @@ static int xlite_write_char(uint32_t base, char ch)
    return 1;
 }
 
+static void xlite_init(int minor )
+{
+   /* Nothing to do */
+}
 
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+static void xlite_interrupt_handler(void *arg)
+{
+   int minor = (int) arg;
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   console_data *cd = &Console_Port_Data[minor];
+   uint32_t base = ct->ulCtrlPort1;
+   uint32_t status = xlite_uart_status(base);
 
+   while ((status & RX_FIFO_VALID_DATA) != 0) {
+      char c = (char) xlite_uart_read(base);
 
+      rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1);
 
+      status = xlite_uart_status(base);
+   }
 
-
-
-
-
-
-static void xlite_init (int minor )
-{
-   uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
-
-   /* clear status register */
-   *((volatile uint32_t*)(base+STAT_REG)) = 0;
-
-   /* clear control register; reset fifos & interrupt enable */
-   *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
+   if (cd->bActive) {
+      rtems_termios_dequeue_characters(cd->termios_data, 1);
+   }
 }
-
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
 
 static int xlite_open(
   int      major,
@@ -137,21 +145,33 @@ static int xlite_open(
   void    *arg
 )
 {
-   uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1;
-
-   /* the lite uarts have hardcoded baud & serial parms so no port
-    * conditioning is needed.  We're running polled so no interrupt
-    * enables either */
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   uint32_t base = ct->ulCtrlPort1;
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+   rtems_status_code sc;
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
 
    /* clear status register */
    *((volatile uint32_t*)(base+STAT_REG)) = 0;
 
-   /* clear control register; reset fifos & disable interrupts */
+   /* clear control register; reset fifos */
    *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
 
-   return RTEMS_SUCCESSFUL;
-}
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+   *((volatile uint32_t*)(base+CTRL_REG)) = ENABLE_INTR;
 
+   sc = rtems_interrupt_handler_install(
+      ct->ulIntVector,
+      "xlite",
+      RTEMS_INTERRUPT_UNIQUE,
+      xlite_interrupt_handler,
+      (void *) minor
+   );
+   assert(sc == RTEMS_SUCCESSFUL);
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   return 0;
+}
 
 static int xlite_close(
   int      major,
@@ -159,8 +179,24 @@ static int xlite_close(
   void    *arg
 )
 {
-   /* no shutdown protocol necessary */
-   return RTEMS_SUCCESSFUL;
+   const console_tbl *ct = Console_Port_Tbl[minor];
+   uint32_t base = ct->ulCtrlPort1;
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+   rtems_status_code sc;
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   *((volatile uint32_t*)(base+CTRL_REG)) = 0;
+
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+   sc = rtems_interrupt_handler_remove(
+      ct->ulIntVector,
+      xlite_interrupt_handler,
+      (void *) minor
+   );
+   assert(sc == RTEMS_SUCCESSFUL);
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
+
+   return 0;
 }
 
 
@@ -177,8 +213,31 @@ static int xlite_read_polled (int minor )
       return -1;
 }
 
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+
+static ssize_t xlite_write_interrupt_driven(
+  int minor,
+  const char *buf,
+  size_t len
+)
+{
+  console_data *cd = &Console_Port_Data[minor];
 
+  if (len > 0) {
+    const console_tbl *ct = Console_Port_Tbl[minor];
+    uint32_t base = ct->ulCtrlPort1;
 
+    xlite_uart_write(base, buf[0]);
+
+    cd->bActive = true;
+  } else {
+    cd->bActive = false;
+  }
+
+  return 0;
+}
+
+#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */
 
 static ssize_t xlite_write_buffer_polled(
   int         minor,
@@ -204,6 +263,7 @@ static ssize_t xlite_write_buffer_polled(
    return nwrite;
 }
 
+#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */
 
 static void xlite_write_char_polled(
   int   minor,
@@ -215,8 +275,6 @@ static void xlite_write_char_polled(
    return;
 }
 
-
-
 static int xlite_set_attributes(int minor, const struct termios *t)
 {
    return RTEMS_SUCCESSFUL;
@@ -230,15 +288,20 @@ static int xlite_set_attributes(int minor, const struct termios *t)
 
 static const console_fns xlite_fns_polled =
 {
-  libchip_serial_default_probe,        /* deviceProbe */
-  xlite_open,                          /* deviceFirstOpen */
-  xlite_close,                         /* deviceLastClose */
-  xlite_read_polled,                   /* deviceRead */
-  xlite_write_buffer_polled,           /* deviceWrite */
-  xlite_init,                          /* deviceInitialize */
-  xlite_write_char_polled,             /* deviceWritePolled */
-  xlite_set_attributes,                /* deviceSetAttributes */
-  FALSE,                               /* deviceOutputUsesInterrupts */
+  .deviceProbe = libchip_serial_default_probe,
+  .deviceFirstOpen = xlite_open,
+  .deviceLastClose = xlite_close,
+  .deviceRead = xlite_read_polled,
+  .deviceInitialize = xlite_init,
+  .deviceWritePolled = xlite_write_char_polled,
+  .deviceSetAttributes = xlite_set_attributes,
+#ifdef VIRTEX_CONSOLE_USE_INTERRUPTS
+  .deviceWrite = xlite_write_interrupt_driven,
+  .deviceOutputUsesInterrupts = true
+#else
+  .deviceWrite = xlite_write_buffer_polled,
+  .deviceOutputUsesInterrupts = false
+#endif
 };
 
 
@@ -269,7 +332,11 @@ console_tbl     Console_Configuration_Ports[] = {
    NULL, /* unused */                      /* getData */
    NULL, /* unused */                      /* setData */
    0,                                      /* ulClock */
-   0                                       /* ulIntVector -- base for port */
+   #ifdef XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
+     .ulIntVector = XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR
+   #else
+     .ulIntVector = 0
+   #endif
 },
 #ifdef XPAR_UARTLITE_1_BASEADDR
 {




More information about the vc mailing list