summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/csb337/console
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-12-08 08:05:04 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-12-08 13:03:50 +0100
commitb748dffebcbcc8089e9774da512f01871c86035b (patch)
treed068b6d78d94df7a8dc9a87f89d40ac3990e3d9c /c/src/lib/libbsp/arm/csb337/console
parentbsp/smdk2410: Move libcpu files to BSP (diff)
downloadrtems-b748dffebcbcc8089e9774da512f01871c86035b.tar.bz2
bsp/csb337: Move libcpu files to BSP
Update #3254.
Diffstat (limited to 'c/src/lib/libbsp/arm/csb337/console')
-rw-r--r--c/src/lib/libbsp/arm/csb337/console/dbgu.c223
-rw-r--r--c/src/lib/libbsp/arm/csb337/console/usart.c261
2 files changed, 484 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/csb337/console/dbgu.c b/c/src/lib/libbsp/arm/csb337/console/dbgu.c
new file mode 100644
index 0000000000..1a16762e32
--- /dev/null
+++ b/c/src/lib/libbsp/arm/csb337/console/dbgu.c
@@ -0,0 +1,223 @@
+/*
+ * Console driver for AT91RM9200 DBGU port
+ *
+ * This driver uses the shared console driver in
+ * ...../libbsp/shared/console.c
+ *
+ * Copyright (c) 2003 by Cogent Computer Systems
+ * Written by Mike Kelly <mike@cogcomp.com>
+ * and Jay Monkman <jtm@lopingdog.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 <bsp.h>
+#include <rtems/libio.h>
+#include <termios.h>
+
+#include <at91rm9200.h>
+#include <at91rm9200_dbgu.h>
+#include <at91rm9200_pmc.h>
+#include <rtems/bspIo.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+volatile int dbg_dly;
+
+/* static function prototypes */
+static int dbgu_first_open(int major, int minor, void *arg);
+static int dbgu_last_close(int major, int minor, void *arg);
+static int dbgu_read(int minor);
+static ssize_t dbgu_write(int minor, const char *buf, size_t len);
+static void dbgu_init(int minor);
+static void dbgu_write_polled(int minor, char c);
+static int dbgu_set_attributes(int minor, const struct termios *t);
+
+/* Pointers to functions for handling the UART. */
+const console_fns dbgu_fns =
+{
+ libchip_serial_default_probe,
+ dbgu_first_open,
+ dbgu_last_close,
+ dbgu_read,
+ dbgu_write,
+ dbgu_init,
+ dbgu_write_polled, /* not used in this driver */
+ dbgu_set_attributes,
+ FALSE /* TRUE if interrupt driven, FALSE if not. */
+};
+/*********************************************************************/
+/* Functions called via callbacks (i.e. the ones in uart_fns */
+/*********************************************************************/
+
+/*
+ * This is called the first time each device is opened. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd enable interrupts here.
+ */
+static int dbgu_first_open(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * This is called the last time each device is closed. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd disable interrupts here.
+ */
+static int dbgu_last_close(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * Read one character from UART.
+ *
+ * return -1 if there's no data, otherwise return
+ * the character in lowest 8 bits of returned int.
+ */
+static int dbgu_read(int minor)
+{
+ char c;
+ console_tbl *console_entry;
+ at91rm9200_dbgu_regs_t *dbgu;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL) {
+ return -1;
+ }
+
+ dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
+
+ if (!(dbgu->sr & DBGU_INT_RXRDY)) {
+ return -1;
+ }
+
+ c = dbgu->rhr & 0xff;
+
+ return c;
+}
+
+
+/*
+ * Write buffer to UART
+ *
+ * return 1 on success, -1 on error
+ */
+static ssize_t dbgu_write(int minor, const char *buf, size_t len)
+{
+ int i, x;
+ char c;
+ console_tbl *console_entry;
+ at91rm9200_dbgu_regs_t *dbgu;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL) {
+ return -1;
+ }
+
+ dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
+
+ for (i = 0; i < len; i++) {
+ /* Wait for fifo to have room */
+ while(1) {
+ if (dbgu->sr & DBGU_INT_TXRDY) {
+ break;
+ }
+ }
+
+ c = (char) buf[i];
+ dbgu->thr = c;
+
+ /* the TXRDY flag does not seem to update right away (is this true?) */
+ /* so we wait a bit before continuing */
+ for (x = 0; x < 100; x++) {
+ dbg_dly++; /* using a global so this doesn't get optimized out */
+ }
+ }
+
+ return 1;
+}
+
+
+/* Set up the UART. */
+static void dbgu_init(int minor)
+{
+ console_tbl *console_entry;
+ at91rm9200_dbgu_regs_t *dbgu;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL) {
+ return;
+ }
+
+ dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
+
+ /* Clear error bits, and reset */
+ dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX);
+
+ /* Clear pending interrupts */
+ dbgu->idr = DBGU_INT_ALL;
+ dbgu->imr = 0;
+
+ /* Set port to no parity, no loopback */
+ dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM;
+
+ /* Set the baud rate */
+ dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud();
+
+ /* Enable the DBGU */
+ dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN);
+}
+
+/* This is used for getchark support */
+static void dbgu_write_polled(int minor, char c)
+{
+ dbgu_write(minor, &c, 1);
+}
+
+/* This is for setting baud rate, bits, etc. */
+static int dbgu_set_attributes(int minor, const struct termios *t)
+{
+ return 0;
+}
+
+/***********************************************************************/
+/*
+ * The following functions are not used by TERMIOS, but other RTEMS
+ * functions use them instead.
+ */
+/***********************************************************************/
+/*
+ * Read from UART. This is used in the exit code, and can't
+ * rely on interrupts.
+ */
+static int dbgu_poll_read(int minor)
+{
+ return dbgu_read(minor);
+}
+
+
+/*
+ * Write a character to the console. This is used by printk() and
+ * maybe other low level functions. It should not use interrupts or any
+ * RTEMS system calls. It needs to be very simple
+ */
+static void _BSP_put_char( char c ) {
+ dbgu_write_polled(0, c);
+}
+
+BSP_output_char_function_type BSP_output_char = _BSP_put_char;
+
+static int _BSP_poll_char(void)
+{
+ return dbgu_poll_read(0);
+}
+
+BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;
diff --git a/c/src/lib/libbsp/arm/csb337/console/usart.c b/c/src/lib/libbsp/arm/csb337/console/usart.c
new file mode 100644
index 0000000000..23b877ce64
--- /dev/null
+++ b/c/src/lib/libbsp/arm/csb337/console/usart.c
@@ -0,0 +1,261 @@
+/*
+ * Driver for AT91RM9200 USART ports
+ */
+
+/*
+ * COPYRIGHT (c) 2006-2009.
+ * NCB - Sistemas Embarcados Ltda. (Brazil)
+ * Fernando Nicodemos <fgnicodemos@terra.com.br>
+ *
+ * and
+ *
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 <bsp.h>
+#include <rtems/libio.h>
+#include <termios.h>
+
+#include <at91rm9200.h>
+#include <at91rm9200_usart.h>
+#include <at91rm9200_pmc.h>
+#include <rtems/bspIo.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+/* static function prototypes */
+static int usart_first_open(int major, int minor, void *arg);
+static int usart_last_close(int major, int minor, void *arg);
+static int usart_read_polled(int minor);
+static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
+static void usart_init(int minor);
+static void usart_write_polled(int minor, char c);
+static int usart_set_attributes(int minor, const struct termios *t);
+at91rm9200_usart_regs_t *usart_get_base(int minor);
+
+/* Pointers to functions for handling the UART polled. */
+const console_fns usart_polling_fns = {
+ libchip_serial_default_probe, /* deviceProbe */
+ usart_first_open, /* deviceFirstOpen */
+ usart_last_close, /* deviceLastClose */
+ usart_read_polled, /* deviceRead */
+ usart_write_polled_support, /* deviceWrite */
+ usart_init, /* deviceInitialize */
+ usart_write_polled, /* deviceWritePolled */
+ usart_set_attributes, /* deviceSetAttributes */
+ FALSE /* TRUE if interrupt driven, FALSE if not. */
+};
+
+at91rm9200_usart_regs_t *usart_get_base(int minor)
+{
+ console_tbl *console_entry;
+ at91rm9200_usart_regs_t *port;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL)
+ return 0;
+
+ port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
+ //printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port );
+
+ return port;
+}
+
+/*
+ * Functions called via callbacks (i.e. the ones in uart_fns
+ */
+
+/*
+ * This is called the first time each device is opened. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd enable interrupts here.
+ */
+static int usart_first_open(int major, int minor, void *arg)
+{
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return -1;
+
+ /* XXX port isn't being initialized or enabled */
+
+ /* XXX I hope this is enough */
+ usart->cr = (US_CR_RXEN | US_CR_TXEN);
+ return 0;
+}
+
+/*
+ * This is called the last time each device is closed. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd disable interrupts here.
+ */
+static int usart_last_close(int major, int minor, void *arg)
+{
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Read one character from UART.
+ *
+ * return -1 if there's no data, otherwise return
+ * the character in lowest 8 bits of returned int.
+ */
+static int usart_read_polled(int minor)
+{
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return -1;
+
+ /* if nothing ready return -1 */
+ if ( (usart->sr & US_IER_RXRDY) == 0 )
+ return -1;
+
+ return usart->rhr;
+}
+
+
+/*
+ * Write character out
+ */
+static void usart_write_polled(int minor, char c)
+{
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return;
+
+ /* delay until TX empty */
+ while ( (usart->sr & US_IER_TXEMPTY) == 0 )
+ ;
+
+ usart->thr = c;
+}
+
+/*
+ * Write buffer to UART
+ *
+ * return 1 on success, -1 on error
+ */
+static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
+{
+ at91rm9200_usart_regs_t *usart;
+ int nwrite=0;
+
+ /*
+ * Verify the minor number
+ */
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return -1;
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len) {
+ usart_write_polled(minor, *buf++);
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+
+ return 1;
+}
+
+
+/* Set up the UART. */
+static void usart_init(int minor)
+{
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return;
+
+}
+
+
+/* This is for setting baud rate, bits, etc. */
+static int usart_set_attributes(int minor, const struct termios *t)
+{
+ uint32_t brgr;
+ uint32_t mode, baud, baud_requested;
+ at91rm9200_usart_regs_t *usart;
+
+ usart = usart_get_base(minor);
+ if ( !usart )
+ return -1;
+
+ /* Get current mode register */
+ mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
+ | US_MR_PAR | US_MR_NBSTOP);
+
+ /* Byte size */
+ switch (t->c_cflag & CSIZE){
+ case CS5:
+ mode |= US_MR_CHRL_5;
+ break;
+ case CS6:
+ mode |= US_MR_CHRL_6;
+ break;
+ case CS7:
+ mode |= US_MR_CHRL_7;
+ break;
+ default:
+ mode |= US_MR_CHRL_8;
+ break;
+ }
+
+ /* Stop bits */
+ if (t->c_cflag & CSTOPB){
+ mode |= US_MR_NBSTOP_2; /* 2 stop bits */
+ } else
+ mode |= US_MR_NBSTOP_1; /* 1 stop bits */
+
+ /* Parity */
+ if (t->c_cflag & PARENB){
+ /* Mark or Space parity */
+ if (t->c_cflag & PARODD){
+ mode |= US_MR_PAR_ODD;
+ } else
+ mode |= US_MR_PAR_EVEN;
+ } else
+ mode |= US_MR_PAR_NONE;
+
+ baud_requested = t->c_ospeed;
+
+ /* If not, set the dbgu console baud as USART baud default */
+ if (!baud_requested)
+ baud_requested = BSP_get_baud();
+
+ baud = rtems_termios_baud_to_number(baud_requested);
+
+ brgr = (at91rm9200_get_mck() / 16) / baud;
+
+ if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */
+ brgr /= 8;
+ mode |= US_MR_USCLKS_MCK_DIV8;
+ }
+
+ usart->mr = mode;
+ usart->brgr = brgr;
+ return 0;
+}