summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-07-09 11:24:27 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-07-09 16:42:01 +0200
commit0a697dd92c0c5f3de84448236e9c709a75336896 (patch)
tree4c21af6b16c6b7e8b2ccf986207b8786d38f3199
parentbsp/virtex: Use ppc_count_leading_zeros() (diff)
downloadrtems-0a697dd92c0c5f3de84448236e9c709a75336896.tar.bz2
bsp/virtex: Add VIRTEX_CONSOLE_USE_INTERRUPTS
Add interrupt support for console driver.
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/configure.ac3
-rw-r--r--c/src/lib/libbsp/powerpc/virtex/console/consolelite.c141
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 fbf8ed1875..201be249f4 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 513d289451..f50454be78 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
{