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 /c/src/lib/libbsp/arm/csb336 | |
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 'c/src/lib/libbsp/arm/csb336')
-rw-r--r-- | c/src/lib/libbsp/arm/csb336/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/csb336/console/uart.c | 476 |
2 files changed, 1 insertions, 477 deletions
diff --git a/c/src/lib/libbsp/arm/csb336/Makefile.am b/c/src/lib/libbsp/arm/csb336/Makefile.am index 04deee4f90..45f9ce342e 100644 --- a/c/src/lib/libbsp/arm/csb336/Makefile.am +++ b/c/src/lib/libbsp/arm/csb336/Makefile.am @@ -30,7 +30,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounter librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/csb336/clock/clockdrv.c librtemsbsp_a_SOURCES += timer/timer.c # console -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb336/console/uart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c diff --git a/c/src/lib/libbsp/arm/csb336/console/uart.c b/c/src/lib/libbsp/arm/csb336/console/uart.c deleted file mode 100644 index 8d8a0c1ed0..0000000000 --- a/c/src/lib/libbsp/arm/csb336/console/uart.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Console driver for MC9328XML UARTs. - * - * Written Jay Monkman <jtm@lopingdog.com> - * Copyright (c) 2005 by Loping Dog Embedded Systems - * - * 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 - */ -#include <bsp.h> -#include <rtems/libio.h> -#include <libchip/sersupp.h> -#include <rtems/error.h> -#include <rtems/bspIo.h> -#include <assert.h> -#include <termios.h> -#include <rtems/irq.h> -#include <bsp/irq.h> -#include <mc9328mxl.h> -#include <rtems/console.h> -#include <inttypes.h> - -/* 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) - -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 ssize_t imx_uart_poll_write(int, const char *, size_t); -static int imx_uart_poll_read_char(int minor); -static void imx_uart_poll_write_char(int minor, char c); -static void _BSP_output_char(char c); -static int _BSP_poll_char(void); - -#if USE_INTERRUPTS -static void imx_uart_tx_isr(void *); -static void imx_uart_rx_isr(void *); -static void imx_uart_isr_on(rtems_vector_number); -static void imx_uart_isr_off(rtems_vector_number); -static ssize_t imx_uart_intr_write(int, const char *, size_t); -static rtems_vector_number imx_uart_name_transmit(int minor); -static rtems_vector_number imx_uart_name_receive(int minor); -#endif - -/* TERMIOS callbacks */ -#if 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 - -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); - } - - 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 -) -{ - 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); -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - 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); -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - 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) { - imx_uart_data[minor].regs = - (mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE; - } else if (minor == 1) { - imx_uart_data[minor].regs = - (mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE; - } else { - rtems_panic("%s:%d Unknown UART minor number %d\n", - __FUNCTION__, __LINE__, minor); - } - - 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; - rtems_status_code status = RTEMS_SUCCESSFUL; - - imx_uart_data[minor].tty = args->iop->data1; - -#if USE_INTERRUPTS - status = rtems_interrupt_handler_install( - imx_uart_name_transmit(minor), - "UART", - RTEMS_INTERRUPT_UNIQUE, - imx_uart_tx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - imx_uart_isr_on(imx_uart_name_transmit(minor)); - - status = rtems_interrupt_handler_install( - imx_uart_name_receive(minor), - "UART", - RTEMS_INTERRUPT_UNIQUE, - imx_uart_rx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - imx_uart_isr_on(imx_uart_name_receive(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) -{ -#if USE_INTERRUPTS - rtems_status_code status = RTEMS_SUCCESSFUL; - - imx_uart_isr_off(imx_uart_name_transmit(minor)); - status = rtems_interrupt_handler_remove( - imx_uart_name_transmit(minor), - imx_uart_tx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - - imx_uart_isr_off(imx_uart_name_receive(minor)); - status = rtems_interrupt_handler_remove( - imx_uart_name_receive(minor), - imx_uart_rx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); -#endif - - 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 { - return -1; - } -} - - -static ssize_t imx_uart_poll_write(int minor, const char *buf, size_t len) -{ - 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; - -} - -#if USE_INTERRUPTS -static ssize_t imx_uart_intr_write(int minor, const char *buf, size_t len) -{ - if (len > 0) { - 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 imx_uart_set_attrs(int minor, const struct termios *t) -{ - int baud; - - baud = rtems_termios_baud_to_number(t->c_ospeed); - imx_uart_set_baud(minor, baud); - - return 0; -} - -#if USE_INTERRUPTS -static void imx_uart_isr_on(rtems_vector_number name) -{ - MC9328MXL_AITC_INTENNUM = name; -} -static void imx_uart_isr_off(rtems_vector_number name) -{ - MC9328MXL_AITC_INTDISNUM = name; -} - -static void imx_uart_rx_isr(void * 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(void * 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); - } -} - -static rtems_vector_number imx_uart_name_transmit(int minor) -{ - if (minor == 0) { - return BSP_INT_UART1_TX; - } else if (minor == 1) { - return BSP_INT_UART2_TX; - } - - assert(0); -} - -static rtems_vector_number imx_uart_name_receive(int minor) -{ - if (minor == 0) { - return BSP_INT_UART1_RX; - } else if (minor == 1) { - return BSP_INT_UART2_RX; - } - - assert(0); -} -#endif - -/* - * 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 - */ -static void imx_uart_set_baud(int minor, int baud) -{ - 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%" PRIx32, - __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; -} - - -/* - * Polled, non-blocking read from UART - */ -static int imx_uart_poll_read_char(int minor) -{ - return imx_uart_poll_read(minor); -} - -/* - * Polled, blocking write from UART - */ -static void imx_uart_poll_write_char(int minor, char c) -{ - imx_uart_poll_write(minor, &c, 1); -} - -/* - * Functions for printk() and friends. - */ -static void _BSP_output_char(char c) -{ - poll_write(c); -} - -BSP_output_char_function_type BSP_output_char = _BSP_output_char; - -static int _BSP_poll_char(void) -{ - return poll_read(); -} - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; - - |