diff options
Diffstat (limited to 'c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c')
-rw-r--r-- | c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c b/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c deleted file mode 100644 index fccce8541d..0000000000 --- a/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Generic UART Serial driver for Motorola Coldfire processors - */ - -/* - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. - * Author: Victor V. Vengerov <vvv@oktet.ru> - * - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * 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 <rtems.h> -#include <termios.h> -#include <rtems/libio.h> -#include "mcf5206/mcfuart.h" - -/* - * int_driven_uart -- mapping between interrupt vector number and - * UART descriptor structures - */ -static struct { - mcfuart *uart; - int vec; -} int_driven_uart[2]; - -/* Forward function declarations */ -static rtems_isr -mcfuart_interrupt_handler(rtems_vector_number vec); - -/* - * mcfuart_init -- - * This function verifies the input parameters and perform initialization - * of the Motorola Coldfire on-chip UART descriptor structure. - * - * PARAMETERS: - * uart - pointer to the UART channel descriptor structure - * tty - pointer to termios structure - * int_driven - interrupt-driven (1) or polled (0) I/O mode - * chn - channel number (0/1) - * rx_buf - pointer to receive buffer - * rx_buf_len - receive buffer length - * - * RETURNS: - * RTEMS_SUCCESSFUL if all parameters are valid, or error code - */ -rtems_status_code -mcfuart_init( - mcfuart *uart, - void *tty, - uint8_t intvec, - uint32_t chn -) -{ - if (uart == NULL) - return RTEMS_INVALID_ADDRESS; - - if ((chn <= 0) || (chn > MCF5206E_UART_CHANNELS)) - return RTEMS_INVALID_NUMBER; - - uart->chn = chn; - uart->intvec = intvec; - uart->tty = tty; - - return RTEMS_SUCCESSFUL; -} - -/* mcfuart_set_baudrate -- - * Program the UART timer to specified baudrate - * - * PARAMETERS: - * uart - pointer to UART descriptor structure - * baud - termios baud rate (B50, B9600, etc...) - * - * RETURNS: - * none - */ -static void -mcfuart_set_baudrate(mcfuart *uart, speed_t baud) -{ - uint32_t div; - uint32_t rate; - - switch (baud) { - case B50: rate = 50; break; - case B75: rate = 75; break; - case B110: rate = 110; break; - case B134: rate = 134; break; - case B150: rate = 150; break; - case B200: rate = 200; break; - case B300: rate = 300; break; - case B600: rate = 600; break; - case B1200: rate = 1200; break; - case B2400: rate = 2400; break; - case B4800: rate = 4800; break; - case B9600: rate = 9600; break; - case B19200: rate = 19200; break; - case B38400: rate = 38400; break; - case B57600: rate = 57600; break; -#ifdef B115200 - case B115200: rate = 115200; break; -#endif -#ifdef B230400 - case B230400: rate = 230400; break; -#endif - default: rate = 9600; break; - } - - div = SYSTEM_CLOCK_FREQUENCY / (rate * 32); - - *MCF5206E_UBG1(MBAR,uart->chn) = (uint8_t)((div >> 8) & 0xff); - *MCF5206E_UBG2(MBAR,uart->chn) = (uint8_t)(div & 0xff); -} - -/* - * mcfuart_reset -- - * This function perform the hardware initialization of Motorola - * Coldfire processor on-chip UART controller using parameters - * filled by the mcfuart_init function. - * - * PARAMETERS: - * uart - pointer to UART channel descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL if channel is initialized successfully, error - * code in other case - * - * ALGORITHM: - * This function in general follows to algorith described in MCF5206e - * User's Manual, 12.5 UART Module Initialization Sequence - */ -rtems_status_code mcfuart_reset(mcfuart *uart) -{ - register uint32_t chn; - rtems_status_code rc; - - if (uart == NULL) - return RTEMS_INVALID_ADDRESS; - - chn = uart->chn; - - /* Reset the receiver and transmitter */ - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_RX; - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_TX; - - /* - * Program the vector number for a UART module interrupt, or - * disable UART interrupts if polled I/O. Enable the desired - * interrupt sources. - */ - if (uart->intvec != 0) { - int_driven_uart[chn - 1].uart = uart; - int_driven_uart[chn - 1].vec = uart->intvec; - rc = rtems_interrupt_catch(mcfuart_interrupt_handler, uart->intvec, - &uart->old_handler); - if (rc != RTEMS_SUCCESSFUL) - return rc; - *MCF5206E_UIVR(MBAR,chn) = uart->intvec; - *MCF5206E_UIMR(MBAR,chn) = MCF5206E_UIMR_FFULL; - *MCF5206E_UACR(MBAR,chn) = MCF5206E_UACR_IEC; - *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(uart->chn == 1 ? - MCF5206E_INTR_UART_1 : - MCF5206E_INTR_UART_2); - } else { - *MCF5206E_UIMR(MBAR,chn) = 0; - } - - /* Select the receiver and transmitter clock. */ - mcfuart_set_baudrate(uart, B19200); /* dBUG defaults (unfortunately, - it is differ to termios default */ - *MCF5206E_UCSR(MBAR,chn) = MCF5206E_UCSR_RCS_TIMER | MCF5206E_UCSR_TCS_TIMER; - - /* Mode Registers 1,2 - set termios defaults (8N1) */ - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_MR; - *MCF5206E_UMR(MBAR,chn) = -/* MCF5206E_UMR1_RXRTS | */ - MCF5206E_UMR1_PM_NO_PARITY | - MCF5206E_UMR1_BC_8; - *MCF5206E_UMR(MBAR,chn) = - MCF5206E_UMR2_CM_NORMAL | -/* MCF5206E_UMR2_TXCTS | */ - MCF5206E_UMR2_SB_1; - - /* Enable Receiver and Transmitter */ - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_ERR; - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_TC_ENABLE; - *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_RC_ENABLE; - - return RTEMS_SUCCESSFUL; -} - -/* - * mcfuart_disable -- - * This function disable the operations on Motorola Coldfire UART - * controller - * - * PARAMETERS: - * uart - pointer to UART channel descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in - * other case - */ -rtems_status_code mcfuart_disable(mcfuart *uart) -{ - rtems_status_code rc; - - *MCF5206E_UCR(MBAR,uart->chn) = - MCF5206E_UCR_TC_DISABLE | - MCF5206E_UCR_RC_DISABLE; - if (uart->intvec != 0) { - *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(uart->chn == 1 ? - MCF5206E_INTR_UART_1 : - MCF5206E_INTR_UART_2); - rc = rtems_interrupt_catch(uart->old_handler, uart->intvec, NULL); - int_driven_uart[uart->chn - 1].uart = NULL; - int_driven_uart[uart->chn - 1].vec = 0; - if (rc != RTEMS_SUCCESSFUL) - return rc; - } - return RTEMS_SUCCESSFUL; -} - -/* - * mcfuart_set_attributes -- - * This function parse the termios attributes structure and perform - * the appropriate settings in hardware. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * t - pointer to termios parameters - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -int mcfuart_set_attributes(mcfuart *uart, const struct termios *t) -{ - int level; - speed_t baud; - uint8_t umr1, umr2; - - baud = cfgetospeed(t); - umr1 = 0; - umr2 = MCF5206E_UMR2_CM_NORMAL; - - /* Set flow control */ - if ((t->c_cflag & CRTSCTS) != 0) { - umr1 |= MCF5206E_UMR1_RXRTS; - umr2 |= MCF5206E_UMR2_TXCTS; - } - - /* Set character size */ - switch (t->c_cflag & CSIZE) { - case CS5: umr1 |= MCF5206E_UMR1_BC_5; break; - case CS6: umr1 |= MCF5206E_UMR1_BC_6; break; - case CS7: umr1 |= MCF5206E_UMR1_BC_7; break; - case CS8: umr1 |= MCF5206E_UMR1_BC_8; break; - } - - /* Set number of stop bits */ - if ((t->c_cflag & CSTOPB) != 0) { - if ((t->c_cflag & CSIZE) == CS5) { - umr2 |= MCF5206E_UMR2_SB5_2; - } else { - umr2 |= MCF5206E_UMR2_SB_2; - } - } else { - if ((t->c_cflag & CSIZE) == CS5) { - umr2 |= MCF5206E_UMR2_SB5_1; - } else { - umr2 |= MCF5206E_UMR2_SB_1; - } - } - - /* Set parity mode */ - if ((t->c_cflag & PARENB) != 0) { - if ((t->c_cflag & PARODD) != 0) { - umr1 |= MCF5206E_UMR1_PM_ODD; - } else { - umr1 |= MCF5206E_UMR1_PM_EVEN; - } - } else { - umr1 |= MCF5206E_UMR1_PM_NO_PARITY; - } - - rtems_interrupt_disable(level); - *MCF5206E_UCR(MBAR,uart->chn) = - MCF5206E_UCR_TC_DISABLE | MCF5206E_UCR_RC_DISABLE; - mcfuart_set_baudrate(uart, baud); - *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_MISC_RESET_MR; - *MCF5206E_UMR(MBAR,uart->chn) = umr1; - *MCF5206E_UMR(MBAR,uart->chn) = umr2; - if ((t->c_cflag & CREAD) != 0) { - *MCF5206E_UCR(MBAR,uart->chn) = - MCF5206E_UCR_TC_ENABLE | MCF5206E_UCR_RC_ENABLE; - } else { - *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_TC_ENABLE; - } - rtems_interrupt_enable(level); - - return RTEMS_SUCCESSFUL; -} - -/* - * mcfuart_poll_read -- - * This function tried to read character from MCF UART and perform - * error handling. When parity or framing error occured, return - * value dependent on termios input mode flags: - * - received character, if IGNPAR == 1 - * - 0, if IGNPAR == 0 and PARMRK == 0 - * - 0xff and 0x00 on next poll_read invocation, if IGNPAR == 0 and - * PARMRK == 1 - * - * PARAMETERS: - * uart - pointer to UART descriptor structure - * - * RETURNS: - * code of received character or -1 if no characters received. - */ -int mcfuart_poll_read(mcfuart *uart) -{ - uint8_t usr; - int ch; - - if (uart->parerr_mark_flag == true) { - uart->parerr_mark_flag = false; - return 0; - } - - usr = *MCF5206E_USR(MBAR,uart->chn); - if ((usr & MCF5206E_USR_RXRDY) != 0) { - if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) && - !(uart->c_iflag & IGNPAR)) { - ch = *MCF5206E_URB(MBAR,uart->chn); /* Clear error bits */ - if (uart->c_iflag & PARMRK) { - uart->parerr_mark_flag = true; - ch = 0xff; - } else { - ch = 0; - } - } else { - ch = *MCF5206E_URB(MBAR,uart->chn); - } - } else - ch = -1; - return ch; -} - -/* - * mcfuart_poll_write -- - * This function transmit buffer byte-by-byte in polling mode. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * buf - pointer to transmit buffer - * len - transmit buffer length - * - * RETURNS: - * 0 - */ -ssize_t mcfuart_poll_write(mcfuart *uart, const char *buf, size_t len) -{ - size_t retval = len; - - while (len--) { - while ((*MCF5206E_USR(MBAR, uart->chn) & MCF5206E_USR_TXRDY) == 0); - *MCF5206E_UTB(MBAR, uart->chn) = *buf++; - } - return retval; -} - -/* mcfuart_interrupt_handler -- - * UART interrupt handler routine - * - * PARAMETERS: - * vec - interrupt vector number - * - * RETURNS: - * none - */ -static rtems_isr mcfuart_interrupt_handler(rtems_vector_number vec) -{ - mcfuart *uart; - register uint8_t usr; - register uint8_t uisr; - register int chn; - register int bp = 0; - - /* Find UART descriptor from vector number */ - if (int_driven_uart[0].vec == vec) - uart = int_driven_uart[0].uart; - else if (int_driven_uart[1].vec == vec) - uart = int_driven_uart[1].uart; - else - return; - - chn = uart->chn; - - uisr = *MCF5206E_UISR(MBAR, chn); - if (uisr & MCF5206E_UISR_DB) { - *MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_BRK; - } - - /* Receiving */ - while (1) { - char buf[32]; - usr = *MCF5206E_USR(MBAR,chn); - if ((bp < sizeof(buf) - 1) && ((usr & MCF5206E_USR_RXRDY) != 0)) { - /* Receive character and handle frame/parity errors */ - if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) && - !(uart->c_iflag & IGNPAR)) { - if (uart->c_iflag & PARMRK) { - buf[bp++] = 0xff; - buf[bp++] = 0x00; - } else { - buf[bp++] = 0x00; - } - } else { - buf[bp++] = *MCF5206E_URB(MBAR, chn); - } - - /* Reset error condition if any errors has been detected */ - if (usr & (MCF5206E_USR_RB | MCF5206E_USR_FE | - MCF5206E_USR_PE | MCF5206E_USR_OE)) { - *MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_ERR; - } - } else { - if (bp != 0) - rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); - break; - } - } - - /* Transmitting */ - while (1) { - if ((*MCF5206E_USR(MBAR, chn) & MCF5206E_USR_TXRDY) == 0) - break; - if (uart->tx_buf != NULL) { - if (uart->tx_ptr >= uart->tx_buf_len) { - register int dequeue = uart->tx_buf_len; - - *MCF5206E_UIMR(MBAR, uart->chn) = MCF5206E_UIMR_FFULL; - uart->tx_buf = NULL; - uart->tx_ptr = uart->tx_buf_len = 0; - rtems_termios_dequeue_characters(uart->tty, dequeue); - } else { - *MCF5206E_UTB(MBAR, chn) = uart->tx_buf[uart->tx_ptr++]; - } - } - else - break; - } -} - -/* mcfuart_interrupt_write -- - * This function initiate transmitting of the buffer in interrupt mode. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * buf - pointer to transmit buffer - * len - transmit buffer length - * - * RETURNS: - * 0 - */ -ssize_t mcfuart_interrupt_write( - mcfuart *uart, - const char *buf, - size_t len -) -{ - if (len > 0) { - uart->tx_buf = buf; - uart->tx_buf_len = len; - uart->tx_ptr = 0; - *MCF5206E_UIMR(MBAR, uart->chn) = - MCF5206E_UIMR_FFULL | MCF5206E_UIMR_TXRDY; - while (((*MCF5206E_USR(MBAR,uart->chn) & MCF5206E_USR_TXRDY) != 0) && - (uart->tx_ptr < uart->tx_buf_len)) { - *MCF5206E_UTB(MBAR,uart->chn) = uart->tx_buf[uart->tx_ptr++]; - } - } - - return 0; -} - -/* mcfuart_stop_remote_tx -- - * This function stop data flow from remote device. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -int mcfuart_stop_remote_tx(mcfuart *uart) -{ - *MCF5206E_UOP0(MBAR, uart->chn) = 1; - return RTEMS_SUCCESSFUL; -} - -/* mcfuart_start_remote_tx -- - * This function resume data flow from remote device. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -int mcfuart_start_remote_tx(mcfuart *uart) -{ - *MCF5206E_UOP1(MBAR, uart->chn) = 1; - return RTEMS_SUCCESSFUL; -} |