2017-08-17 17:21 GMT+02:00 Gedare Bloom <ged...@rtems.org>: > Remove the extra blank lines, and consider adding some helper > functions (for enable/disable UARTx, for example) > > On Wed, Aug 16, 2017 at 11:13 AM, Denis Obrezkov > <denisobrez...@gmail.com> wrote: > > --- > > .../libbsp/riscv32/hifive1/console/fe310-uart.c | 215 > +++++++++++++++++++++ > > .../libbsp/riscv32/hifive1/include/fe310-gpio.h | 41 ++++ > > .../libbsp/riscv32/hifive1/include/fe310-uart.h | 38 ++++ > > 3 files changed, 294 insertions(+) > > create mode 100644 c/src/lib/libbsp/riscv32/hifiv > e1/console/fe310-uart.c > > create mode 100644 c/src/lib/libbsp/riscv32/hifiv > e1/include/fe310-gpio.h > > create mode 100644 c/src/lib/libbsp/riscv32/hifiv > e1/include/fe310-uart.h > > > > diff --git a/c/src/lib/libbsp/riscv32/hifive1/console/fe310-uart.c > b/c/src/lib/libbsp/riscv32/hifive1/console/fe310-uart.c > > new file mode 100644 > > index 0000000..1784ff7 > > --- /dev/null > > +++ b/c/src/lib/libbsp/riscv32/hifive1/console/fe310-uart.c > > @@ -0,0 +1,215 @@ > > +/* > > + * Copyright (c) 2017 Denis Obrezkov <denisobrez...@gmail.com> > > + * > > + * 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/console.h> > > +#include <rtems/termiostypes.h> > > +#include <termios.h> > > +#include <bsp/prci.h> > > +#include <bsp/fe310-uart.h> > > +#include <bsp/fe310-gpio.h> > > +#include <bsp/fe310.h> > > +#include <bsp/fatal.h> > > +#include <bsp/console-polled.h> > > + > > +static void fe310_console_putc (char ch); > > + > > +fe310_uart_context driver_context = { > > + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("FE310_UART0"), > > + .device_name = "/dev/console", > > + .regs = (volatile fe310_uart_t *) &FE310_UART0, > > +}; > > + > > + > > +rtems_device_driver console_initialize( > > + rtems_device_major_number major, > > + rtems_device_minor_number minor, > > + void *arg > > +) > > +{ > > + rtems_status_code sc; > > + const rtems_termios_device_handler *handler = > &fe310_uart_handler_polled; > > + > > + /* > > + * Initialize the Termios infrastructure. If Termios has already > > + * been initialized by another device driver, then this call will > > + * have no effect. > > + */ > > + rtems_termios_initialize(); > > + fe310_uart_context * ctx = &driver_context; > > + /* > > + * Install this device in the file system and Termios. In order > > + * to use the console (i.e. being able to do printf, scanf etc. > > + * on stdin, stdout and stderr), one device must be registered as > > + * "/dev/console" (CONSOLE_DEVICE_NAME). > > + */ > > + sc = rtems_termios_device_install( > > + ctx->device_name, > > + handler, > > + NULL, > > + &ctx->base > > + ); > > + if ( sc != RTEMS_SUCCESSFUL ) { > > + bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV); > > + } > > + > > + return RTEMS_SUCCESSFUL; > > +} > > + > > + > > + > > +static bool fe310_uart_first_open ( > > + rtems_termios_tty *tty, > > + rtems_termios_device_context *base, > > + struct termios *term, > > + rtems_libio_open_close_args_t *args > > +) > > +{ > > + volatile fe310_gpio_t * gpio; > > + fe310_uart_context * ctx; > > + rtems_status_code sc; > > + > > + > > + /* Configure GPIO to be UART */ > > + gpio = (volatile fe310_gpio_t *)&FE310_GPIO; > > + gpio->iof_sel &= ~IOF0_UART0_MASK; > > + gpio->iof_en |= ~IOF0_UART0_MASK; > > + > > + > > + sc = rtems_termios_set_initial_baud (tty, B115200); > > + if ( sc != RTEMS_SUCCESSFUL ) { > > + return false; > > + } > > + > > + /* Set up a baud rate and enable tx and rx */ > > + ctx = (fe310_uart_context *) base; > > + (ctx->regs)->div = hifive1_default_freq / 115200 - 1; > > + (ctx->regs)->txctrl |= 1; > > + (ctx->regs)->rxctrl |= 1; > > + return true; > > +}; > > + > > +static void fe310_uart_last_close ( > > + rtems_termios_tty *tty, > > + rtems_termios_device_context *base, > > + rtems_libio_open_close_args_t *args > > +) > > +{ > > + return; > > +} > > + > > +static int fe310_uart_poll_read ( > > + rtems_termios_device_context *base > > +) > > +{ > > + fe310_uart_context * ctx = (fe310_uart_context*) base; > > + size_t i; > > + > > + if (((ctx->regs->rxdata) & 0x80000000) != 0) { > > + return -1; > > + } else { > > + return ctx->regs->rxdata; > > + } > > +} > > + > > +static uint32_t freq = 0; > > + > > +static ssize_t fe310_uart_poll_write ( > > + rtems_termios_device_context *base, > > + const char *buf, > > + size_t n > > +) > > +{ > > + > > + fe310_uart_context * ctx = (fe310_uart_context*) base; > > + size_t i; > > + > > + > > + volatile fe310_gpio_t * gpio; > > + rtems_status_code sc; > > + > > + gpio = (volatile fe310_gpio_t *)&FE310_GPIO; > > + gpio->iof_sel &= ~IOF0_UART0_MASK; > > + gpio->iof_en |= ~IOF0_UART0_MASK; > > + > > + gpio->iof_sel &= ~IOF0_UART1_MASK; > > + gpio->iof_en |= ~IOF0_UART1_MASK; > > + > > + > > + (ctx->regs)->div = hifive1_default_freq / 115200 - 1; > > + (ctx->regs)->txctrl |= 1; > > + (ctx->regs)->rxctrl |= 1; > > + > > + > > + > > + for (i = 0; i < n; ++i) { > > + while (((ctx->regs->txdata) & 0x80000000) != 0) { > > + ; > > + } > > + ctx->regs->txdata = buf[i]; > > + } > > + return n; > > +} > > + > > +static void fe310_console_putc (char ch) { > > + fe310_uart_poll_write ( (rtems_termios_device_context > *)&driver_context, &ch, 1); > > +} > > + > > +static bool fe310_uart_set_attributes( > > + rtems_termios_device_context *base, > > + const struct termios *term > > +) > > +{ > > + return true; > > +} > > + > > +const rtems_termios_device_handler fe310_uart_handler_polled = { > > + .first_open = fe310_uart_first_open, > > + .last_close = fe310_uart_last_close, > > + .poll_read = fe310_uart_poll_read, > > + .write = fe310_uart_poll_write, > > + .set_attributes = fe310_uart_set_attributes, > > + .ioctl = NULL, > > + .mode = TERMIOS_POLLED > > +}; > > + > > +void console_outbyte_polled( > > + int port, > > + char ch > > +) > > +{ > > + fe310_console_putc(ch); > > +} > > + > > +int console_inbyte_nonblocking( > > + int port > > +) > > +{ > > + return -1; > > +} > > + > > +void console_initialize_hardware (void) > > +{ > > + volatile fe310_gpio_t * gpio; > > + volatile fe310_uart_t * uregs = (volatile fe310_uart_t *) > &FE310_UART0; > > + rtems_status_code sc; > > + > > + gpio = (volatile fe310_gpio_t *)&FE310_GPIO; > > + gpio->iof_sel &= ~IOF0_UART0_MASK; > > + gpio->iof_en |= ~IOF0_UART0_MASK; > > + > > + > > + uregs->div = hifive1_default_freq / 115200 - 1; > > + uregs->txctrl |= 1; > > + return; > > + > > +} > > + > > + > > +#include <rtems/bspIo.h> > > +BSP_output_char_function_type BSP_output_char = fe310_console_putc; > > + > > diff --git a/c/src/lib/libbsp/riscv32/hifive1/include/fe310-gpio.h > b/c/src/lib/libbsp/riscv32/hifive1/include/fe310-gpio.h > > new file mode 100644 > > index 0000000..d5332fc > > --- /dev/null > > +++ b/c/src/lib/libbsp/riscv32/hifive1/include/fe310-gpio.h > > @@ -0,0 +1,41 @@ > > +/* > > + * Copyright (c) 2017 Denis Obrezkov <denisobrez...@gmail.com> > > + * > > + * 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 FE310_GPIO_H > > +#define FE310_GPIO_H > > + > > + > > +#include <rtems/termiostypes.h> > > +#include <rtems/irq.h> > > + > > +#define IOF0_UART0_MASK 0x00030000 > > +#define IOF0_UART1_MASK 0x00300000 > > + > > +typedef struct { > > + uint32_t value; > > + uint32_t input_en; > > + uint32_t output_en; > > + uint32_t port; > > + uint32_t pue; > > + uint32_t ds; > > + uint32_t rise_ie; > > + uint32_t rise_ip; > > + uint32_t fall_ie; > > + uint32_t fall_ip; > > + uint32_t high_ie; > > + uint32_t high_ip; > > + uint32_t low_ie; > > + uint32_t low_ip; > > + uint32_t iof_en; > > + uint32_t iof_sel; > > + uint32_t out_xor; > > +} fe310_gpio_t; > > + > > + > > + > > +#endif /* FE310_GPIO_H */ > > diff --git a/c/src/lib/libbsp/riscv32/hifive1/include/fe310-uart.h > b/c/src/lib/libbsp/riscv32/hifive1/include/fe310-uart.h > > new file mode 100644 > > index 0000000..78210b4 > > --- /dev/null > > +++ b/c/src/lib/libbsp/riscv32/hifive1/include/fe310-uart.h > > @@ -0,0 +1,38 @@ > > +/* > > + * Copyright (c) 2017 Denis Obrezkov <denisobrez...@gmail.com> > > + * > > + * 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 FE310_UART_H > > +#define FE310_UART_H > > + > > + > > +#include <rtems/termiostypes.h> > > +#include <rtems/irq.h> > > + > > +typedef struct { > > + uint32_t txdata; > > + uint32_t rxdata; > > + uint32_t txctrl; > > + uint32_t rxctrl; > > + uint32_t ie; > > + uint32_t ip; > > + uint32_t div; > > +} fe310_uart_t; > > + > > +/* Low-level driver specific data structure */ > > +typedef struct { > > + rtems_termios_device_context base; > > + const char *device_name; > > + volatile fe310_uart_t *regs; > > +} fe310_uart_context; > > + > > + > > +extern const rtems_termios_device_handler fe310_uart_handler_polled; > > + > > +extern fe310_uart_context driver_context; > > + > > +#endif /* FE310_UART_H */ > > -- > > 2.1.4 > > > > _______________________________________________ > > devel mailing list > > devel@rtems.org > > http://lists.rtems.org/mailman/listinfo/devel > My example was TMS570's console code, but, honestly, I don't like that the console code and uart code are mixed together. Though, again, I have no time to reimplement it now, but I agree that uart part should be separated from the console abstraction.
-- Regards, Denis Obrezkov
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel