[PATCH 12/15] HiFive1: add UART support

Denis Obrezkov denisobrezkov at gmail.com
Mon Aug 21 20:46:14 UTC 2017


2017-08-17 17:21 GMT+02:00 Gedare Bloom <gedare at 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
> <denisobrezkov at 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 <denisobrezkov at 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 <denisobrezkov at 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 <denisobrezkov at 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 at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20170821/16ff8480/attachment-0001.html>


More information about the devel mailing list