diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-10-07 08:29:16 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-10-07 16:35:20 +0200 |
commit | 6ec438e8a323cf623cdaecce6f2b3b52b062881a (patch) | |
tree | 8cd71b9fb974897a825b36ea1f070dd4405af46f /c/src/lib/libbsp/arm/lpc32xx | |
parent | bsps: Add Termios console driver initialization (diff) | |
download | rtems-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.am | 12 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/console/console-config.c | 259 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/console/hsu.c | 192 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/include/hsu.h | 68 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc32xx/preinstall.am | 4 |
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 |