summaryrefslogtreecommitdiffstats
path: root/bsps/arm/rtl22xx
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-19 06:28:01 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:32 +0200
commitd7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch)
treecaa54b4229e86a68c84ab5961af34e087dce5302 /bsps/arm/rtl22xx
parentbsps/powerpc: Move shared btimer support (diff)
downloadrtems-d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc.tar.bz2
bsps: Move console drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'bsps/arm/rtl22xx')
-rw-r--r--bsps/arm/rtl22xx/console/lpc22xx_uart.h187
-rw-r--r--bsps/arm/rtl22xx/console/uart.c283
2 files changed, 470 insertions, 0 deletions
diff --git a/bsps/arm/rtl22xx/console/lpc22xx_uart.h b/bsps/arm/rtl22xx/console/lpc22xx_uart.h
new file mode 100644
index 0000000000..f6ae249672
--- /dev/null
+++ b/bsps/arm/rtl22xx/console/lpc22xx_uart.h
@@ -0,0 +1,187 @@
+/**
+ * @file
+ * @ingroup rtl22xx_uart
+ * @brief UART support.
+ */
+
+#ifndef LPC22XX_UART_H
+#define LPC22XX_UART_H
+
+/**
+ * @defgroup rtl22xx_uart UART Support
+ * @ingroup arm_rtl22xx
+ * @brief UART (Universal Asynchronous Reciever/Transmitter) Support
+ * @{
+ */
+
+#define FIFODEEP 16
+
+#define BD115200 115200
+#define BD38400 38400
+#define BD9600 9600
+
+/** @brief PINSEL0 Value for UART0 */
+#define U0_PINSEL (0x00000005)
+/** @brief PINSEL0 Mask for UART0 */
+#define U0_PINMASK (0x0000000F)
+/** @brief PINSEL0 Value for UART1 */
+#define U1_PINSEL (0x00050000)
+/** @brief PINSEL0 Mask for UART1 */
+#define U1_PINMASK (0x000F0000)
+
+/**
+ * @name Uart line control register bit descriptions
+ * @{
+ */
+
+#define LCR_WORDLENTH_BIT 0
+#define LCR_STOPBITSEL_BIT 2
+#define LCR_PARITYENBALE_BIT 3
+#define LCR_PARITYSEL_BIT 4
+#define LCR_BREAKCONTROL_BIT 6
+#define LCR_DLAB_BIT 7
+
+/** @} */
+
+/**
+ * @name Line Control Register bit definitions
+ * @{
+ */
+
+/** @brief 5-bit character length */
+#define ULCR_CHAR_5 (0 << 0)
+/** @brief 6-bit character length */
+#define ULCR_CHAR_6 (1 << 0)
+/** @brief 7-bit character length */
+#define ULCR_CHAR_7 (2 << 0)
+/** @brief 8-bit character length */
+#define ULCR_CHAR_8 (3 << 0)
+/** @brief no stop bits */
+#define ULCR_STOP_0 (0 << 2)
+/** @brief 1 stop bit */
+#define ULCR_STOP_1 (1 << 2)
+/** @brief No Parity */
+#define ULCR_PAR_NO (0 << 3)
+/** @brief Odd Parity */
+#define ULCR_PAR_ODD (1 << 3)
+/** @brief Even Parity */
+#define ULCR_PAR_EVEN (3 << 3)
+/** @brief MARK "1" Parity */
+#define ULCR_PAR_MARK (5 << 3)
+/** @brief SPACE "0" Paruty */
+#define ULCR_PAR_SPACE (7 << 3)
+/** @brief Output BREAK line condition */
+#define ULCR_BREAK_ENABLE (1 << 6)
+/** @brief Enable Divisor Latch Access */
+#define ULCR_DLAB_ENABLE (1 << 7)
+
+/** @} */
+
+/**
+ * @name Modem Control Register bit definitions
+ * @{
+ */
+
+/** @brief Data Terminal Ready */
+#define UMCR_DTR (1 << 0)
+/** @brief Request To Send */
+#define UMCR_RTS (1 << 1)
+/** @brief Loopback */
+#define UMCR_LB (1 << 4)
+
+/** @} */
+
+/**
+ * @name Line Status Register bit definitions
+ * @{
+ */
+
+/** @brief Receive Data Ready */
+#define ULSR_RDR (1 << 0)
+/** @brief Overrun Error */
+#define ULSR_OE (1 << 1)
+/** @brief Parity Error */
+#define ULSR_PE (1 << 2)
+/** @brief Framing Error */
+#define ULSR_FE (1 << 3)
+/** @brief Break Interrupt */
+#define ULSR_BI (1 << 4)
+/** @brief Transmit Holding Register Empty */
+#define ULSR_THRE (1 << 5)
+/** @brief Transmitter Empty */
+#define ULSR_TEMT (1 << 6)
+/** @brief Error in Receive FIFO */
+#define ULSR_RXFE (1 << 7)
+#define ULSR_ERR_MASK 0x1E
+
+/** @} */
+
+/**
+ * @name Modem Status Register bit definitions
+ * @{
+ */
+
+/** @brief Delta Clear To Send */
+#define UMSR_DCTS (1 << 0)
+/** @brief Delta Data Set Ready */
+#define UMSR_DDSR (1 << 1)
+/** @brief Trailing Edge Ring Indicator */
+#define UMSR_TERI (1 << 2)
+/** @brief Delta Data Carrier Detect */
+#define UMSR_DDCD (1 << 3)
+/** @brief Clear To Send */
+#define UMSR_CTS (1 << 4)
+/** @brief Data Set Ready */
+#define UMSR_DSR (1 << 5)
+/** @brief Ring Indicator */
+#define UMSR_RI (1 << 6)
+/** @brief Data Carrier Detect */
+#define UMSR_DCD (1 << 7)
+
+/** @} */
+
+/**
+ * @name Uart Interrupt Identification
+ * @{
+ */
+
+#define IIR_RSL 0x3
+#define IIR_RDA 0x2
+#define IIR_CTI 0x6
+#define IIR_THRE 0x1
+
+/** @} */
+
+/**
+ * @name Uart Interrupt Enable Type
+ * @{
+ */
+
+#define IER_RBR 0x1
+#define IER_THRE 0x2
+#define IER_RLS 0x4
+
+/** @} */
+
+/**
+ * @name Uart Receiver Errors
+ * @{
+ */
+
+#define RC_FIFO_OVERRUN_ERR 0x1
+#define RC_OVERRUN_ERR 0x2
+#define RC_PARITY_ERR 0x4
+#define RC_FRAMING_ERR 0x8
+#define RC_BREAK_IND 0x10
+
+/** @} */
+
+typedef enum {
+ UART0 = 0,
+ UART1
+} LPC_UartChanel_t;
+
+/** @} */
+
+#endif
+
diff --git a/bsps/arm/rtl22xx/console/uart.c b/bsps/arm/rtl22xx/console/uart.c
new file mode 100644
index 0000000000..2952e74508
--- /dev/null
+++ b/bsps/arm/rtl22xx/console/uart.c
@@ -0,0 +1,283 @@
+/*
+ * console driver for RTL22xx UARTs
+ *
+ * If you want the driver to be interrupt driven, you
+ * need to write the ISR, and in the ISR insert the
+ * chars into termios's queue.
+ */
+
+/*
+ * Copyright (c) By ray <rayx.cn@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 <bsp.h> /* Must be before libio.h */
+#include <rtems/libio.h>
+#include <termios.h>
+#include <rtems/bspIo.h>
+
+/* Put the CPU (or UART) specific header file #include here */
+#include <lpc22xx.h>
+#include "lpc22xx_uart.h"
+
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+/* How many serial ports? */
+#define NUM_DEVS 1
+
+int dbg_dly;
+
+/* static function prototypes */
+static int uart_first_open(int major, int minor, void *arg);
+static int uart_last_close(int major, int minor, void *arg);
+static int uart_read(int minor);
+static ssize_t uart_write(int minor, const char *buf, size_t len);
+static void uart_init(int minor);
+static void uart_write_polled(int minor, char c);
+static int uart_set_attributes(int minor, const struct termios *t);
+
+/* These are used by code in console.c */
+unsigned long Console_Configuration_Count = NUM_DEVS;
+
+/* Pointers to functions for handling the UART. */
+const console_fns uart_fns = {
+ libchip_serial_default_probe,
+ uart_first_open,
+ uart_last_close,
+ uart_read,
+ uart_write,
+ uart_init,
+ uart_write_polled, /* not used in this driver */
+ uart_set_attributes,
+ FALSE /* TRUE if interrupt driven, FALSE if not. */
+};
+
+/*
+ * There's one item in array for each UART.
+ *
+ * Some of these fields are marked "NOT USED". They are not used
+ * by console.c, but may be used by drivers in libchip
+ */
+console_tbl Console_Configuration_Ports[] = {
+{
+ "/dev/com0", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &uart_fns, /* pDeviceFns */
+ NULL, /* deviceProbe */
+ NULL, /* pDeviceFlow */
+ 0, /* ulMargin - NOT USED */
+ 0, /* ulHysteresis - NOT USED */
+ NULL, /* pDeviceParams */
+ 0, /* ulCtrlPort1 - NOT USED */
+ 0, /* ulCtrlPort2 - NOT USED */
+ 0, /* ulDataPort - NOT USED */
+ NULL, /* getRegister - NOT USED */
+ NULL, /* setRegister - NOT USED */
+ NULL, /* getData - NOT USED */
+ NULL, /* setData - NOT USED */
+ 0, /* ulClock - NOT USED */
+ 0 /* ulIntVector - NOT USED */
+}
+#if 0
+{
+ "/dev/com1", /* sDeviceName */
+ SERIAL_CUSTOM, /* deviceType */
+ &uart_fns, /* pDeviceFns */
+ NULL, /* deviceProbe */
+ NULL, /* pDeviceFlow */
+ 0, /* ulMargin - NOT USED */
+ 0, /* ulHysteresis - NOT USED */
+ NULL, /* pDeviceParams */
+ 0, /* ulCtrlPort1 - NOT USED */
+ 0, /* ulCtrlPort2 - NOT USED */
+ 0, /* ulDataPort - NOT USED */
+ NULL, /* getRegister - NOT USED */
+ NULL, /* setRegister - NOT USED */
+ NULL, /* getData - NOT USED */
+ NULL, /* setData - NOT USED */
+ 0, /* ulClock - NOT USED */
+ 0 /* ulIntVector - NOT USED */
+}
+#endif
+};
+
+/*
+ * This is called the first time each device is opened. If the driver
+ * is interrupt driven, you should enable interrupts here. Otherwise,
+ * it's probably safe to do nothing.
+ *
+ * Since micromonitor already set up the UART, we do nothing.
+ */
+static int uart_first_open(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+/*
+ * This is called the last time each device is closed. If the driver
+ * is interrupt driven, you should disable interrupts here. Otherwise,
+ * it's probably safe to do nothing.
+ */
+static int uart_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 uart_read(int minor)
+{
+ char c;
+
+ switch (minor) {
+ case 0:
+ if (U0LSR & ULSR_RDR) {
+ c = U0RBR;
+ return c;
+ }
+ return -1;
+ case 1:
+ if (U1LSR & ULSR_RDR) {
+ c = U1RBR;
+ return c;
+ }
+ return -1;
+ default:
+ break;
+ }
+ printk("Unknown console minor number %d\n", minor);
+ return -1;
+}
+
+/*
+ * Write buffer to UART
+ *
+ * return 1 on success, -1 on error
+ */
+static ssize_t uart_write(int minor, const char *buf, size_t len)
+{
+ size_t i;
+
+ switch (minor) {
+ case 0:
+ for (i = 0; i < len; i++) {
+ while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
+ continue; /* also either WDOG() or swap()*/
+ U0THR = (char) buf[i];
+ }
+ break;
+ case 1:
+ for (i = 0; i < len; i++) {
+ while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
+ continue; /* also either WDOG() or swap()*/
+ U0THR = (char) buf[i];
+ }
+ break;
+ default:
+ printk("Unknown console minor number %d\n", minor);
+ return -1;
+ }
+
+ return len;
+}
+
+/* Set up the UART. */
+static void uart_init(int minor)
+{
+#if 0 //init will be done in bspstart.c
+ int baud=6;
+ int mode =0x03;
+ if(minor==0){
+ // set port pins for UART0
+ PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
+
+ U0IER = 0x00; // disable all interrupts
+
+ // set the baudrate
+ U0LCR = 1<<7; // select divisor latches
+ U0DLL = (uint8_t)baud; // set for baud low byte
+ U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
+
+ // set the number of characters and other
+ // user specified operating parameters
+ U0LCR = (mode & ~ULCR_DLAB_ENABLE);
+ U0FCR = mode>>8; /*fifo mode*/
+
+ // set port pins for UART1
+ PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
+
+ U1IER = 0x00; // disable all interrupts
+ }else if(minor==1){
+ // set the baudrate
+ U1LCR = ULCR_DLAB_ENABLE; // select divisor latches
+ U1DLL = (uint8_t)baud; // set for baud low byte
+ U1DLM = (uint8_t)(baud >> 8); // set for baud high byte
+
+ // set the number of characters and other
+ // user specified operating parameters
+ U1LCR = (mode & ~ULCR_DLAB_ENABLE);
+ U1FCR = mode>>8;/*fifo mode*/
+ }
+
+#endif
+}
+
+/* I'm not sure this is needed for the shared console driver. */
+static void uart_write_polled(int minor, char c)
+{
+ uart_write(minor, &c, 1);
+}
+
+/* This is for setting baud rate, bits, etc. */
+static int uart_set_attributes(int minor, const struct termios *t)
+{
+ return 0;
+}
+
+/*
+ * 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 )
+{
+ uart_write_polled(0, c);
+}
+
+BSP_output_char_function_type BSP_output_char = _BSP_put_char;
+
+static int _BSP_get_char(void)
+{
+ return uart_read(0);
+}
+
+BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
+
+/*
+ * init USART 0ĄŁ8 bit, 1 Stop,No checkout, BPS115200
+ */
+void UART0_Ini(void)
+{
+ long Fdiv;
+ int i;
+
+ PINSEL0 = 0x00000005; // I/O to UART0
+ U0LCR = 0x83; // DLAB = 1
+ Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS
+ U0DLM = Fdiv/256;
+ U0DLL = Fdiv%256;
+ U0LCR = 0x03;
+
+ for(i=0;i<10;i++){
+ U0THR = 67; //send a C to see if is OK
+ while ( (U0LSR&0x40)==0 );
+ }
+}