summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c')
-rw-r--r--c/src/lib/libcpu/m68k/mcf5206/console/mcfuart.c519
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;
-}