X-Git-Url: http://rtime.felk.cvut.cz/gitweb/rtems-devel.git/blobdiff_plain/b43d26bd4d8cb9dda0fe9be21883dffde1f775af..e3003e37814bd44142fd2965a72b8f8b9c95dfb4:/rtems-patches/applied/rtems-csb336-20051008-uart.patch diff --git a/rtems-patches/applied/rtems-csb336-20051008-uart.patch b/rtems-patches/applied/rtems-csb336-20051008-uart.patch deleted file mode 100644 index 292feea..0000000 --- a/rtems-patches/applied/rtems-csb336-20051008-uart.patch +++ /dev/null @@ -1,664 +0,0 @@ -Index: rtems/c/src/lib/libbsp/arm/csb336/console/uart.c -=================================================================== ---- rtems.orig/c/src/lib/libbsp/arm/csb336/console/uart.c -+++ rtems/c/src/lib/libbsp/arm/csb336/console/uart.c -@@ -1,262 +1,453 @@ - /* -- * console driver for MC9328XML UARTs -+ * Console driver for MC9328XML UARTs. - * -- * This driver uses the shared console driver in -- * ...../libbsp/shared/console.c -+ * Written Jay Monkman -+ * Copyright (c) 2005 by Loping Dog Embedded Systems - * -- * 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. -+ * The license and distribution terms for this file may be -+ * found in the file LICENSE in this distribution or at -+ * http://www.rtems.com/license - * -- * Copyright (c) 2004 Cogent Computer Systems -- * Written by Jay Monkman -- * -- * The license and distribution terms for this file may be -- * found in the file LICENSE in this distribution or at -- * -- * http://www.OARcorp.com/rtems/license.html. -- * -- * -- * $Id: uart.c,v 1.1 2004/07/15 06:12:05 jtm Exp $ --*/ --#include /* Must be before libio.h */ -+ * $Id:$ -+ */ -+#include - #include --#include -+#include -+#include - #include -- --/* Put the CPU (or UART) specific header file #include here */ -+#include -+#include - #include --#include --#include -+ -+ -+/* Define this to use interrupt driver UART driver */ -+#define USE_INTERRUPTS 1 - - /* How many serial ports? */ - #define NUM_DEVS 2 -+#define poll_write(c) imx_uart_poll_write_char(0, c) -+#define poll_read() imx_uart_poll_read_char(0) - --int uart_poll_read(int minor); -+static int imx_uart_first_open(int, int, void *); -+static int imx_uart_last_close(int, int, void *); -+static int imx_uart_poll_read(int); -+static int imx_uart_set_attrs(int, const struct termios *); -+static void imx_uart_init(int minor); -+static void imx_uart_set_baud(int, int); -+static int imx_uart_poll_write(int, const char *, int); -+ -+#if defined(USE_INTERRUPTS) -+static void imx_uart_tx_isr(rtems_irq_hdl_param); -+static void imx_uart_rx_isr(rtems_irq_hdl_param); -+static void imx_uart_isr_on(const rtems_irq_connect_data *irq); -+static void imx_uart_isr_off(const rtems_irq_connect_data *irq); -+static int imx_uart_isr_is_on(const rtems_irq_connect_data *irq); -+static int imx_uart_intr_write(int, const char *, int); -+#endif - --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 int uart_write(int minor, const char *buf, int 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_Port_Count = NUM_DEVS; --console_data Console_Port_Data[NUM_DEVS]; -- --/* rtems console uses the following minor number */ --rtems_device_minor_number Console_Port_Minor = 0; -- --/* Pointers to functions for handling the UART. */ --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. */ -+ -+/* TERMIOS callbacks */ -+#if defined(USE_INTERRUPTS) -+rtems_termios_callbacks imx_uart_cbacks = { -+ .firstOpen = imx_uart_first_open, -+ .lastClose = imx_uart_last_close, -+ .pollRead = NULL, -+ .write = imx_uart_intr_write, -+ .setAttributes = imx_uart_set_attrs, -+ .stopRemoteTx = NULL, -+ .startRemoteTx = NULL, -+ .outputUsesInterrupts = 1, -+}; -+#else -+rtems_termios_callbacks imx_uart_cbacks = { -+ .firstOpen = imx_uart_first_open, -+ .lastClose = imx_uart_last_close, -+ .pollRead = imx_uart_poll_read, -+ .write = imx_uart_poll_write, -+ .setAttributes = imx_uart_set_attrs, -+ .stopRemoteTx = NULL, -+ .startRemoteTx = NULL, -+ .outputUsesInterrupts = 0, - }; -+#endif - --/* -- * 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_Port_Tbl[] = { -- { -- "/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 */ -- }, -- { -- "/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 */ -+#if defined(USE_INTERRUPTS) -+static rtems_irq_connect_data imx_uart_tx_isr_data[NUM_DEVS]; -+static rtems_irq_connect_data imx_uart_rx_isr_data[NUM_DEVS]; -+#endif -+ -+typedef struct { -+ int minor; -+ mc9328mxl_uart_regs_t * regs; -+ volatile const char *buf; -+ volatile int len; -+ volatile int idx; -+ void *tty; -+} imx_uart_data_t; -+ -+static imx_uart_data_t imx_uart_data[NUM_DEVS]; -+ -+rtems_device_driver console_initialize( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void *arg -+) -+{ -+ rtems_status_code status; -+ int i; -+ -+ for (i = 0; i < NUM_DEVS; i++) { -+ imx_uart_init(i); - } --}; - --/*********************************************************************/ --/* Functions called via termios callbacks (i.e. the ones in uart_fns */ --/*********************************************************************/ -- --/* -- * 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) -+ rtems_termios_initialize(); -+ -+ /* /dev/console and /dev/tty0 are the same */ -+ status = rtems_io_register_name("/dev/console", major, 0); -+ if (status != RTEMS_SUCCESSFUL) { -+ rtems_panic("%s:%d Error registering /dev/console :: %d\n", -+ __FUNCTION__, __LINE__, status); -+ } -+ -+ status = rtems_io_register_name("/dev/tty0", major, 0); -+ if (status != RTEMS_SUCCESSFUL) { -+ rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n", -+ __FUNCTION__, __LINE__, status); -+ } -+ -+ status = rtems_io_register_name("/dev/tty1", major, 1); -+ if (status != RTEMS_SUCCESSFUL) { -+ rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n", -+ __FUNCTION__, __LINE__, status); -+ } -+ return RTEMS_SUCCESSFUL; -+} -+ -+rtems_device_driver console_open( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void * arg -+) - { -- return 0; -+ rtems_status_code rc; -+ -+ if (minor > (NUM_DEVS - 1)) { -+ return RTEMS_INVALID_NUMBER; -+ } -+ -+ rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks); -+ -+ return rc; - } - -+rtems_device_driver console_close( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void * arg -+) -+{ -+ return rtems_termios_close(arg); -+} - --/* -- * 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) -+rtems_device_driver console_read( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void * arg -+) - { -- return 0; -+ return rtems_termios_read(arg); - } - -+rtems_device_driver console_write( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void * arg -+) -+{ -+ return rtems_termios_write(arg); -+} - --/* -- * 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) -+rtems_device_driver console_control( -+ rtems_device_major_number major, -+ rtems_device_minor_number minor, -+ void * arg -+) - { -- char c; -+ return rtems_termios_ioctl(arg); -+} -+ -+static void imx_uart_init(int minor) -+{ -+ imx_uart_data[minor].minor = minor; -+ imx_uart_data[minor].buf = NULL; -+ imx_uart_data[minor].len = 0; -+ imx_uart_data[minor].idx = 0; - - if (minor == 0) { -- if (MC9328MXL_UART1_SR2 & MC9328MXL_UART_SR2_RDR) { -- c = MC9328MXL_UART1_RXD & MC9328MXL_UART_RXD_CHARMASK; -- return c; -- } else { -- return -1; -- } -+#if defined(USE_INTERRUPTS) -+ imx_uart_tx_isr_data[minor].name = BSP_INT_UART1_TX; -+ imx_uart_rx_isr_data[minor].name = BSP_INT_UART1_RX; -+#endif -+ imx_uart_data[minor].regs = -+ (mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE; - } else if (minor == 1) { -- if (MC9328MXL_UART2_SR2 & MC9328MXL_UART_SR2_RDR) { -- c = MC9328MXL_UART2_RXD & MC9328MXL_UART_RXD_CHARMASK; -- return c; -- } else { -- return -1; -- } -+#if defined(USE_INTERRUPTS) -+ imx_uart_tx_isr_data[minor].name = BSP_INT_UART2_TX; -+ imx_uart_rx_isr_data[minor].name = BSP_INT_UART2_RX; -+#endif -+ imx_uart_data[minor].regs = -+ (mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE; - } else { -- printk("Unknown console minor number: %d\n", minor); -- return -1; -+ rtems_panic("%s:%d Unknown UART minor number %d\n", -+ __FUNCTION__, __LINE__, minor); - } - -+#if defined(USE_INTERRUPTS) -+ imx_uart_tx_isr_data[minor].hdl = imx_uart_tx_isr; -+ imx_uart_tx_isr_data[minor].handle = &imx_uart_data[minor]; -+ imx_uart_tx_isr_data[minor].on = imx_uart_isr_on; -+ imx_uart_tx_isr_data[minor].off = imx_uart_isr_off; -+ imx_uart_tx_isr_data[minor].isOn = imx_uart_isr_is_on; -+ -+ imx_uart_rx_isr_data[minor].hdl = imx_uart_rx_isr; -+ imx_uart_rx_isr_data[minor].handle = &imx_uart_data[minor]; -+ imx_uart_rx_isr_data[minor].on = imx_uart_isr_on; -+ imx_uart_rx_isr_data[minor].off = imx_uart_isr_off; -+ imx_uart_rx_isr_data[minor].isOn = imx_uart_isr_is_on; -+#endif -+ -+ imx_uart_data[minor].regs->cr1 = ( -+ MC9328MXL_UART_CR1_UARTCLKEN | -+ MC9328MXL_UART_CR1_UARTEN); -+ -+ imx_uart_data[minor].regs->cr2 = ( -+ MC9328MXL_UART_CR2_IRTS | -+ MC9328MXL_UART_CR2_WS | -+ MC9328MXL_UART_CR2_TXEN | -+ MC9328MXL_UART_CR2_RXEN | -+ MC9328MXL_UART_CR2_SRST); -+ -+ imx_uart_data[minor].regs->cr3 = 0; -+ -+ imx_uart_data[minor].regs->cr4 = 0; -+ -+ imx_uart_data[minor].regs->fcr = ( -+ MC9328MXL_UART_FCR_TXTL(32) | -+ MC9328MXL_UART_FCR_RFDIV_1 | -+ MC9328MXL_UART_FCR_RXTL(1)); -+ -+ imx_uart_set_baud(minor, 38400); -+ - } - -+static int imx_uart_first_open(int major, int minor, void *arg) -+{ -+ rtems_libio_open_close_args_t *args = arg; - --/* -- * Write buffer to UART -- * -- * return 1 on success, -1 on error -- */ --static int uart_write(int minor, const char *buf, int len) -+ imx_uart_data[minor].tty = args->iop->data1; -+ -+#if defined(USE_INTERRUPTS) -+ BSP_install_rtems_irq_handler(&imx_uart_tx_isr_data[minor]); -+ BSP_install_rtems_irq_handler(&imx_uart_rx_isr_data[minor]); -+ -+ imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN; -+#endif -+ -+ return 0; -+} -+ -+static int imx_uart_last_close(int major, int minor, void *arg) - { -- int i; -+#if defined(USE_INTERRUPTS) -+ BSP_remove_rtems_irq_handler(&imx_uart_tx_isr_data[minor]); -+ BSP_remove_rtems_irq_handler(&imx_uart_rx_isr_data[minor]); -+#endif - -- if (minor == 0) { -- for (i = 0; i < len; i++) { -- /* Wait for fifo to have room */ -- while(!(MC9328MXL_UART1_SR2 & MC9328MXL_UART_SR2_TXDC)) { -- continue; -- } -- -- MC9328MXL_UART1_TXD = (char) buf[i]; -- } -- } else if (minor == 1) { -- for (i = 0; i < len; i++) { -- /* Wait for fifo to have room */ -- while(!(MC9328MXL_UART2_SR2 & MC9328MXL_UART_SR2_TXDC)) { -- continue; -- } -- -- MC9328MXL_UART2_TXD = (char) buf[i]; -- } -+ return 0; -+} -+ -+static int imx_uart_poll_read(int minor) -+{ -+ if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) { -+ return imx_uart_data[minor].regs->rxd & 0xff; - } else { -- printk("Unknown console minor number: %d\n", minor); - return -1; - } -- -- return 1; - } - - --/* Set up the UART. */ --static void uart_init(int minor) -+static int imx_uart_poll_write(int minor, const char *buf, int len) - { -- /* leave the debug sio port as setup by umon */ -+ int i; -+ for (i = 0; i < len; i++) { -+ /* Wait for there to be room in the fifo */ -+ while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) { -+ continue; -+ } -+ -+ imx_uart_data[minor].regs->txd = buf[i]; -+ } -+ return 1; -+ - } - --/* I'm not sure this is needed for the shared console driver. */ --static void uart_write_polled(int minor, char c) -+#if defined(USE_INTERRUPTS) -+static int imx_uart_intr_write(int minor, const char *buf, int len) - { -- uart_write(minor, &c, 1); -+ imx_uart_data[minor].buf = buf; -+ imx_uart_data[minor].len = len; -+ imx_uart_data[minor].idx = 0; -+ -+ imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN; -+ -+ return 1; - } -+#endif -+ - - /* This is for setting baud rate, bits, etc. */ --static int uart_set_attributes(int minor, const struct termios *t) -+static int imx_uart_set_attrs(int minor, const struct termios *t) - { -+ int baud; -+ -+ baud = termios_baud_to_number(t->c_cflag & CBAUD); -+ imx_uart_set_baud(minor, baud); -+ - return 0; - } - --/***********************************************************************/ -+#if defined(USE_INTERRUPTS) -+static void imx_uart_isr_on(const rtems_irq_connect_data *irq) -+{ -+ MC9328MXL_AITC_INTENNUM = irq->name; -+} -+static void imx_uart_isr_off(const rtems_irq_connect_data *irq) -+{ -+ MC9328MXL_AITC_INTDISNUM = irq->name; -+} -+static int imx_uart_isr_is_on(const rtems_irq_connect_data *irq) -+{ -+ int irq_num = (int)irq->name; -+ if (irq_num < 32) { -+ return MC9328MXL_AITC_INTENABLEL & (1 << irq_num); -+ } else { -+ return MC9328MXL_AITC_INTENABLEH & (1 << (irq_num - 32)); -+ } -+} -+ -+static void imx_uart_rx_isr(rtems_irq_hdl_param param) -+{ -+ imx_uart_data_t *uart_data = param; -+ char buf[32]; -+ int i=0; -+ -+ while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) { -+ buf[i] = uart_data->regs->rxd & 0xff; -+ i++; -+ } -+ -+ rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i); -+} -+ -+static void imx_uart_tx_isr(rtems_irq_hdl_param param) -+{ -+ imx_uart_data_t *uart_data = param; -+ int len; -+ int minor = uart_data->minor; -+ -+ -+ if (uart_data->idx < uart_data->len) { -+ while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) && -+ (uart_data->idx < uart_data->len)) { -+ uart_data->regs->txd = uart_data->buf[uart_data->idx]; -+ uart_data->idx++; -+ } -+ } else { -+ len = uart_data->len; -+ uart_data->len = 0; -+ imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN; -+ rtems_termios_dequeue_characters(uart_data->tty, len); -+ } -+} -+#endif -+ - /* -- * The following functions are not used by TERMIOS, but other RTEMS -- * functions use them instead. -+ * Set the UART's baud rate. The calculation is: -+ * (baud * 16) / ref_freq = num/demom -+ * -+ * ref_freq = perclk1 / RFDIV[2:0] -+ * BIR = num - 1 -+ * BMR = demom - 1 -+ * -+ * Setting 'num' to 16 yields this equation: -+ * demom = ref_freq / baud - */ --/***********************************************************************/ --/* -- * Read from UART. This is used in the exit code, and can't -- * rely on interrupts. --*/ --int uart_poll_read(int minor) -+static void imx_uart_set_baud(int minor, int baud) - { -- return uart_read(minor); -+ unsigned int perclk1; -+ unsigned int denom; -+ unsigned int ref_freq = 0; -+ uint32_t fcr; -+ -+ perclk1 = get_perclk1_freq(); -+ fcr = imx_uart_data[minor].regs->fcr; -+ -+ switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) { -+ case MC9328MXL_UART_FCR_RFDIV_1: ref_freq = perclk1/1; break; -+ case MC9328MXL_UART_FCR_RFDIV_2: ref_freq = perclk1/2; break; -+ case MC9328MXL_UART_FCR_RFDIV_3: ref_freq = perclk1/3; break; -+ case MC9328MXL_UART_FCR_RFDIV_4: ref_freq = perclk1/4; break; -+ case MC9328MXL_UART_FCR_RFDIV_5: ref_freq = perclk1/5; break; -+ case MC9328MXL_UART_FCR_RFDIV_6: ref_freq = perclk1/6; break; -+ case MC9328MXL_UART_FCR_RFDIV_7: ref_freq = perclk1/7; break; -+ default: -+ rtems_panic("%s:%d Unknown RFDIV: 0x%x", -+ __FUNCTION__, __LINE__, -+ fcr & MC9328MXL_UART_FCR_RFDIV_MASK); -+ break; -+ } -+ -+ denom = ref_freq / baud; -+ -+ imx_uart_data[minor].regs->bir = 0xf; -+ imx_uart_data[minor].regs->bmr = denom; - } - - - /* -- * 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 -+ * Polled, non-blocking read from UART -+ */ -+int imx_uart_poll_read_char(int minor) -+{ -+ return imx_uart_poll_read(minor); -+} -+ -+/* -+ * Polled, blocking write from UART - */ --static void _BSP_put_char( char c ) { -- uart_write_polled(0, c); -+void imx_uart_poll_write_char(int minor, char c) -+{ -+ imx_uart_poll_write(minor, &c, 1); -+} -+ -+/* -+ * Functions for printk() and friends. -+ */ -+void _BSP_output_char(char c) -+{ -+ poll_write(c); - if (c == '\n') { -- uart_write_polled(0, '\r'); -+ poll_write('\r'); - } - } -+BSP_output_char_function_type BSP_output_char = _BSP_output_char; - --BSP_output_char_function_type BSP_output_char = _BSP_put_char; - -+char _BSP_poll_char() -+{ -+ return poll_read(); -+} -+BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; - - -Index: rtems/c/src/lib/libbsp/arm/csb336/Makefile.am -=================================================================== ---- rtems.orig/c/src/lib/libbsp/arm/csb336/Makefile.am -+++ rtems/c/src/lib/libbsp/arm/csb336/Makefile.am -@@ -35,7 +35,7 @@ startup_rel_CPPFLAGS = $(AM_CPPFLAGS) - startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - - noinst_PROGRAMS += console.rel --console_rel_SOURCES = console/uart.c ../../shared/console.c -+console_rel_SOURCES = console/uart.c - console_rel_CPPFLAGS = $(AM_CPPFLAGS) - console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) -