From 6b2fcc40ac8013d37e4c8aa4ea162316e2388ada Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 21 Feb 2017 10:30:30 +0100 Subject: bsp/xilinx-zynq: Use new Termios device driver --- c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am | 7 +- .../arm/xilinx-zynq/console/console-config.c | 100 +++++++-------------- .../libbsp/arm/xilinx-zynq/console/debug-console.c | 68 ++++++++++++++ .../lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c | 94 +++++++++---------- .../arm/xilinx-zynq/include/zynq-uart-regs.h | 2 +- .../lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h | 27 +++++- .../lib/libbsp/arm/xilinx-zynq/startup/bspreset.c | 6 +- 7 files changed, 168 insertions(+), 136 deletions(-) create mode 100644 c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c (limited to 'c/src/lib/libbsp/arm/xilinx-zynq') diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am index 8e6f8c3c9c..1f9ed5990c 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am +++ b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am @@ -106,12 +106,9 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c libbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -libbsp_a_SOURCES += ../../shared/console.c -libbsp_a_SOURCES += ../../shared/console_control.c -libbsp_a_SOURCES += ../../shared/console_read.c -libbsp_a_SOURCES += ../../shared/console_select_simple.c -libbsp_a_SOURCES += ../../shared/console_write.c +libbsp_a_SOURCES += ../../shared/console-termios.c libbsp_a_SOURCES += console/console-config.c +libbsp_a_SOURCES += console/debug-console.c libbsp_a_SOURCES += console/zynq-uart.c # Clock diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c index 94e5e4f799..ce7da2f114 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c +++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -12,89 +12,51 @@ * http://www.rtems.org/license/LICENSE. */ -#include - +#include #include -#include #include #include -console_tbl Console_Configuration_Ports[] = { +#include + +zynq_uart_context zynq_uart_instances[2] = { { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &zynq_uart_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 0, - .ulHysteresis = 0, - .pDeviceParams = (void *) 115200, - .ulCtrlPort1 = 0xe0000000, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = NULL, - .setRegister = NULL, - .getData = NULL, - .setData = NULL, - .ulClock = 0, - .ulIntVector = ZYNQ_IRQ_UART_0 + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), + .regs = (volatile struct zynq_uart *) 0xe0000000, + .irq = ZYNQ_IRQ_UART_0 }, { - .sDeviceName = "/dev/ttyS1", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &zynq_uart_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 0, - .ulHysteresis = 0, - .pDeviceParams = (void *) 115200, - .ulCtrlPort1 = 0xe0001000, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = NULL, - .setRegister = NULL, - .getData = NULL, - .setData = NULL, - .ulClock = 0, - .ulIntVector = ZYNQ_IRQ_UART_1 + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), + .regs = (volatile struct zynq_uart *) 0xe0001000, + .irq = ZYNQ_IRQ_UART_1 } }; -unsigned long Console_Configuration_Count = - RTEMS_ARRAY_SIZE(Console_Configuration_Ports); - -static void output_char(char c) +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) { - int minor = (int) Console_Port_Minor; - const console_tbl *ct = Console_Port_Tbl != NULL ? - Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor]; - const console_fns *cf = ct->pDeviceFns; - - if (c == '\n') { - (*cf->deviceWritePolled)(minor, '\r'); - } + size_t i; - (*cf->deviceWritePolled)(minor, c); -} - -static void output_char_init(char c) -{ - if (Console_Port_Tbl == NULL) { - int minor; - const console_fns *cf; + rtems_termios_initialize(); - bsp_console_select(); + for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) { + char uart[] = "/dev/ttySX"; - minor = (int) Console_Port_Minor; - cf = Console_Configuration_Ports[minor].pDeviceFns; + uart[sizeof(uart) - 2] = (char) ('0' + i); + rtems_termios_device_install( + &uart[0], + &zynq_uart_handler, + NULL, + &zynq_uart_instances[i].base + ); - (*cf->deviceInitialize)(minor); + if (i == BSP_CONSOLE_MINOR) { + link(&uart[0], CONSOLE_DEVICE_NAME); + } } - BSP_output_char = output_char; - output_char(c); + return RTEMS_SUCCESSFUL; } - -BSP_output_char_function_type BSP_output_char = output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c new file mode 100644 index 0000000000..887a7ea46c --- /dev/null +++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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 +#include + +#include + +#include + +static void zynq_debug_console_out(char c) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + if (c == '\n') { + zynq_uart_write_polled(base, '\r'); + } + + zynq_uart_write_polled(base, c); +} + +static void zynq_debug_console_init(void) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + zynq_uart_initialize(base); + BSP_output_char = zynq_debug_console_out; +} + +static void zynq_debug_console_early_init(char c) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + zynq_uart_initialize(base); + zynq_debug_console_out(c); +} + +static int zynq_debug_console_in(void) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + return zynq_uart_read_polled(base); +} + +BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in; + +RTEMS_SYSINIT_ITEM( + zynq_debug_console_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST +); diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c index f9a1cf91d5..05c8e5424e 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c +++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -17,16 +17,6 @@ #include -#include - -static volatile zynq_uart *zynq_uart_get_regs(int minor) -{ - const console_tbl *ct = Console_Port_Tbl != NULL ? - Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor]; - - return (volatile zynq_uart *) ct->ulCtrlPort1; -} - /* * Make weak and let the user override. */ @@ -112,13 +102,14 @@ static int zynq_cal_baud_rate(uint32_t baudrate, return 0; } -static void zynq_uart_initialize(int minor) +void zynq_uart_initialize(rtems_termios_device_context *base) { - volatile zynq_uart *regs = zynq_uart_get_regs(minor); + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; uint32_t brgr = 0x3e; uint32_t bauddiv = 0x6; - zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode); + zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode); regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); regs->control = ZYNQ_UART_CONTROL_RXDIS @@ -137,27 +128,23 @@ static void zynq_uart_initialize(int minor) | ZYNQ_UART_CONTROL_RSTTO; } -static int zynq_uart_first_open(int major, int minor, void *arg) +static bool zynq_uart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) { - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - console_data *cd = &Console_Port_Data[minor]; - const console_tbl *ct = Console_Port_Tbl[minor]; - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, (rtems_termios_baud_t) ct->pDeviceParams); - - return 0; -} + rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); + zynq_uart_initialize(base); -static int zynq_uart_last_close(int major, int minor, void *arg) -{ - return 0; + return true; } -static int zynq_uart_read_polled(int minor) +int zynq_uart_read_polled(rtems_termios_device_context *base) { - volatile zynq_uart *regs = zynq_uart_get_regs(minor); + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { return -1; @@ -166,9 +153,13 @@ static int zynq_uart_read_polled(int minor) } } -static void zynq_uart_write_polled(int minor, char c) +void zynq_uart_write_polled( + rtems_termios_device_context *base, + char c +) { - volatile zynq_uart *regs = zynq_uart_get_regs(minor); + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) { /* Wait */ @@ -177,8 +168,8 @@ static void zynq_uart_write_polled(int minor, char c) regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); } -static ssize_t zynq_uart_write_support_polled( - int minor, +static void zynq_uart_write_support_polled( + rtems_termios_device_context *base, const char *s, size_t n ) @@ -186,13 +177,14 @@ static ssize_t zynq_uart_write_support_polled( ssize_t i = 0; for (i = 0; i < n; ++i) { - zynq_uart_write_polled(minor, s[i]); + zynq_uart_write_polled(base, s[i]); } - - return n; } -static int zynq_uart_set_attribues(int minor, const struct termios *term) +static bool zynq_uart_set_attributes( + rtems_termios_device_context *context, + const struct termios *term +) { #if 0 volatile zynq_uart *regs = zynq_uart_get_regs(minor); @@ -209,31 +201,27 @@ static int zynq_uart_set_attribues(int minor, const struct termios *term) regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN; - return 0; + return true; #else - return -1; + return false; #endif } -const console_fns zynq_uart_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = zynq_uart_first_open, - .deviceLastClose = zynq_uart_last_close, - .deviceRead = zynq_uart_read_polled, - .deviceWrite = zynq_uart_write_support_polled, - .deviceInitialize = zynq_uart_initialize, - .deviceWritePolled = zynq_uart_write_polled, - .deviceSetAttributes = zynq_uart_set_attribues, - .deviceOutputUsesInterrupts = false +const rtems_termios_device_handler zynq_uart_handler = { + .first_open = zynq_uart_first_open, + .write = zynq_uart_write_support_polled, + .poll_read = zynq_uart_read_polled, + .set_attributes = zynq_uart_set_attributes, + .mode = TERMIOS_POLLED }; -void zynq_uart_reset_tx_flush(int minor) +void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) { - volatile zynq_uart *regs = zynq_uart_get_regs(minor); + volatile zynq_uart *regs = ctx->regs; int c = 4; while (c-- > 0) - zynq_uart_write_polled(minor, '\r'); + zynq_uart_write_polled(&ctx->base, '\r'); while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) { /* Wait */ diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h index f8f902bbde..e72b93a9dc 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h +++ b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h @@ -30,7 +30,7 @@ #include -typedef struct { +typedef struct zynq_uart { uint32_t control; #define ZYNQ_UART_CONTROL_STPBRK BSP_BIT32(8) #define ZYNQ_UART_CONTROL_STTBRK BSP_BIT32(7) diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h index 07c883af87..57412d7ec9 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h +++ b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -21,7 +21,7 @@ #ifndef LIBBSP_ARM_XILINX_ZYNQ_UART_H #define LIBBSP_ARM_XILINX_ZYNQ_UART_H -#include +#include #ifdef __cplusplus extern "C" { @@ -33,12 +33,31 @@ extern "C" { * @brief UART Support */ -extern const console_fns zynq_uart_fns; +typedef struct { + rtems_termios_device_context base; + volatile struct zynq_uart *regs; + rtems_vector_number irq; +} zynq_uart_context; + +const rtems_termios_device_handler zynq_uart_handler; + +extern zynq_uart_context zynq_uart_instances[2]; + +#define ZYNQ_UART_DEFAULT_BAUD 115200 + +void zynq_uart_initialize(rtems_termios_device_context *base); + +int zynq_uart_read_polled(rtems_termios_device_context *base); + +void zynq_uart_write_polled( + rtems_termios_device_context *base, + char c +); /** * Flush TX FIFO and wait until it is empty. Used in bsp_reset. */ -void zynq_uart_reset_tx_flush(int minor); +void zynq_uart_reset_tx_flush(zynq_uart_context *ctx); #ifdef __cplusplus } diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c b/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c index f86d1f3e05..b57354c9e2 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c +++ b/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -21,9 +21,7 @@ void bsp_reset(void) volatile uint32_t *slcr_unlock = (volatile uint32_t *) 0xf8000008; volatile uint32_t *pss_rst_ctrl = (volatile uint32_t *) 0xf8000200; - if (Console_Port_Tbl != NULL) { - zynq_uart_reset_tx_flush((int) Console_Port_Minor); - } + zynq_uart_reset_tx_flush(&zynq_uart_instances[BSP_CONSOLE_MINOR]); while (true) { *slcr_unlock = 0xdf0d; -- cgit v1.2.3