diff options
Diffstat (limited to 'bsps/arm/gumstix/console/ffuart.c')
-rw-r--r-- | bsps/arm/gumstix/console/ffuart.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/bsps/arm/gumstix/console/ffuart.c b/bsps/arm/gumstix/console/ffuart.c new file mode 100644 index 0000000000..335fc6f4de --- /dev/null +++ b/bsps/arm/gumstix/console/ffuart.c @@ -0,0 +1,227 @@ +/* + * Console driver for pxa255 full function port by Yang Xi <hiyangxi@gmail.com> + * Copyright (c) 2004 by 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 <pxa255.h> +#include <ffuart.h> +#include <rtems/bspIo.h> +#include <libchip/serial.h> +#include <libchip/sersupp.h> + +volatile int dbg_dly; + +/* static function prototypes */ +static int ffuart_first_open(int major, int minor, void *arg); +static int ffuart_last_close(int major, int minor, void *arg); +static int ffuart_read(int minor); +static ssize_t ffuart_write(int minor, const char *buf, size_t len); +static void ffuart_init(int minor); +static void ffuart_write_polled(int minor, char c); +static int ffuart_set_attributes(int minor, const struct termios *t); + +/* Pointers to functions for handling the UART. */ +const console_fns ffuart_fns = +{ + libchip_serial_default_probe, + ffuart_first_open, + ffuart_last_close, + ffuart_read, + ffuart_write, + ffuart_init, + ffuart_write_polled, /* not used in this driver */ + ffuart_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; + + +/* + * 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 ffuart_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 ffuart_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 ffuart_read(int minor) +{ + char c; + console_tbl *console_entry; + ffuart_reg_t *ffuart; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + + if (!(ffuart->lsr & FULL_RECEIVE)) { + return -1; + } + + c = ffuart->rbr & 0xff; + + return c; +} + + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t ffuart_write(int minor, const char *buf, size_t len) +{ + size_t i, x; + char c; + console_tbl *console_entry; + ffuart_reg_t *ffuart; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + + for (i = 0; i < len; i++) { + + while(1) { + if (ffuart->lsr & SEND_EMPTY) { + break; + } + } + + c = (char) buf[i]; +#if ON_SKYEYE != 1 + if(c=='\n'){ + ffuart->rbr = '\r'; + for (x = 0; x < 100; x++) { + dbg_dly++; /* using a global so this doesn't get optimized out */ + } + while(1){ + if(ffuart->lsr & SEND_EMPTY){ + break; + } + } + } +#endif + ffuart->rbr = 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; +} + + +static void ffuart_init(int minor) +{ + + + console_tbl *console_entry; + ffuart_reg_t *ffuart; + unsigned int divisor; + + console_entry = BSP_get_uart_from_minor(minor); + + + + if (console_entry == NULL) { + return; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + ffuart->lcr |= DLAB; + /*Set the Bound*/ + ffuart->lcr |= DLAB; + divisor = FREQUENCY_UART / (115200*16); + ffuart->rbr = divisor & 0xff; + ffuart->ier = (divisor >> 8)&0xff; + /*Disable FIFO*/ + ffuart->iir = 0; + ffuart->lcr &=~DLAB; + /*Enable UART*/ + ffuart->ier = 0x40; + ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT; + +} + +/* I'm not sure this is needed for the shared console driver. */ +static void ffuart_write_polled(int minor, char c) +{ + ffuart_write(minor, &c, 1); +} + +/* This is for setting baud rate, bits, etc. */ +static int ffuart_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 ffuart_poll_read(int minor) +{ + return ffuart_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 ) { + ffuart_write_polled(0, c); +} + +static int _BSP_poll_char(void) { + return ffuart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; +BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; |