summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lpc32xx
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-07 08:29:16 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-07 16:35:20 +0200
commit6ec438e8a323cf623cdaecce6f2b3b52b062881a (patch)
tree8cd71b9fb974897a825b36ea1f070dd4405af46f /c/src/lib/libbsp/arm/lpc32xx
parentbsps: Add Termios console driver initialization (diff)
downloadrtems-6ec438e8a323cf623cdaecce6f2b3b52b062881a.tar.bz2
libchip/serial: Add alternative NS16550 driver
Use the Termios device API.
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc32xx')
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/Makefile.am12
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/console/console-config.c259
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/console/hsu.c192
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/include/hsu.h68
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/preinstall.am4
5 files changed, 296 insertions, 239 deletions
diff --git a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am
index 0eef512254..524d07e509 100644
--- a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am
+++ b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am
@@ -48,6 +48,7 @@ include_bsp_HEADERS += include/lpc-clock-config.h
include_bsp_HEADERS += include/lpc-ethernet-config.h
include_bsp_HEADERS += include/nand-mlc.h
include_bsp_HEADERS += include/boot.h
+include_bsp_HEADERS += include/hsu.h
include_bsp_HEADERS += include/i2c.h
include_bsp_HEADERS += include/emc.h
@@ -111,13 +112,10 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
libbsp_a_SOURCES += irq/irq.c
# Console
-libbsp_a_SOURCES += ../../shared/console.c \
- ../../shared/console_select.c \
- console/console-config.c \
- console/hsu.c \
- ../../shared/console_read.c \
- ../../shared/console_write.c \
- ../../shared/console_control.c
+libbsp_a_SOURCES += ../../shared/console-termios-init.c
+libbsp_a_SOURCES += ../../shared/console-termios.c
+libbsp_a_SOURCES += console/console-config.c
+libbsp_a_SOURCES += console/hsu.c
# Clock
libbsp_a_SOURCES += ../shared/lpc/clock/lpc-clock-config.c
diff --git a/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c b/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c
index d2889856e1..17e6b0af8f 100644
--- a/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c
+++ b/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c
@@ -7,26 +7,26 @@
*/
/*
- * Copyright (c) 2009
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
+ * Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
-#include <libchip/serial.h>
#include <libchip/ns16550.h>
#include <bsp.h>
#include <bsp/lpc32xx.h>
#include <bsp/irq.h>
-
-extern const console_fns lpc32xx_hsu_fns;
+#include <bsp/hsu.h>
+#include <bsp/console-termios.h>
static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i)
{
@@ -43,18 +43,18 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
}
#ifdef LPC32XX_UART_3_BAUD
- static bool lpc32xx_uart_probe_3(int minor)
+ static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context)
{
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0);
LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5);
- return true;
+ return ns16550_probe(context);
}
#endif
#ifdef LPC32XX_UART_4_BAUD
- static bool lpc32xx_uart_probe_4(int minor)
+ static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context)
{
volatile lpc32xx_gpio *gpio = &lpc32xx.gpio;
@@ -68,12 +68,12 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7);
- return true;
+ return ns16550_probe(context);
}
#endif
#ifdef LPC32XX_UART_6_BAUD
- static bool lpc32xx_uart_probe_6(int minor)
+ static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context)
{
/* Bypass the IrDA modulator/demodulator */
LPC32XX_UART_CTRL |= BSP_BIT32(5);
@@ -82,163 +82,144 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11);
- return true;
+ return ns16550_probe(context);
}
#endif
/* FIXME: Console selection */
-console_tbl Console_Configuration_Ports [] = {
+#ifdef LPC32XX_UART_5_BAUD
+static ns16550_context lpc32xx_uart_context_5 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 5"),
+ .get_reg = lpc32xx_uart_get_register,
+ .set_reg = lpc32xx_uart_set_register,
+ .port = LPC32XX_BASE_UART_5,
+ .irq = LPC32XX_IRQ_UART_5,
+ .clock = 16 * LPC32XX_UART_5_BAUD,
+ .initial_baud = LPC32XX_UART_5_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_3_BAUD
+static ns16550_context lpc32xx_uart_context_3 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
+ .get_reg = lpc32xx_uart_get_register,
+ .set_reg = lpc32xx_uart_set_register,
+ .port = LPC32XX_BASE_UART_3,
+ .irq = LPC32XX_IRQ_UART_3,
+ .clock = 16 * LPC32XX_UART_3_BAUD,
+ .initial_baud = LPC32XX_UART_3_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_4_BAUD
+static ns16550_context lpc32xx_uart_context_4 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 4"),
+ .get_reg = lpc32xx_uart_get_register,
+ .set_reg = lpc32xx_uart_set_register,
+ .port = LPC32XX_BASE_UART_4,
+ .irq = LPC32XX_IRQ_UART_4,
+ .clock = 16 * LPC32XX_UART_4_BAUD,
+ .initial_baud = LPC32XX_UART_4_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_6_BAUD
+static ns16550_context lpc32xx_uart_context_6 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 6"),
+ .get_reg = lpc32xx_uart_get_register,
+ .set_reg = lpc32xx_uart_set_register,
+ .port = LPC32XX_BASE_UART_6,
+ .irq = LPC32XX_IRQ_UART_6,
+ .clock = 16 * LPC32XX_UART_6_BAUD,
+ .initial_baud = LPC32XX_UART_6_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_1_BAUD
+static lpc32xx_hsu_context lpc32xx_uart_context_1 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
+ .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_1,
+ .irq = LPC32XX_IRQ_UART_1,
+ .initial_baud = LPC32XX_UART_1_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_2_BAUD
+static lpc32xx_hsu_context lpc32xx_uart_context_2 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
+ .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_2,
+ .irq = LPC32XX_IRQ_UART_2,
+ .initial_baud = LPC32XX_UART_2_BAUD
+};
+#endif
+
+#ifdef LPC32XX_UART_7_BAUD
+static lpc32xx_hsu_context lpc32xx_uart_context_7 = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 7"),
+ .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_7,
+ .irq = LPC32XX_IRQ_UART_7,
+ .initial_baud = LPC32XX_UART_7_BAUD
+};
+#endif
+
+const console_device console_device_table[] = {
#ifdef LPC32XX_UART_5_BAUD
{
- .sDeviceName = "/dev/ttyS5",
- .deviceType = SERIAL_NS16550,
- .pDeviceFns = &ns16550_fns,
- .deviceProbe = NULL,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_5_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_5,
- .ulCtrlPort2 = 0,
- .ulDataPort = LPC32XX_BASE_UART_5,
- .getRegister = lpc32xx_uart_get_register,
- .setRegister = lpc32xx_uart_set_register,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16 * LPC32XX_UART_5_BAUD,
- .ulIntVector = LPC32XX_IRQ_UART_5
+ .device_file = "/dev/ttyS5",
+ .probe = console_device_probe_default,
+ .handler = &ns16550_handler_interrupt,
+ .context = &lpc32xx_uart_context_5.base
},
#endif
#ifdef LPC32XX_UART_3_BAUD
{
- .sDeviceName = "/dev/ttyS3",
- .deviceType = SERIAL_NS16550,
- .pDeviceFns = &ns16550_fns,
- .deviceProbe = lpc32xx_uart_probe_3,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_3_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_3,
- .ulCtrlPort2 = 0,
- .ulDataPort = LPC32XX_BASE_UART_3,
- .getRegister = lpc32xx_uart_get_register,
- .setRegister = lpc32xx_uart_set_register,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16 * LPC32XX_UART_3_BAUD,
- .ulIntVector = LPC32XX_IRQ_UART_3
+ .device_file = "/dev/ttyS3",
+ .probe = lpc32xx_uart_probe_3,
+ .handler = &ns16550_handler_interrupt,
+ .context = &lpc32xx_uart_context_3.base
},
#endif
#ifdef LPC32XX_UART_4_BAUD
{
- .sDeviceName = "/dev/ttyS4",
- .deviceType = SERIAL_NS16550,
- .pDeviceFns = &ns16550_fns,
- .deviceProbe = lpc32xx_uart_probe_4,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_4_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_4,
- .ulCtrlPort2 = 0,
- .ulDataPort = LPC32XX_BASE_UART_4,
- .getRegister = lpc32xx_uart_get_register,
- .setRegister = lpc32xx_uart_set_register,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16 * LPC32XX_UART_4_BAUD,
- .ulIntVector = LPC32XX_IRQ_UART_4
+ .device_file = "/dev/ttyS4",
+ .probe = lpc32xx_uart_probe_4,
+ .handler = &ns16550_handler_interrupt,
+ .context = &lpc32xx_uart_context_4.base
},
#endif
#ifdef LPC32XX_UART_6_BAUD
{
- .sDeviceName = "/dev/ttyS6",
- .deviceType = SERIAL_NS16550,
- .pDeviceFns = &ns16550_fns,
- .deviceProbe = lpc32xx_uart_probe_6,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_6_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_6,
- .ulCtrlPort2 = 0,
- .ulDataPort = LPC32XX_BASE_UART_6,
- .getRegister = lpc32xx_uart_get_register,
- .setRegister = lpc32xx_uart_set_register,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16 * LPC32XX_UART_6_BAUD,
- .ulIntVector = LPC32XX_IRQ_UART_6
+ .device_file = "/dev/ttyS6",
+ .probe = lpc32xx_uart_probe_6,
+ .handler = &ns16550_handler_interrupt,
+ .context = &lpc32xx_uart_context_6.base
},
#endif
#ifdef LPC32XX_UART_1_BAUD
{
- .sDeviceName = "/dev/ttyS1",
- .deviceType = SERIAL_CUSTOM,
- .pDeviceFns = &lpc32xx_hsu_fns,
- .deviceProbe = NULL,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_1_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_1,
- .ulCtrlPort2 = 0,
- .ulDataPort = 0,
- .getRegister = NULL,
- .setRegister = NULL,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16,
- .ulIntVector = LPC32XX_IRQ_UART_1
+ .device_file = "/dev/ttyS1",
+ .probe = lpc32xx_hsu_probe,
+ .handler = &lpc32xx_hsu_fns,
+ .context = &lpc32xx_uart_context_1.base
},
#endif
#ifdef LPC32XX_UART_2_BAUD
{
- .sDeviceName = "/dev/ttyS2",
- .deviceType = SERIAL_CUSTOM,
- .pDeviceFns = &lpc32xx_hsu_fns,
- .deviceProbe = NULL,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_2_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_2,
- .ulCtrlPort2 = 0,
- .ulDataPort = 0,
- .getRegister = NULL,
- .setRegister = NULL,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16,
- .ulIntVector = LPC32XX_IRQ_UART_2
+ .device_file = "/dev/ttyS2",
+ .probe = lpc32xx_hsu_probe,
+ .handler = &lpc32xx_hsu_fns,
+ .context = &lpc32xx_uart_context_2.base
},
#endif
#ifdef LPC32XX_UART_7_BAUD
{
- .sDeviceName = "/dev/ttyS7",
- .deviceType = SERIAL_CUSTOM,
- .pDeviceFns = &lpc32xx_hsu_fns,
- .deviceProbe = NULL,
- .pDeviceFlow = NULL,
- .ulMargin = 16,
- .ulHysteresis = 8,
- .pDeviceParams = (void *) LPC32XX_UART_7_BAUD,
- .ulCtrlPort1 = LPC32XX_BASE_UART_7,
- .ulCtrlPort2 = 0,
- .ulDataPort = 0,
- .getRegister = NULL,
- .setRegister = NULL,
- .getData = NULL,
- .setData = NULL,
- .ulClock = 16,
- .ulIntVector = LPC32XX_IRQ_UART_7
+ .device_file = "/dev/ttyS7",
+ .probe = lpc32xx_hsu_probe,
+ .handler = &lpc32xx_hsu_fns,
+ .context = &lpc32xx_uart_context_7.base
},
#endif
};
-#define LPC32XX_UART_COUNT \
- (sizeof(Console_Configuration_Ports) / sizeof(Console_Configuration_Ports [0]))
-
-unsigned long Console_Configuration_Count = LPC32XX_UART_COUNT;
+const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
diff --git a/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c b/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c
index 0dc4a61695..8beeeef9b0 100644
--- a/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c
+++ b/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c
@@ -7,36 +7,23 @@
*/
/*
- * Copyright (c) 2010
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
+ * Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/termiostypes.h>
-
-#include <libchip/serial.h>
-#include <libchip/sersupp.h>
-
#include <bsp.h>
#include <bsp/lpc32xx.h>
#include <bsp/irq.h>
-
-typedef struct {
- uint32_t fifo;
- uint32_t level;
- uint32_t iir;
- uint32_t ctrl;
- uint32_t rate;
-} lpc32xx_hsu;
+#include <bsp/hsu.h>
#define HSU_FIFO_SIZE 64
@@ -60,54 +47,29 @@ typedef struct {
/* We are interested in RX timeout, RX trigger and TX trigger interrupts */
#define HSU_IIR_MASK 0x7U
-static int lpc32xx_hsu_first_open(int major, int minor, void *arg)
-{
- rtems_libio_open_close_args_t *oca = arg;
- struct rtems_termios_tty *tty = oca->iop->data1;
- console_tbl *ct = Console_Port_Tbl [minor];
- console_data *cd = &Console_Port_Data [minor];
- volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
-
- cd->termios_data = tty;
- rtems_termios_set_initial_baud(tty, (int32_t) ct->pDeviceParams);
- hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
-
- return 0;
-}
-
-static ssize_t lpc32xx_hsu_write(int minor, const char *buf, size_t len)
+bool lpc32xx_hsu_probe(rtems_termios_device_context *base)
{
- console_tbl *ct = Console_Port_Tbl [minor];
- console_data *cd = &Console_Port_Data [minor];
- volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
- size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT;
- size_t tx_free = HSU_FIFO_SIZE - tx_level;
- size_t i = 0;
- size_t out = len > tx_free ? tx_free : len;
+ lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
- for (i = 0; i < out; ++i) {
- hsu->fifo = buf [i];
- }
+ hsu->ctrl = HSU_CTRL_INTR_DISABLED;
- if (len > 0) {
- cd->pDeviceContext = (void *) out;
- cd->bActive = true;
- hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED;
+ /* Drain FIFOs */
+ while (hsu->level != 0) {
+ hsu->fifo;
}
- return 0;
+ return true;
}
static void lpc32xx_hsu_interrupt_handler(void *arg)
{
- int minor = (int) arg;
- console_tbl *ct = Console_Port_Tbl [minor];
- console_data *cd = &Console_Port_Data [minor];
- volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
+ rtems_termios_tty *tty = arg;
+ lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty);
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
/* Iterate until no more interrupts are pending */
do {
- int chars_to_dequeue = (int) cd->pDeviceContext;
int rv = 0;
int i = 0;
char buf [HSU_FIFO_SIZE];
@@ -125,49 +87,97 @@ static void lpc32xx_hsu_interrupt_handler(void *arg)
break;
}
}
- rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
+ rtems_termios_enqueue_raw_characters(tty, buf, i);
/* Dequeue transmitted characters */
- cd->pDeviceContext = 0;
- rv = rtems_termios_dequeue_characters(cd->termios_data, chars_to_dequeue);
+ rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission);
if (rv == 0) {
/* Nothing to transmit */
- cd->bActive = false;
- hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
- hsu->iir = HSU_IIR_TX;
}
} while ((hsu->iir & HSU_IIR_MASK) != 0);
}
-static void lpc32xx_hsu_initialize(int minor)
+static bool lpc32xx_hsu_first_open(
+ struct rtems_termios_tty *tty,
+ rtems_termios_device_context *base,
+ struct termios *term,
+ rtems_libio_open_close_args_t *args
+)
{
- console_tbl *ct = Console_Port_Tbl [minor];
- console_data *cd = &Console_Port_Data [minor];
- volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
-
- hsu->ctrl = HSU_CTRL_INTR_DISABLED;
+ lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
+ rtems_status_code sc;
+ bool ok;
- cd->bActive = false;
- cd->pDeviceContext = 0;
+ sc = rtems_interrupt_handler_install(
+ ctx->irq,
+ "HSU",
+ RTEMS_INTERRUPT_UNIQUE,
+ lpc32xx_hsu_interrupt_handler,
+ tty
+ );
+ ok = sc == RTEMS_SUCCESSFUL;
- /* Drain FIFOs */
- while (hsu->level != 0) {
- hsu->fifo;
+ if (ok) {
+ rtems_termios_set_initial_baud(tty, ctx->initial_baud);
+ hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
}
- rtems_interrupt_handler_install(
- ct->ulIntVector,
- "HSU",
- RTEMS_INTERRUPT_UNIQUE,
+ return ok;
+}
+
+static void lpc32xx_hsu_last_close(
+ struct rtems_termios_tty *tty,
+ rtems_termios_device_context *base,
+ rtems_libio_open_close_args_t *args
+)
+{
+ lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
+
+ hsu->ctrl = HSU_CTRL_INTR_DISABLED;
+
+ rtems_interrupt_handler_remove(
+ ctx->irq,
lpc32xx_hsu_interrupt_handler,
- (void *) minor
+ tty
);
}
-static int lpc32xx_hsu_set_attributes(int minor, const struct termios *term)
+static void lpc32xx_hsu_write(
+ rtems_termios_device_context *base,
+ const char *buf,
+ size_t len
+)
+{
+ lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
+ size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT;
+ size_t tx_free = HSU_FIFO_SIZE - tx_level;
+ size_t i = 0;
+ size_t out = len > tx_free ? tx_free : len;
+
+ for (i = 0; i < out; ++i) {
+ hsu->fifo = buf [i];
+ }
+
+ ctx->chars_in_transmission = out;
+
+ if (len > 0) {
+ hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED;
+ } else {
+ hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
+ hsu->iir = HSU_IIR_TX;
+ }
+}
+
+static bool lpc32xx_hsu_set_attributes(
+ rtems_termios_device_context *base,
+ const struct termios *term
+)
{
- console_tbl *ct = Console_Port_Tbl [minor];
- volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
+ lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
+ volatile lpc32xx_hsu *hsu = ctx->hsu;
int baud_flags = term->c_cflag & CBAUD;
if (baud_flags != 0) {
@@ -186,17 +196,13 @@ static int lpc32xx_hsu_set_attributes(int minor, const struct termios *term)
}
}
- return 0;
+ return true;
}
-const console_fns lpc32xx_hsu_fns = {
- .deviceProbe = libchip_serial_default_probe,
- .deviceFirstOpen = lpc32xx_hsu_first_open,
- .deviceLastClose = NULL,
- .deviceRead = NULL,
- .deviceWrite = lpc32xx_hsu_write,
- .deviceInitialize = lpc32xx_hsu_initialize,
- .deviceWritePolled = NULL,
- .deviceSetAttributes = lpc32xx_hsu_set_attributes,
- .deviceOutputUsesInterrupts = true
+const rtems_termios_device_handler lpc32xx_hsu_fns = {
+ .first_open = lpc32xx_hsu_first_open,
+ .last_close = lpc32xx_hsu_last_close,
+ .write = lpc32xx_hsu_write,
+ .set_attributes = lpc32xx_hsu_set_attributes,
+ .mode = TERMIOS_IRQ_DRIVEN
};
diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/hsu.h b/c/src/lib/libbsp/arm/lpc32xx/include/hsu.h
new file mode 100644
index 0000000000..ba97dfb423
--- /dev/null
+++ b/c/src/lib/libbsp/arm/lpc32xx/include/hsu.h
@@ -0,0 +1,68 @@
+/**
+ * @file
+ *
+ * @ingroup lpc32xx_hsu
+ *
+ * @brief HSU support API.
+ */
+
+/*
+ * Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_LPC32XX_HSU_H
+#define LIBBSP_ARM_LPC32XX_HSU_H
+
+#include <rtems/termiostypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup lpc32xx_hsu HSU Support
+ *
+ * @ingroup arm_lpc32xx
+ *
+ * @brief HSU Support
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t fifo;
+ uint32_t level;
+ uint32_t iir;
+ uint32_t ctrl;
+ uint32_t rate;
+} lpc32xx_hsu;
+
+typedef struct {
+ rtems_termios_device_context base;
+ volatile lpc32xx_hsu *hsu;
+ size_t chars_in_transmission;
+ rtems_vector_number irq;
+ uint32_t initial_baud;
+} lpc32xx_hsu_context;
+
+extern const rtems_termios_device_handler lpc32xx_hsu_fns;
+
+bool lpc32xx_hsu_probe(rtems_termios_device_context *base);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_LPC32XX_HSU_H */
diff --git a/c/src/lib/libbsp/arm/lpc32xx/preinstall.am b/c/src/lib/libbsp/arm/lpc32xx/preinstall.am
index b15e8cdaeb..9a2571ed41 100644
--- a/c/src/lib/libbsp/arm/lpc32xx/preinstall.am
+++ b/c/src/lib/libbsp/arm/lpc32xx/preinstall.am
@@ -146,6 +146,10 @@ $(PROJECT_INCLUDE)/bsp/boot.h: include/boot.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/boot.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/boot.h
+$(PROJECT_INCLUDE)/bsp/hsu.h: include/hsu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/hsu.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/hsu.h
+
$(PROJECT_INCLUDE)/bsp/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2c.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2c.h