diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-19 06:28:01 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 13:08:32 +0200 |
commit | d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch) | |
tree | caa54b4229e86a68c84ab5961af34e087dce5302 /bsps/arm/rtl22xx | |
parent | bsps/powerpc: Move shared btimer support (diff) | |
download | rtems-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.h | 187 | ||||
-rw-r--r-- | bsps/arm/rtl22xx/console/uart.c | 283 |
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 ); + } +} |