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