From d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 Apr 2018 06:28:01 +0200 Subject: bsps: Move console drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libbsp/m68k/av5282/Makefile.am | 2 +- c/src/lib/libbsp/m68k/av5282/console/console.c | 711 --------- c/src/lib/libbsp/m68k/csb360/Makefile.am | 4 +- c/src/lib/libbsp/m68k/csb360/console/console-io.c | 97 -- c/src/lib/libbsp/m68k/gen68340/Makefile.am | 6 +- c/src/lib/libbsp/m68k/gen68340/console/console.c | 690 -------- c/src/lib/libbsp/m68k/gen68340/console/m340uart.c | 311 ---- c/src/lib/libbsp/m68k/gen68360/Makefile.am | 4 +- c/src/lib/libbsp/m68k/gen68360/console/console.c | 390 ----- c/src/lib/libbsp/m68k/genmcf548x/Makefile.am | 2 +- c/src/lib/libbsp/m68k/genmcf548x/console/console.c | 843 ---------- c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am | 4 +- .../lib/libbsp/m68k/mcf5206elite/console/console.c | 431 ----- c/src/lib/libbsp/m68k/mcf52235/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mcf52235/console/console.c | 656 -------- c/src/lib/libbsp/m68k/mcf52235/console/debugio.c | 32 - c/src/lib/libbsp/m68k/mcf5225x/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mcf5225x/console/console.c | 689 -------- c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c | 35 - c/src/lib/libbsp/m68k/mcf5235/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mcf5235/console/console.c | 745 --------- c/src/lib/libbsp/m68k/mcf5329/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mcf5329/console/console.c | 668 -------- c/src/lib/libbsp/m68k/mrm332/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mrm332/console/console.c | 155 -- c/src/lib/libbsp/m68k/mrm332/console/sci.c | 1586 ------------------ c/src/lib/libbsp/m68k/mrm332/console/sci.h | 233 --- c/src/lib/libbsp/m68k/mvme147/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mvme147/console/console.c | 203 --- c/src/lib/libbsp/m68k/mvme147s/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mvme162/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mvme162/console/console.c | 277 ---- c/src/lib/libbsp/m68k/mvme167/Makefile.am | 2 +- .../m68k/mvme167/console/console-recording.h | 572 ------- c/src/lib/libbsp/m68k/mvme167/console/console.c | 1676 -------------------- c/src/lib/libbsp/m68k/uC5282/Makefile.am | 2 +- c/src/lib/libbsp/m68k/uC5282/console/console.c | 774 --------- 37 files changed, 25 insertions(+), 11799 deletions(-) delete mode 100644 c/src/lib/libbsp/m68k/av5282/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/csb360/console/console-io.c delete mode 100644 c/src/lib/libbsp/m68k/gen68340/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/gen68340/console/m340uart.c delete mode 100644 c/src/lib/libbsp/m68k/gen68360/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/genmcf548x/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5206elite/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf52235/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf52235/console/debugio.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5225x/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5235/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5329/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/sci.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/sci.h delete mode 100644 c/src/lib/libbsp/m68k/mvme147/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mvme162/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mvme167/console/console-recording.h delete mode 100644 c/src/lib/libbsp/m68k/mvme167/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/uC5282/console/console.c (limited to 'c/src/lib/libbsp/m68k') diff --git a/c/src/lib/libbsp/m68k/av5282/Makefile.am b/c/src/lib/libbsp/m68k/av5282/Makefile.am index c96fe93459..4ad8a6a915 100644 --- a/c/src/lib/libbsp/m68k/av5282/Makefile.am +++ b/c/src/lib/libbsp/m68k/av5282/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/av5282/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/av5282/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/av5282/console/console.c b/c/src/lib/libbsp/m68k/av5282/console/console.c deleted file mode 100644 index dd557660f8..0000000000 --- a/c/src/lib/libbsp/m68k/av5282/console/console.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ - MCF5282_UART_USR_FE | \ - MCF5282_UART_USR_PE | \ - MCF5282_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void _BSP_null_char( char c ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - - MCF5282_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - - rtems_interrupt_enable(level); -} -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/* - * Function : IntUartSet - * - * Description : This updates the hardware UART settings. - */ -static void IntUartSet( - int minor, - int baud, - int databits, - int parity, - int stopbits, - int hwflow -) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UOP0(minor) = 1; - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = (clock_speed / ( 32 * baud )); - if ( divisor < 2 ) - divisor = 2; - - /* check to see if doing hardware flow control */ - if ( hwflow ) { - /* set hardware flow options */ - umr1 |= MCF5282_UART_UMR1_RXRTS; - umr2 |= MCF5282_UART_UMR2_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; - MCF5282_UART_UMR(minor) = umr1; - MCF5282_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5282_UART_UCSR(minor) = - (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); - MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); -} - -/* - * Function : IntUartSetAttributes - * - * Description : This provides the hardware-dependent portion of tcsetattr(). - * value and sets it. At the moment this just sets the baud rate. - * - * Note: The highest baudrate is 115200 as this stays within - * an error of +/- 5% at 25MHz processor clock - */ -static int IntUartSetAttributes( - int minor, - const struct termios *t -) -{ - /* set default index values */ - int baud = (int)19200; - int databits = (int)MCF5282_UART_UMR1_BC_8; - int parity = (int)MCF5282_UART_UMR1_PM_NONE; - int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) { - case CS5: - databits = (int)MCF5282_UART_UMR1_BC_5; - break; - case CS6: - databits = (int)MCF5282_UART_UMR1_BC_6; - break; - case CS7: - databits = (int)MCF5282_UART_UMR1_BC_7; - break; - case CS8: - databits = (int)MCF5282_UART_UMR1_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) { - if ( t->c_cflag & PARODD ) { - /* odd parity */ - parity = (int)MCF5282_UART_UMR1_PM_ODD; - } else { - /* even parity */ - parity = (int)MCF5282_UART_UMR1_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) { - /* two stop bits */ - stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return RTEMS_SUCCESSFUL; -} - -/* - * Function : IntUartInterruptHandler - * - * Description : This is the interrupt handler for the internal uart. It - * determines which channel caused the interrupt before queueing any received - * chars and dequeueing chars waiting for transmission. - */ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) { - /* read data and put into the receive buffer */ - while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) { - - if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) { - /* clear the error */ - MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) { - info->rx_in = 0; - } - } - - /* Make sure the port has been opened */ - if ( info->ttyp ) { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters( - info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && - ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/* - * Function : IntUartInitialize - * - * Description : This initialises the internal uart hardware for all - * internal uarts. If the internal uart is to be interrupt driven then the - * interrupt vectors are hooked. - */ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - rtems_interrupt_level level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; - - MCF5282_UART_UACR(chan) = 0; - MCF5282_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 1: - MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 2: - MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | - MCF5282_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/* - * Function : IntUartInterruptWrite - * - * Description : This writes a single character to the appropriate uart - * channel. This is either called during an interrupt or in the user's task - * to initiate a transmit sequence. Calling this routine enables Tx - * interrupts. - */ -static ssize_t IntUartInterruptWrite( - int minor, - const char *buf, - size_t len -) -{ - if (len > 0) { - /* write out character */ - MCF5282_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return 0; -} - -/* - * Function : IntUartInterruptOpen - * - * Description : This enables interrupts when the tty is opened. - */ -static int IntUartInterruptOpen( - int major, - int minor, - void *arg -) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | - MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - return 0; -} - -/* - * Function : IntUartInterruptClose - * - * Description : This disables interrupts when the tty is closed. - */ -static int IntUartInterruptClose( - int major, - int minor, - void *arg -) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return 0; -} - -/* - * Function : IntUartTaskRead - * - * Description : This reads all available characters from the internal uart - * and places them into the termios buffer. The rx interrupts will be - * re-enabled after all data has been read. - */ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return EOF; -} - - - -/* - * Function : IntUartPollRead - * - * Description : This reads a character from the internal uart. It returns - * to the caller without blocking if not character is waiting. - */ -static int IntUartPollRead(int minor) -{ - if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) - return-1; - - return MCF5282_UART_URB(minor); -} - - -/* - * Function : IntUartPollWrite - * - * Description : This writes out each character in the buffer to the - * appropriate internal uart channel waiting till each one is sucessfully - * transmitted. - */ -static ssize_t IntUartPollWrite( - int minor, - const char *buf, - size_t len -) -{ - size_t retval = len; - /* loop over buffer */ - - while ( len-- ) { - /* block until we can transmit */ - while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5282_UART_UTB(minor) = *buf++; - } - return retval; -} - -/* - * Function : console_initialize - * - * Description : This initialises termios, both sets of uart hardware before - * registering /dev/tty devices for each channel and the system /dev/console. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - } - - return RTEMS_SUCCESSFUL; -} - -/* - * Function : console_open - * - * Description : This actually opens the device depending on the minor - * number set during initialisation. The device specific access routines are - * passed to termios when the devices is opened depending on whether it is - * polled or not. - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) { - info = &IntUartInfo[minor]; - switch ( info->iomode ) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return status; -} - -/* - * Function : console_close - * - * Description : This closes the device via termios - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close(arg); -} - -/* - * Function : console_read - * - * Description : Read from the device via termios - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_read(arg); -} - -/* - * Function : console_write - * - * Description : Write to the device via termios - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_write(arg); -} - -/* - * Function : console_ioctl - * - * Description : Pass the IOCtl call to termios - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_ioctl(arg); -} diff --git a/c/src/lib/libbsp/m68k/csb360/Makefile.am b/c/src/lib/libbsp/m68k/csb360/Makefile.am index cce7610faf..3fd41e5d4c 100644 --- a/c/src/lib/libbsp/m68k/csb360/Makefile.am +++ b/c/src/lib/libbsp/m68k/csb360/Makefile.am @@ -27,8 +27,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # console -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/csb360/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/memProbe.c diff --git a/c/src/lib/libbsp/m68k/csb360/console/console-io.c b/c/src/lib/libbsp/m68k/csb360/console/console-io.c deleted file mode 100644 index 9b0aeac5bb..0000000000 --- a/c/src/lib/libbsp/m68k/csb360/console/console-io.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the mcf5272 - */ - -/* - * 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 -#include -#include -#include - -volatile int g_cnt = 0; - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ -} - - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ - -void console_outbyte_polled( - int port, - char ch -) -{ - uart_regs_t *uart; - int i; - if (port == 0) { - uart = g_uart0_regs; - } else { - uart = g_uart1_regs; - } - - /* wait for the fifo to make room */ -/* while ((uart->usr & MCF5272_USR_TXRDY) == 0) { */ - while ((uart->ucsr & MCF5272_USR_TXRDY) == 0) { - continue; - } - - uart->udata = ch; - for (i = 0; i < 1000; i++) g_cnt++; -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - uart_regs_t *uart; - unsigned char c; - - if (port == 0) { - uart = g_uart0_regs; - } else { - uart = g_uart1_regs; - } - -/* if (uart->usr & MCF5272_USR_RXRDY) { */ - if (uart->ucsr & MCF5272_USR_RXRDY) { - c = (char)uart->udata; - return c; - } else { - return -1; - } -} - -#include - -static void mcf5272_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = mcf5272_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/m68k/gen68340/Makefile.am b/c/src/lib/libbsp/m68k/gen68340/Makefile.am index c3df13693d..ab20c9dda3 100644 --- a/c/src/lib/libbsp/m68k/gen68340/Makefile.am +++ b/c/src/lib/libbsp/m68k/gen68340/Makefile.am @@ -30,9 +30,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/gen68340/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/m340uart.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68340/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68340/console/m340uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/gen68340/console/console.c b/c/src/lib/libbsp/m68k/gen68340/console/console.c deleted file mode 100644 index d6634b1079..0000000000 --- a/c/src/lib/libbsp/m68k/gen68340/console/console.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * 68340/68349 console serial I/O. - */ - -/* - * Author: - * Geoffroy Montel - * France Telecom - CNET/DSM/TAM/CAT - * 4, rue du Clos Courtel - * 35512 CESSON-SEVIGNE - * FRANCE - * - * e-mail: g_montel@yahoo.com - * - * COPYRIGHT (c) 1989-1999. - * 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 - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define CONSOLE_VECTOR 121 -#define CONSOLE_IRQ_LEVEL 3 -#define CONSOLE_INTERRUPT_ARBITRATION 2 - -static void *ttypA; /* to remember which tty has been opened on channel A - used when interrupts are enabled */ - -static void *ttypB; /* to remember which tty has been opened on channel B - used when interrupts are enabled */ - -unsigned char DUIER_mirror = 0 ; /* reflects the state of IER register, which is Write Only */ -unsigned char Error_Status_A = 0; /* error status on Channel A */ -unsigned char Error_Status_B = 0; /* error status on Channel A */ - -/* - * Device-specific routines - */ - -#define USE_INTERRUPTS_A (m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS) -#define USE_INTERRUPTS_B (m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS) -#define CHANNEL_ENABLED_A m340_uart_config[UART_CHANNEL_A].enable -#define CHANNEL_ENABLED_B m340_uart_config[UART_CHANNEL_B].enable - -#define set_DUIER(a) DUIER_mirror |= (a); DUIER = DUIER_mirror -#define unset_DUIER(a) DUIER_mirror &= ~(a); DUIER = DUIER_mirror - -#define Enable_Interrupts_Tx_A if (USE_INTERRUPTS_A) set_DUIER(m340_TxRDYA) -#define Disable_Interrupts_Tx_A if (USE_INTERRUPTS_A) unset_DUIER(m340_TxRDYA) - -#define Enable_Interrupts_Tx_B if (USE_INTERRUPTS_B) set_DUIER(m340_TxRDYB) -#define Disable_Interrupts_Tx_B if (USE_INTERRUPTS_B) unset_DUIER(m340_TxRDYB) - -/****************************************************** - Name: InterruptHandler - Input parameters: vector number - Output parameters: - - Description: UART ISR Routine, called by _RTEMS_ISR - *****************************************************/ -rtems_isr -InterruptHandler (rtems_vector_number v) -{ - char ch; - - /***************************************************************************** - ** CHANNEL A ** - *****************************************************************************/ - - /* check Received Break*/ - if (DUSRA & m340_RB) { - Error_Status_A |= m340_RB; - /* reset error status */ - DUCRA = m340_Reset_Error_Status; - } - - /* buffer received ? */ - if (DUSRA & m340_Rx_RDY) { - do { - /* error encountered? */ - if (DUSRA & (m340_OE | m340_PE | m340_FE | m340_RB)) { - Error_Status_A |= DUSRA; - /* reset error status */ - DUCRA = m340_Reset_Error_Status; - /* all the characters in the queue may not be good */ - while (DUSRA & m340_Rx_RDY) - /* push them in a trash */ - ch = DURBA; - } - else { - /* this is necessary, otherwise it blocks when FIFO is full */ - ch = DURBA; - rtems_termios_enqueue_raw_characters(ttypA,&ch,1); - } - } while (DUSRA & m340_Rx_RDY); - Restart_Fifo_Full_A_Timer(); /* only if necessary (pointer to a fake function if - not in FIFO full mode) */ - } - - else /* if no character has been received */ - Restart_Check_A_Timer(); /* same remark */ - - /* ready to accept a character ? */ - if (DUISR & DUIER_mirror & m340_TxRDYA) { - Disable_Interrupts_Tx_A; - /* one character has been transmitted */ - rtems_termios_dequeue_characters(ttypA,1); - } - - /***************************************************************************** - ** CHANNEL B ** - *****************************************************************************/ - - /* check Received Break*/ - if (DUSRB & m340_RB) { - Error_Status_B |= m340_RB; - /* reset error status */ - DUCRB = m340_Reset_Error_Status; - } - - /* buffer received ? */ - if (DUSRB & m340_Rx_RDY) { - do { - if (DUSRB & (m340_OE | m340_PE | m340_FE | m340_RB)) { - Error_Status_B |= DUSRB; - /* reset error status */ - DUCRB = m340_Reset_Error_Status; - /* all the characters in the queue may not be good */ - while (DUSRB & m340_Rx_RDY) - /* push them in a trash */ - ch = DURBB; - } - else { - ch = DURBB; - rtems_termios_enqueue_raw_characters(ttypB,&ch,1); - } - - } while (DUSRB & m340_Rx_RDY); - Restart_Fifo_Full_B_Timer(); - } - else /* if no character has been received */ - Restart_Check_B_Timer(); - - /* ready to accept a character ? */ - if (DUISR & DUIER_mirror & m340_TxRDYB) { - Disable_Interrupts_Tx_B; - /* one character has been transmitted */ - rtems_termios_dequeue_characters(ttypB,1); - } -} - -/****************************************************** - Name: InterruptWrite - Input parameters: minor = channel, pointer to buffer, - and length of buffer to transmit - Output parameters: - - Description: write the first character of buf only - may be called by either console_write - or rtems_termios_enqueue_raw_characters - *****************************************************/ -static ssize_t -InterruptWrite (int minor, const char *buf, size_t len) -{ - if (minor==UART_CHANNEL_A) { - if (len>0) { - DUTBA=*buf; - Enable_Interrupts_Tx_A; - } - } - else if (minor==UART_CHANNEL_B) { - if (len>0) { - DUTBB=*buf; - Enable_Interrupts_Tx_B; - } - } - return 0; -} - -/****************************************************** - Name: dbug_out_char - Input parameters: channel, character to emit - Output parameters: - - Description: wait for the UART to be ready to emit - a character and send it - *****************************************************/ -void dbug_out_char( int minor, int ch ) -{ - if (minor==UART_CHANNEL_A) { - while (!(DUSRA & m340_Tx_RDY)) continue; - DUTBA=ch; - } - else if (minor==UART_CHANNEL_B) { - while (!(DUSRB & m340_Tx_RDY)) continue; - DUTBB=ch; - } -} - -/****************************************************** - Name: dbug_in_char - Input parameters: - - Output parameters: received character - Description: return the character in the UART - *****************************************************/ -int dbug_in_char( int minor ) -{ - if (minor==UART_CHANNEL_A) { - return DURBA; - } - else if (minor==UART_CHANNEL_B) { - return DURBB; - } - return 0; -} - -/****************************************************** - Name: dbug_char_present - Input parameters: channel # - Output parameters: TRUE or FALSE - Description: return whether there's a character - in the receive buffer - *****************************************************/ -int dbug_char_present( int minor ) -{ - if (minor==UART_CHANNEL_A) { - return (DUSRA & m340_Rx_RDY); - } - else if (minor==UART_CHANNEL_B) { - return (DUSRB & m340_Rx_RDY); - } - return 0; -} - -/****************************************************** - Name: dbugInitialise - Input parameters: - - Output parameters: - - Description: Init the UART - *****************************************************/ -static void -dbugInitialise (void) -{ - t_baud_speed_table uart_config; /* configuration of UARTS */ - - /* - * Reset Receiver - */ - DUCRA = m340_Reset_Receiver; - DUCRB = m340_Reset_Receiver; - - /* - * Reset Transmitter - */ - DUCRA = m340_Reset_Transmitter; - DUCRB = m340_Reset_Transmitter; - - /* - * Enable serial module for normal operation, ignore FREEZE, select the crystal clock, - * supervisor/user serial registers unrestricted - * interrupt arbitration at priority CONSOLE_INTERRUPT_ARBITRATION - * WARNING : 8 bits access only on this UART! - */ - DUMCRH = 0x00; - DUMCRL = CONSOLE_INTERRUPT_ARBITRATION; - - /* - * Interrupt level register - */ - DUILR = CONSOLE_IRQ_LEVEL; - - /* sets the IVR */ - DUIVR = CONSOLE_VECTOR; - - /* search for a correct m340 uart configuration */ - uart_config = Find_Right_m340_UART_Config(m340_uart_config[UART_CHANNEL_A].rx_baudrate, - m340_uart_config[UART_CHANNEL_A].tx_baudrate, - CHANNEL_ENABLED_A, - m340_uart_config[UART_CHANNEL_B].rx_baudrate, - m340_uart_config[UART_CHANNEL_B].tx_baudrate, - CHANNEL_ENABLED_B); - - /***************************************************************************** - ** CHANNEL A ** - *****************************************************************************/ - if (CHANNEL_ENABLED_A) { - - if (USE_INTERRUPTS_A) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (InterruptHandler, - CONSOLE_VECTOR, - &old_handler); - - /* uncomment this if you want to pass control to your own ISR handler - it may be usefull to do so to check for performances with an oscilloscope */ - /* - { - proc_ptr ignored; - _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); - } - */ - - /* - * Interrupt Enable Register - * Enable Interrupts on Channel A Receiver Ready - */ - set_DUIER(m340_RxRDYA); - } - else { - /* - * Disable Interrupts on channel A - */ - unset_DUIER(m340_RxRDYA&m340_TxRDYA); - } - - /* - * Change set of baud speeds - * disable input control - */ - /* no good uart configuration ? */ - if (uart_config.nb<1) rtems_fatal_error_occurred (-1); - - if (uart_config.baud_speed_table[UART_CHANNEL_A].set==1) - DUACR = m340_BRG_Set1; - else - DUACR = m340_BRG_Set2; - - /* - * make OPCR an auxiliary function serving the communication channels - */ - DUOPCR = m340_OPCR_Aux; - - /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal - input is not applied to the baud rate generator */ - while (DUISR & m340_XTAL_RDY) continue; - - /* - * Serial Channel Baud Speed - */ - DUCSRA = (uart_config.baud_speed_table[UART_CHANNEL_A].rcs << 4) - | (uart_config.baud_speed_table[UART_CHANNEL_A].tcs); - - /* - * Serial Channel Configuration - */ - DUMR1A = m340_uart_config[UART_CHANNEL_A].parity_mode - | m340_uart_config[UART_CHANNEL_A].bits_per_char - | m340_RxRTS; - - if (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL) DUMR1A |= m340_R_F | m340_ERR; - - /* - * Serial Channel Configuration 2 - */ - DUMR2A |= m340_normal; - - /* - * Enable Channel A: transmitter and receiver - */ - DUCRA = m340_Transmitter_Enable | m340_Receiver_Enable; - } /* channel A enabled */ - - /***************************************************************************** - ** CHANNEL B ** - *****************************************************************************/ - if (CHANNEL_ENABLED_B) { - - /* we mustn't set the console vector twice! */ - if ((USE_INTERRUPTS_B && !(CHANNEL_ENABLED_A)) - || (USE_INTERRUPTS_B && CHANNEL_ENABLED_A && !USE_INTERRUPTS_A)) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (InterruptHandler, - CONSOLE_VECTOR, - &old_handler); - - /* uncomment this if you want to pass control to your own ISR handler - it may be usefull to do so to check for performances with an oscilloscope */ - /* - { - proc_ptr ignored; - _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); - } - */ - - /* - * Interrupt Enable Register - * Enable Interrupts on Channel A Receiver Ready - */ - set_DUIER(m340_RxRDYB); - } - else { - /* - * Disable Interrupts on channel B - */ - unset_DUIER(m340_RxRDYB&m340_TxRDYB); - } - - /* - * Change set of baud speeds - * disable input control - */ - - /* no good uart configuration ? */ - if (uart_config.nb<2) rtems_fatal_error_occurred (-1); - - /* don't set DUACR twice! */ - if (!CHANNEL_ENABLED_A) { - if (uart_config.baud_speed_table[UART_CHANNEL_B].set==1) - DUACR = m340_BRG_Set1; - else - DUACR = m340_BRG_Set2; - } - - /* - * make OPCR an auxiliary function serving the communication channels - */ - if (!CHANNEL_ENABLED_A) DUOPCR = m340_OPCR_Aux; - - /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal - input is not applied to the baud rate generator */ - while (DUISR & m340_XTAL_RDY) continue; - - /* - * Serial Channel Baud Speed - */ - DUCSRB = (uart_config.baud_speed_table[UART_CHANNEL_B].rcs << 4) - | (uart_config.baud_speed_table[UART_CHANNEL_B].tcs); - - /* - * Serial Channel Configuration - */ - DUMR1B = m340_uart_config[UART_CHANNEL_B].parity_mode - | m340_uart_config[UART_CHANNEL_B].bits_per_char - | m340_RxRTS; - - if (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL) DUMR1B |= m340_R_F | m340_ERR; - - /* - * Serial Channel Configuration 2 - */ - DUMR2B |= m340_normal; - - /* - * Enable Channel A: transmitter and receiver - */ - DUCRB = m340_Transmitter_Enable | m340_Receiver_Enable; - } /* channel B enabled */ -} - -/****************************************************** - Name: SetAttributes - Input parameters: termios structure, channel - Output parameters: - - Description: return whether there's a character - in the receive buffer - TO DO: add the channel # to check for!! - *****************************************************/ -static int -SetAttributes (int minor, const struct termios *t) -{ - rtems_interrupt_level level; - float ispeed, ospeed; - - /* convert it */ - ispeed = rtems_termios_baud_to_number(t->c_ispeed); - ospeed = rtems_termios_baud_to_number(t->c_ospeed); - - if (ispeed || ospeed) { - /* update config table */ - m340_uart_config[UART_CHANNEL_A].rx_baudrate = ((minor==UART_CHANNEL_A)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_A].rx_baudrate; - m340_uart_config[UART_CHANNEL_A].tx_baudrate = ((minor==UART_CHANNEL_A)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_A].tx_baudrate; - m340_uart_config[UART_CHANNEL_B].rx_baudrate = ((minor==UART_CHANNEL_B)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_B].rx_baudrate; - m340_uart_config[UART_CHANNEL_B].tx_baudrate = ((minor==UART_CHANNEL_B)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_B].tx_baudrate; - } - - /* change parity */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) m340_uart_config[minor].parity_mode = m340_Odd_Parity; - else m340_uart_config[minor].parity_mode = m340_Even_Parity; - } - - /* change bits per character */ - if (t->c_cflag & CSIZE) { - switch (t->c_cflag & CSIZE) { - default: break; - case CS5: m340_uart_config[minor].bits_per_char = m340_5bpc; break; - case CS6: m340_uart_config[minor].bits_per_char = m340_6bpc; break; - case CS7: m340_uart_config[minor].bits_per_char = m340_7bpc; break; - case CS8: m340_uart_config[minor].bits_per_char = m340_8bpc; break; - } - } - - /* if serial module configuration has been changed */ - if (t->c_cflag & (CSIZE | PARENB)) { - rtems_interrupt_disable(level); - /* reinit the UART */ - dbugInitialise(); - rtems_interrupt_enable (level); - } - - return 0; -} - -/****************************************************** - Name: console_initialize - Input parameters: MAJOR # of console_driver, - minor is always 0, - args are always NULL - Output parameters: - - Description: Reserve resources consumed by this driver - TODO: We should pass m340_uart_config table in arg - *****************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - int i; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize (); - - /* - * Do device-specific initialization - */ - Init_UART_Table(); - dbugInitialise (); - Fifo_Full_benchmark_timer_initialize(); - - /* - * Register the devices - */ - for (i=0; iiop->data1; - } - else { - sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); - } - } - - else if (minor==UART_CHANNEL_B) { - if (USE_INTERRUPTS_B) { - rtems_libio_open_close_args_t *args = arg; - - sc |= rtems_termios_open (major, minor, arg, &intrCallbacks); - ttypB = args->iop->data1; - } - else { - sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); - } - } - - else return RTEMS_INVALID_NUMBER; - - return sc; -} - -/****************************************************** - Name: console_close - Input parameters: channel #, termios args - Output parameters: - - Description: close the device - *****************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/****************************************************** - Name: console_read - Input parameters: channel #, termios args - Output parameters: - - Description: read the device - *****************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/****************************************************** - Name: console_write - Input parameters: channel #, termios args - Output parameters: - - Description: write to the device - *****************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/****************************************************** - Name: console_control - Input parameters: channel #, termios args - Output parameters: - - Description: Handle ioctl request - *****************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - if (args->command == TIOCSETA) - SetAttributes (minor, (struct termios *)args->buffer); - - return rtems_termios_ioctl (arg); -} diff --git a/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c b/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c deleted file mode 100644 index 56ad29c256..0000000000 --- a/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * M68340/349 UART management tools - */ - -/* - * Author: - * Geoffroy Montel - * France Telecom - CNET/DSM/TAM/CAT - * 4, rue du Clos Courtel - * 35512 CESSON-SEVIGNE - * FRANCE - * - * e-mail: g_montel@yahoo.com - * - * COPYRIGHT (c) 1989-1999. - * 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 -#include -#include -#include -#include -#include -#include - -/* this table shows compatible speed configurations for the MC68340: - the first row shows baud rates for baud speed set 1 - the second row shows baud rates for baud speed set 2 - look at Motorola's MC68340 Integrated Processor User's Manual - page 7-30 for more infos */ - -float m340_Baud_Rates_Table[16][2] = { - { 50, 75 }, - { 110, 110 }, - { 134.5, 134.5 }, - { 200, 150 }, - { 300, 300 }, - { 600, 600 }, - { 1200, 1200 }, - { 1050, 2000 }, - { 2400, 2400 }, - { 4800, 4800 }, - { 7200, 1800 }, - { 9600, 9600 }, - { 38400, 19200 }, - { 76800, 38400 }, - { SCLK/16, SCLK/16}, - { SCLK, SCLK }, -}; - -/* config on both 340 channels */ -uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS]; - -/* - * Init UART table - */ - -#define NOT_IMPLEMENTED_YET 0 - -/****************************************************** - Name: Init_UART_Table - Input parameters: - - Output parameters: - - Description: Init the m340_uart_config - THIS SHOULD NOT BE HERE! - Its aim was to let the user configure - UARTs for each application. - As we can't pass args to the console - driver initialisation routine at the - moment, this was not done. - ATTENTION: TERMIOS init presupposes that the channel - baud rates is 9600/9600. - -> risks when using IOCTL - *****************************************************/ -void Init_UART_Table(void) -{ - m340_uart_config[UART_CHANNEL_A].enable = TRUE; - strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME); - m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity; - m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc; - m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600; - m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600; - m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR; - m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING; - - m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE; - m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; - m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; - - m340_uart_config[UART_CHANNEL_B].enable = FALSE; - strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME); - m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity; - m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc; - m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400; - m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400; - m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR; - m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS; - - m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE; - m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; - m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; -} - -/****************************************************** - Name: Find_Right_m340_UART_Channel_Config - Input parameters: Send/Receive baud rates for a - given channel - Output parameters: UART compatible configs for this - channel - Description: returns which uart configurations fit - Receiver Baud Rate and Transmitter Baud - Rate for a given channel - For instance, according to the - m340_Baud_Rates_Table: - - Output Speed = 50, Input Speed = 75 - is not a correct config, because - 50 bauds implies set 1 and 75 bauds - implies set 2 - - Output Speed = 9600, Input Speed = 9600 - two correct configs for this: - RCS=11, TCS=11, Set=1 or 2 - *****************************************************/ -static t_baud_speed_table -Find_Right_m340_UART_Channel_Config( - float ReceiverBaudRate, - float TransmitterBaudRate -) -{ - t_baud_speed_table return_value; - int i,j; - - struct { - int cs; - int set; - } Receiver[2], Transmitter[2]; - - int Receiver_nb_of_config = 0; - int Transmitter_nb_of_config = 0; - - /* Receiver and Transmitter baud rates must be compatible, ie in the - * same set. - */ - - /* search for configurations for ReceiverBaudRate - * there can't be more than two (only two sets). - */ - for (i=0;i<16;i++) { - for (j=0;j<2;j++) { - if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) { - Receiver[Receiver_nb_of_config].cs=i; - Receiver[Receiver_nb_of_config].set=j; - Receiver_nb_of_config++; - } - } - } - - /* search for configurations for TransmitterBaudRate - * there can't be more than two (only two sets) - */ - for (i=0;i<16;i++) { - for (j=0;j<2;j++) { - if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) { - Transmitter[Transmitter_nb_of_config].cs=i; - Transmitter[Transmitter_nb_of_config].set=j; - Transmitter_nb_of_config++; - } - } - } - - /* now check if there's a compatible config */ - return_value.nb=0; - - for (i=0; i -#include -#include -#include -#include -#include - -/* - * Declare clock speed -- may be overwritten by downloader or debugger - */ -int m360_clock_rate = 25000000; - -/* - * Interrupt-driven input buffer - * Declare console baud rate -- may also be overwritten - */ -int console_baud_rate = 9600; - -/* - */ -#define RXBUFSIZE 16 - -/* - * Interrupt-driven callback - */ -static int m360_smc1_interrupt = 1; -static void *smc1ttyp; - -/* - * I/O buffers and pointers to buffer descriptors - */ -static volatile char rxBuf[RXBUFSIZE]; -static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; - -/* - * Device-specific routines - */ - -/* - * Compute baud-rate-generator configuration register value - */ -static int -smc1BRGC (int baud) -{ - int divisor; - int div16 = 0; - - divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud; - if (divisor > 4096) { - div16 = 1; - divisor = (divisor + 8) / 16; - } - return M360_BRG_EN | M360_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16; -} - -/* - * Hardware-dependent portion of tcsetattr(). - */ -static int -smc1SetAttributes (int minor, const struct termios *t) -{ - int baud; - - baud = rtems_termios_baud_to_number(t->c_ospeed); - if (baud > 0) - m360.brgc1 = smc1BRGC (baud); - return 0; -} - -/* - * Interrupt handler - */ -static rtems_isr -smc1InterruptHandler (rtems_vector_number v) -{ - /* - * Buffer received? - */ - if (m360.smc1.smce & 0x1) { - m360.smc1.smce = 0x1; - while ((smcRxBd->status & M360_BD_EMPTY) == 0) { - rtems_termios_enqueue_raw_characters (smc1ttyp, - (char *)smcRxBd->buffer, - smcRxBd->length); - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; - } - } - - /* - * Buffer transmitted? - */ - if (m360.smc1.smce & 0x2) { - m360.smc1.smce = 0x2; - if ((smcTxBd->status & M360_BD_READY) == 0) - rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length); - } - m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ -} - -static int -smc1Initialize (int major, int minor, void *arg) -{ - /* - * Allocate buffer descriptors - */ - smcRxBd = M360AllocateBufferDescriptors (1); - smcTxBd = M360AllocateBufferDescriptors (1); - - /* - * Configure port B pins to enable SMTXD1 and SMRXD1 pins - */ - m360.pbpar |= 0xC0; - m360.pbdir &= ~0xC0; - m360.pbodr &= ~0xC0; - - /* - * Set up BRG1 (9,600 baud) - */ - m360.brgc1 = M360_BRG_RST; - m360.brgc1 = smc1BRGC (console_baud_rate); - - /* - * Put SMC1 in NMSI mode, connect SMC1 to BRG1 - */ - m360.simode |= M360_SI_SMC1_BRG1; - - /* - * Set up SMC1 parameter RAM common to all protocols - */ - m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360; - m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360; - m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; - m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; - if (m360_smc1_interrupt) - m360.smc1p.mrblr = RXBUFSIZE; - else - m360.smc1p.mrblr = 1; - - /* - * Set up SMC1 parameter RAM UART-specific parameters - */ - m360.smc1p.un.uart.max_idl = 10; - m360.smc1p.un.uart.brklen = 0; - m360.smc1p.un.uart.brkec = 0; - m360.smc1p.un.uart.brkcr = 0; - - /* - * Set up the Receive Buffer Descriptor - */ - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; - smcRxBd->length = 0; - smcRxBd->buffer = rxBuf; - - /* - * Setup the Transmit Buffer Descriptor - */ - smcTxBd->status = M360_BD_WRAP; - - /* - * Set up SMC1 general and protocol-specific mode registers - */ - m360.smc1.smce = ~0; /* Clear any pending events */ - m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ - m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; - - /* - * Send "Init parameters" command - */ - M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); - - /* - * Enable receiver and transmitter - */ - m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; - - if (m360_smc1_interrupt) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (smc1InterruptHandler, - (m360.cicr & 0xE0) | 0x04, - &old_handler); - m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */ - m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ - } - - return 0; -} - -static int -smc1PollRead (int minor) -{ - unsigned char c; - - if (smcRxBd->status & M360_BD_EMPTY) - return -1; - c = rxBuf[0]; - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; - return c; -} - -/* - * Device-dependent write routine - * Interrupt-driven devices: - * Begin transmission of as many characters as possible (minimum is 1). - * Polling devices: - * Transmit all characters. - */ -static ssize_t -smc1InterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - smcTxBd->buffer = (char *)buf; - smcTxBd->length = len; - smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT; - } - - return 0; -} - -static ssize_t -smc1PollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - while (len--) { - static char txBuf; - while (smcTxBd->status & M360_BD_READY) - continue; - txBuf = *buf++; - smcTxBd->buffer = &txBuf; - smcTxBd->length = 1; - smcTxBd->status = M360_BD_READY | M360_BD_WRAP; - } - return retval; -} - -/* - *************** - * BOILERPLATE * - *************** - */ - -/* - * Reserve resources consumed by this driver - * - * NOTE: This is in another file to reduce dependencies on the minimum size. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize (); - - /* - * Register the device - */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code sc; - static const rtems_termios_callbacks intrCallbacks = { - smc1Initialize, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - smc1InterruptWrite, /* write */ - smc1SetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks pollCallbacks = { - smc1Initialize, /* firstOpen */ - NULL, /* lastClose */ - smc1PollRead, /* pollRead */ - smc1PollWrite, /* write */ - smc1SetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - /* - * Do generic termios initialization - */ - if (m360_smc1_interrupt) { - rtems_libio_open_close_args_t *args = arg; - - sc = rtems_termios_open (major, minor, arg, &intrCallbacks); - smc1ttyp = args->iop->data1; - } - else { - sc = rtems_termios_open (major, minor, arg, &pollCallbacks); - } - return sc; -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl (arg); -} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am index a20f56ad89..3ba91a7f92 100644 --- a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am +++ b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/genmcf548x/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/genmcf548x/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/genmcf548x/console/console.c b/c/src/lib/libbsp/m68k/genmcf548x/console/console.c deleted file mode 100644 index 32e5601a17..0000000000 --- a/c/src/lib/libbsp/m68k/genmcf548x/console/console.c +++ /dev/null @@ -1,843 +0,0 @@ -/*===============================================================*\ -| Project: RTEMS generic mcf548x BSP | -+-----------------------------------------------------------------+ -| File: console.c | -+-----------------------------------------------------------------+ -| The file contains the console driver code of generic MCF548x | -| BSP. | -+-----------------------------------------------------------------+ -| Copyright (c) 2007 | -| Embedded Brains GmbH | -| Obere Lagerstr. 30 | -| D-82178 Puchheim | -| Germany | -| rtems@embedded-brains.de | -+-----------------------------------------------------------------+ -| | -| Parts of the code has been derived from the "dBUG source code" | -| package Freescale is providing for M548X EVBs. The usage of | -| the modified or unmodified code and it's integration into the | -| generic mcf548x BSP has been done according to the Freescale | -| license terms. | -| | -| The Freescale license terms can be reviewed in the file | -| | -| Freescale_license.txt | -| | -+-----------------------------------------------------------------+ -| | -| The generic mcf548x BSP has been developed on the basic | -| structures and modules of the av5282 BSP. | -| | -+-----------------------------------------------------------------+ -| | -| 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. | -| | -+-----------------------------------------------------------------+ -| | -| date history ID | -| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | -| 12.11.07 1.0 ras | -| | -\*===============================================================*/ - - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x)) - -#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF | \ - MCF548X_PSC_SR_FE_PHYERR | \ - MCF548X_PSC_SR_PE_CRCERR | \ - MCF548X_PSC_SR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static int IntUartPollRead (int minor); -static int IntUartSetAttributes(int minor, const struct termios *t); - -static void -psc_output_char( char c ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) - continue; - *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c; - while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) - continue; - rtems_interrupt_enable(level); -} - -static void -psc_output_char_init(char c) -{ - IntUartSetAttributes(CONSOLE_PORT, NULL); - BSP_output_char = psc_output_char; - psc_output_char(c); -} - -BSP_output_char_function_type BSP_output_char = psc_output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 4 -#define RX_BUFFER_SIZE 248 - -struct IntUartInfoStruct -{ - int iomode; - volatile int imr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -static int GetBaud( int baudHandle ) -{ - int baud = BSP_CONSOLE_BAUD; - switch(baudHandle) - { - case B0: - baud = (int)0; - break; - case B1200: - baud = (int)1200; - break; - case B2400: - baud = (int)2400; - break; - case B4800: - baud = (int)4800; - break; - case B9600: - baud = (int)9600; - break; - case B19200: - baud = (int)19200; - break; - case B38400: - baud = (int)38400; - break; - case B57600: - baud = (int)57600; - break; - case B115200: - baud = (int)115200; - break; - } - return baud; -} - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - uint8_t psc_mode_1 = 0, psc_mode_2 = 0; - uint16_t divider; - int level; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - /* Mask all psc interrupts */ - MCF548X_PSC_IMR(minor) = 0x0000; - - /* Clear RTS to send */ - MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS); - - /* Disable receiver and transmitter */ - MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); - - /* provide gpio settings */ - switch (minor) - { - case 0: - MCF548X_GPIO_PAR_PSC0 = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS); - } - break; - case 1: - MCF548X_GPIO_PAR_PSC1 = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS); - } - break; - case 2: - MCF548X_GPIO_PAR_PSC2 = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS); - } - break; - case 3: - MCF548X_GPIO_PAR_PSC3 = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS); - } - break; - default: - break; - } - - /* save the current values */ - info->imr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - /* Put PSC in UART mode */ - MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART; - - /* set the baud rate values */ - MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK); - - /* Calculate baud settings */ - divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32)); - MCF548X_PSC_CTUR(minor) = (uint8_t) ((divider >> 8) & 0xFF); - MCF548X_PSC_CTLR(minor) = (uint8_t) (divider & 0xFF); - - /* Reset transmitter, receiver, mode register, and error conditions */ - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR; - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - psc_mode_1 = MCF548X_PSC_MR_RXRTS; - psc_mode_2 = MCF548X_PSC_MR_TXCTS; - } - - /* set mode registers */ - psc_mode_1 |= (uint8_t)(parity | databits); - psc_mode_2 |= (uint8_t)(stopbits); - - /* set mode registers */ - MCF548X_PSC_MR(minor) = psc_mode_1; - MCF548X_PSC_MR(minor) = psc_mode_2; - - /* Setup FIFO Alarms */ - MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248); - MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->imr |= MCF548X_PSC_IMR_RXRDY_FU; - MCF548X_PSC_IMR(minor) = info->imr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; - } - - rtems_interrupt_enable(level); - - /* Enable receiver and transmitter */ - MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); - - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ -/* set default index values */ -#ifdef HAS_DBUG - int baud = DBUG_SETTINGS.console_baudrate; -#else - int baud = (int)BSP_CONSOLE_BAUD; -#endif - int databits = (int)MCF548X_PSC_MR_BC_8; - int parity = (int)MCF548X_PSC_MR_PM_NONE; - int stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1; - int hwflow = (int)1; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = GetBaud( t->c_ospeed ); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF548X_PSC_MR_BC_5; - break; - case CS6: - databits = (int)MCF548X_PSC_MR_BC_6; - break; - case CS7: - databits = (int)MCF548X_PSC_MR_BC_7; - break; - case CS8: - databits = (int)MCF548X_PSC_MR_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF548X_PSC_MR_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF548X_PSC_MR_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - -return RTEMS_SUCCESSFUL; - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU ) - { - /* read data and put into the receive buffer */ - while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY ) - { - - /* put data in rx buffer */ - info->rx_buffer[info->rx_in] = *((volatile uint8_t *)&MCF548X_PSC_RB(chan)); - - /* check for errors */ - if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR ) - { - /* clear the error */ - MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR; - } - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->imr & MCF548X_PSC_IMR_TXRDY ) && - ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->imr &= ~MCF548X_PSC_IMR_TXRDY; - MCF548X_PSC_IMR(chan) = info->imr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } - -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - - MCF548X_PSC_ACR(chan) = 0; - MCF548X_PSC_IMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - bsp_interrupt_vector_enable(MCF548X_IRQ_PSC(chan)); - } /* of chan loop */ - - BSP_output_char = psc_output_char; -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - *(volatile uint8_t *)(&MCF548X_PSC_TB(minor)) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY; - MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr; - } - - return 0; -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->imr |= MCF548X_PSC_IMR_RXRDY_FU; - MCF548X_PSC_IMR(minor) = info->imr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; - } - - return 0; -} - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF548X_PSC_IMR(minor) = 0; - MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); - - /* reset values */ - info->ttyp = NULL; - info->imr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return 0; -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return EOF; -} - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ -if (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY))) - return(-1); - - return *((uint8_t *)&MCF548X_PSC_RB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; -/* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY))) - continue; - /* transmit data byte */ - *((uint8_t *)&MCF548X_PSC_TB(minor)) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; //TERMIOS_POLLED; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/*************************************************************************** - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} diff --git a/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am b/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am index 12ddd0340f..465a4f8b53 100644 --- a/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am @@ -32,8 +32,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5206elite/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # i2c librtemsbsp_a_SOURCES += i2c/i2c.c librtemsbsp_a_SOURCES += i2c/i2cdrv.c diff --git a/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c b/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c deleted file mode 100644 index bbf343d0f3..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Console driver for Motorola MCF5206E UART modules - */ - -/* - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia - * Author: Victor V. Vengerov - * - * COPYRIGHT (c) 1989-1998. - * 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 -#include -#include -#include -#include "mcf5206/mcf5206e.h" -#include "mcf5206/mcfuart.h" - -/* Descriptor structures for two on-chip UART channels */ -static mcfuart uart[2]; - -/* Console operations mode: - * 0 - raw (non-termios) polled input/output - * 1 - termios-based polled input/output - * 2 - termios-based interrupt-driven input/output - */ -int console_mode = 2; -#define CONSOLE_MODE_RAW (0) -#define CONSOLE_MODE_POLL (1) -#define CONSOLE_MODE_INT (2) - -/* Wrapper functions for MCF UART generic driver */ - -/* console_poll_read -- - * wrapper for poll read function - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * character code readed from UART, or -1 if there is no characters - * available - */ -static int -console_poll_read(int minor) -{ - return mcfuart_poll_read(&uart[minor]); -} - -/* console_interrupt_write -- - * wrapper for interrupt write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_interrupt_write(int minor, const char *buf, size_t len) -{ - return mcfuart_interrupt_write(&uart[minor], buf, len); -} - -/* console_poll_write -- - * wrapper for polling mode write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_poll_write(int minor, const char *buf, size_t len) -{ - return mcfuart_poll_write(&uart[minor], buf, len); -} - -/* console_set_attributes -- - * wrapper for hardware-dependent termios attributes setting - * - * PARAMETERS: - * minor - minor device number - * t - pointer to the termios structure - * - * RETURNS: - * result code - */ -static int -console_set_attributes(int minor, const struct termios *t) -{ - return mcfuart_set_attributes(&uart[minor], t); -} - -/* console_stop_remote_tx -- - * wrapper for stopping data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * result code - */ -static int -console_stop_remote_tx(int minor) -{ - if (minor < sizeof(uart)/sizeof(uart[0])) - return mcfuart_stop_remote_tx(&uart[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_start_remote_tx -- - * wrapper for resuming data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - */ -static int -console_start_remote_tx(int minor) -{ - if (minor < sizeof(uart)/sizeof(uart[0])) - return mcfuart_start_remote_tx(&uart[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_first_open -- - * wrapper for UART controller initialization functions - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device open argument - * - * RETURNS: - * error code - */ -static int -console_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_status_code sc; - uint8_t intvec; - - switch (minor) { - case 0: intvec = BSP_INTVEC_UART1; break; - case 1: intvec = BSP_INTVEC_UART2; break; - default: - return RTEMS_INVALID_NUMBER; - } - - if (console_mode != CONSOLE_MODE_INT) { - intvec = 0; - } - - sc = mcfuart_init( - &uart[minor], /* uart */ - args->iop->data1, /* tty */ - intvec, /* interrupt vector number */ - minor+1); - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[minor]); - - return sc; -} - -/* console_last_close -- - * wrapper for UART controller close function - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device close argument - * - * RETURNS: - * error code - */ -static int -console_last_close(int major, int minor, void *arg) -{ - return mcfuart_disable(&uart[minor]); -} - -/* console_initialize -- - * This routine initializes the console IO drivers and register devices - * in RTEMS I/O system. - * - * PARAMETERS: - * major - major console device number - * minor - minor console device number (not used) - * arg - device initialize argument - * - * RETURNS: - * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* - * Set up TERMIOS - */ - if (console_mode != CONSOLE_MODE_RAW) - rtems_termios_initialize (); - - /* - * Register the devices - */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/aux", major, 1); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - if (console_mode == CONSOLE_MODE_RAW) { - rtems_status_code sc; - sc = mcfuart_init(&uart[0], /* uart */ - NULL, /* tty */ - 0, /* interrupt vector number */ - 1); /* UART channel number */ - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[0]); - - sc = mcfuart_init(&uart[1], /* uart */ - NULL, /* tty */ - 0, /* interrupt vector number */ - 2); /* UART channel number */ - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[1]); - return sc; - } - - return RTEMS_SUCCESSFUL; -} - -/* console_open -- - * Open console device driver. Pass appropriate termios callback - * functions to termios library. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device opening argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - static const rtems_termios_callbacks intr_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - NULL, /* pollRead */ - console_interrupt_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks poll_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - console_poll_read, /* pollRead */ - console_poll_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - switch (console_mode) { - case CONSOLE_MODE_RAW: - return RTEMS_SUCCESSFUL; - - case CONSOLE_MODE_INT: - return rtems_termios_open(major, minor, arg, &intr_callbacks); - - case CONSOLE_MODE_POLL: - return rtems_termios_open(major, minor, arg, &poll_callbacks); - - default: - rtems_fatal_error_occurred(0xC07A1310); - } - return RTEMS_INTERNAL_ERROR; -} - -/* console_close -- - * Close console device. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device close argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) - return rtems_termios_close (arg); - else - return RTEMS_SUCCESSFUL; -} - -/* console_read -- - * Read from the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device read argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_read (arg); - } else { - rtems_libio_rw_args_t *argp = arg; - char *buf = argp->buffer; - int count = argp->count; - int n = 0; - int c; - - while (n < count) { - do { - c = mcfuart_poll_read(&uart[minor]); - } while (c == -1); - if (c == '\r') - c = '\n'; - *(buf++) = c; - n++; - if (c == '\n') - break; - } - argp->bytes_moved = n; - return RTEMS_SUCCESSFUL; - } -} - -/* console_write -- - * Write to the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device write argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_write (arg); - } else { - rtems_libio_rw_args_t *argp = arg; - char cr = '\r'; - char *buf = argp->buffer; - int count = argp->count; - int i; - - for (i = 0; i < count; i++) { - if (*buf == '\n') - mcfuart_poll_write(&uart[minor], &cr, 1); - mcfuart_poll_write(&uart[minor], buf, 1); - buf++; - } - argp->bytes_moved = count; - return RTEMS_SUCCESSFUL; - } -} - -/* console_control -- - * Handle console device I/O control (IOCTL) - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device ioctl argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_ioctl (arg); - } else { - return RTEMS_SUCCESSFUL; - } -} diff --git a/c/src/lib/libbsp/m68k/mcf52235/Makefile.am b/c/src/lib/libbsp/m68k/mcf52235/Makefile.am index 98b8993521..c9138f2d66 100644 --- a/c/src/lib/libbsp/m68k/mcf52235/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf52235/Makefile.am @@ -31,9 +31,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf52235/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf52235/console/console.c # debugio -librtemsbsp_a_SOURCES += console/debugio.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf52235/console/debugio.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf52235/console/console.c b/c/src/lib/libbsp/m68k/mcf52235/console/console.c deleted file mode 100644 index c2b6e36bfa..0000000000 --- a/c/src/lib/libbsp/m68k/mcf52235/console/console.c +++ /dev/null @@ -1,656 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); - break; - - case 1: - MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); - break; - - case 2: - MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the other port */ - if (CONSOLE_PORT != 0) { - status = rtems_io_register_name("/dev/tty00", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - if (CONSOLE_PORT != 1) { - status = rtems_io_register_name("/dev/tty01", major, 1); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c b/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c deleted file mode 100644 index 1fbf4b09d7..0000000000 --- a/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c +++ /dev/null @@ -1,32 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -static void _BSP_null_char(char c) -{ - int level; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am b/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am index 99b996c1f4..f93dd98d5f 100644 --- a/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am @@ -24,8 +24,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5225x/clock/clock.c -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/debugio.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5225x/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5225x/console/debugio.c librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf5225x.c diff --git a/c/src/lib/libbsp/m68k/mcf5225x/console/console.c b/c/src/lib/libbsp/m68k/mcf5225x/console/console.c deleted file mode 100644 index 9e36e3945a..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5225x/console/console.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * 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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - -#if 1 /* TZN: maybe needed for santec bus modul handling */ - if (minor==STATIONS_PORT) - umr2 |= (stopbits) | 0x20; /* 0x20 ... set TXRTS just4testing */ - else - umr2 |= (stopbits); -#else - umr2 |= (stopbits); -#endif - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - if (minor==STATIONS_PORT) //maybe needed for santec handling - MCF_UART_UOP0(minor) = 1; - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - -#if 0 /* TZN ... just4testing */ - if (MCF_GPIO_PORTTC&MCF_GPIO_PORTTC_PORTTC0) - MCF_GPIO_PORTTC &= ~MCF_GPIO_PORTTC_PORTTC0; - else - MCF_GPIO_PORTTC |= MCF_GPIO_PORTTC_PORTTC0; -#endif - - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_IRQ_DRIVEN; /*TZN, irq driven console io */ - //info->iomode = TERMIOS_POLLED; /*TZN, just4testint, use polling mode for all UARTS */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); - break; - - case 1: - MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); - break; - - case 2: - MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static -int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return (0); -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the RS485 port to communicate with SANTEC stations */ - if ((STATIONS_PORT!=CONSOLE_PORT) && (STATIONS_PORT!=BLUETOOTH_PORT)) { - status = rtems_io_register_name("/dev/tty00", major,STATIONS_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - else { - status=RTEMS_TOO_MANY; - rtems_fatal_error_occurred(status); - } - - /* Register the Bluetooth port */ - if ((BLUETOOTH_PORT!=CONSOLE_PORT) && (BLUETOOTH_PORT!=STATIONS_PORT)) { - status = rtems_io_register_name("/dev/tty01", major, BLUETOOTH_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - else { - status=RTEMS_TOO_MANY; - rtems_fatal_error_occurred(status); - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B115200; - term.c_ospeed = B115200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c b/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c deleted file mode 100644 index b91048a310..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * 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 -#include -#include -#include -#include -#include -#include - -#include - -static void _BSP_null_char(char c) -{ - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am index c4caf60792..abc3b777d2 100644 --- a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES += startup/copyvectors.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5235/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5235/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf5235/console/console.c b/c/src/lib/libbsp/m68k/mcf5235/console/console.c deleted file mode 100644 index 38317130cb..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5235/console/console.c +++ /dev/null @@ -1,745 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5235_UART_USR_ERROR ( MCF5235_UART_USR_RB | \ - MCF5235_UART_USR_FE | \ - MCF5235_UART_USR_PE | \ - MCF5235_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void -_BSP_null_char( char c ) -{ - int level; - - rtems_interrupt_disable(level); - while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - MCF5235_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - rtems_interrupt_enable(level); -} -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5235_UART_UIMR(minor) = 0; - MCF5235_UART_UOP0(minor) = 1; - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed/2) / ( 32 * baud )); - if ( divisor < 2 ) { - divisor = 2; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - umr1 |= MCF5235_UART_UMR_RXRTS; - umr2 |= MCF5235_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_ERROR; - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_RX; - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_MR; - MCF5235_UART_UMR(minor) = umr1; - MCF5235_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5235_UART_UCSR(minor) = (MCF5235_UART_UCSR_RCS_SYS_CLK | MCF5235_UART_UCSR_TCS_SYS_CLK); - MCF5235_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5235_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5235_UART_UIMR_FFULL; - MCF5235_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF5235_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int)19200; - int databits = (int)MCF5235_UART_UMR_BC_8; - int parity = (int)MCF5235_UART_UMR_PM_NONE; - int stopbits = (int)MCF5235_UART_UMR_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF5235_UART_UMR_BC_5; - break; - case CS6: - databits = (int)MCF5235_UART_UMR_BC_6; - break; - case CS7: - databits = (int)MCF5235_UART_UMR_BC_7; - break; - case CS8: - databits = (int)MCF5235_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF5235_UART_UMR_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF5235_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF5235_UART_UMR_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return( RTEMS_SUCCESSFUL ); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_RXRDY ) - { - /* read data and put into the receive buffer */ - while ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_RXRDY ) - { - - if ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_ERROR ) - { - /* clear the error */ - MCF5235_UART_UCR(chan) = MCF5235_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5235_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5235_UART_UIMR_TXRDY ) && - ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5235_UART_UIMR_TXRDY; - MCF5235_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - - - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF5235_UART_UACR(chan) = 0; - MCF5235_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - MCF5235_INTC0_ICR13 = MCF5235_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT13 | - MCF5235_INTC0_IMRL_MASKALL); - break; - - case 1: - MCF5235_INTC0_ICR14 = MCF5235_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT14 | - MCF5235_INTC0_IMRL_MASKALL); - break; - - case 2: - MCF5235_INTC0_ICR15 = MCF5235_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT15 | - MCF5235_INTC0_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF5235_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5235_UART_UIMR_TXRDY; - MCF5235_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5235_UART_UIMR_FFULL; - MCF5235_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF5235_UART_UOP1(minor) = 1; - } - - return( 0 ); -} - - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5235_UART_UIMR(minor) = 0; - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return( EOF ); -} - - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ - if ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_RXRDY) == 0 ) - return(-1); - - return(MCF5235_UART_URB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5235_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) - { - /* - * Reset the default baudrate. - */ - struct termios term; - if (tcgetattr (STDIN_FILENO, &term) >= 0) - { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr (STDIN_FILENO, TCSANOW, &term); - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} diff --git a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am index 5a82f8849f..1be86750a6 100644 --- a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am @@ -31,7 +31,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5329/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5329/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf5329/console/console.c b/c/src/lib/libbsp/m68k/mcf5329/console/console.c deleted file mode 100644 index 797e5b0606..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5329/console/console.c +++ /dev/null @@ -1,668 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+26+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -static void _BSP_null_char(char c) -{ - int level; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_BUS_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR26 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK26); - break; - - case 1: - MCF_INTC0_ICR27 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK27); - break; - - case 2: - MCF_INTC0_ICR28 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK28); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the other port */ - if (CONSOLE_PORT != 0) { - status = rtems_io_register_name("/dev/tty00", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - if (CONSOLE_PORT != 1) { - status = rtems_io_register_name("/dev/tty01", major, 1); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/*************************************************************************** - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mrm332/Makefile.am b/c/src/lib/libbsp/m68k/mrm332/Makefile.am index 462628eba3..4677565797 100644 --- a/c/src/lib/libbsp/m68k/mrm332/Makefile.am +++ b/c/src/lib/libbsp/m68k/mrm332/Makefile.am @@ -29,8 +29,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mrm332/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/sci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mrm332/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mrm332/console/sci.c # spurious librtemsbsp_a_SOURCES += spurious/spinit.c # timer diff --git a/c/src/lib/libbsp/m68k/mrm332/console/console.c b/c/src/lib/libbsp/m68k/mrm332/console/console.c deleted file mode 100644 index 7b5ae7d51c..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/console.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * COPYRIGHT (c) 1989-1997. - * 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 - -#include -#include -#include -#include "sci.h" - -/* - * console_open - * - * open a port as a termios console. - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code status; - - /* the console is opened three times at startup */ - /* for standard input, output, and error */ - - /* Get correct callback structure for the device */ - - /* argument of FALSE gives us interrupt driven serial io */ - /* argument of TRUE gives us polling based serial io */ - - /* SCI internal uart */ - - status = rtems_termios_open( major, minor, arg, SciGetTermiosHandlers( FALSE ) ); - - return status; -} - -/* - * console_close - * - * This routine closes a port that has been opened as console. - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/* - * console_read - * - * This routine uses the termios driver to read a character. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/* - * console_write - * - * this routine uses the termios driver to write a character. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/* - * console_control - * - * this routine uses the termios driver to process io - */ - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl (arg); -} - -/* - * console_initialize - * - * Routine called to initialize the console device driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor_arg, - void *arg -) -{ - rtems_status_code status; - - /* - * initialize the termio interface. - */ - rtems_termios_initialize(); - - /* - * register the SCI device name for termios - * do this over in the sci driver init routine? - */ - - status = rtems_io_register_name( "/dev/sci", major, 0 ); - - if (status != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(status); - } - - /* - * Link the uart device to the console device - */ - -#if 1 - status = rtems_io_register_name( "/dev/console", major, 0 ); - - if (status != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(status); - } -#else - if ( link( "/dev/sci", "/dev/console") < 0 ) - { - rtems_fatal_error_occurred( RTEMS_IO_ERROR ); - } -#endif - - /* - * Console Initialize Succesful - */ - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.c b/c/src/lib/libbsp/m68k/mrm332/console/sci.c deleted file mode 100644 index c6b4933f13..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/sci.c +++ /dev/null @@ -1,1586 +0,0 @@ -/***************************************************************************** -* File: sci.c -* -* Desc: This file contains the console IO routines for the SCI port. -* There are two interfaces in this module. One is for the rtems -* termios/console code and the other is a device driver interface. -* This module works together with the termio module which is -* sometimes referred to as the "line disciplines" which implements -* terminal i/o processing like tabs, backspaces, and newlines. -* The rtems printf uses interrupt io and the rtems printk routine -* uses polled io which is better for debugging. -* -* Index: Documentation -* Section A - Include Files -* Section B - Manifest Constants -* Section C - External Data -* Section D - External Functions -* Section E - Local Functions -* Section F - Local Variables -* Section G - A circular data buffer for rcv chars -* Section H - RTEMS termios callbacks for the interrupt api -* Section I - RTEMS termios callbacks for the polled api - -* Section 0 - Miscellaneous routines -* Section 1 - Routines to manipulate the circular buffer -* Section 2 - Interrupt based entry points for the termios module -* Section 3 - Polling based entry points for the termios module -* Section 4 - Device driver public api entry points -* Section 5 - Hardware level routines -* Section 6 - Testing and debugging code -* -* Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module -* -* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. -* -*****************************************************************************/ - -/***************************************************************************** - Overview of serial port console terminal input/output -*****************************************************************************/ - -/* - +-----------+ +---------+ - | app | | app | - +-----------+ +---------+ - | | - | (printf,scanf,etc.) | - v | - +-----------+ | - | libc | | - +-----------+ | - | | - | | - | (open,close,read,write,ioctl) | - ======|==========================================|======================== - | /dev/console | /dev/sci - | (stdin,stdout,stderr) | - ======|==========================================|======================== - | | - | | - v v - +-----------+ +-----------+ +---------+ - | console | <---> | termios | <---> | sci | - | driver | | module | | driver | - +-----------+ +-----------+ +---------+ - | - | - v - +---------+ - | | - | uart | - | | - +---------+ -*/ - - -/***************************************************************************** - Section A - Include Files -*****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include "sci.h" -#include -#include -/*#include "../misc/include/cpu332.h" */ - -/***************************************************************************** - Section B - Manifest Constants -*****************************************************************************/ - -#define SCI_MINOR 0 /* minor device number */ - -/* IMPORTANT - if the device driver api is opened, it means the sci is being - * used for direct hardware access, so other users (like termios) get ignored - */ -#define DRIVER_CLOSED 0 /* the device driver api is closed */ -#define DRIVER_OPENED 1 /* the device driver api is opened */ - -/* system clock definitions, i dont have documentation on this... */ - -#if 0 /* Not needed, this is provided in mrm332.h */ -#define XTAL 32768.0 /* crystal frequency in Hz */ -#define NUMB_W 0 /* system clock parameters */ -#define NUMB_X 1 -#define NUMB_Y 0x38 /* for 14.942 Mhz */ -#define NUMB_Y 0x3F /* for 16.777 Mhz */ - -#define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X))) - -#endif - - -/***************************************************************************** - Section C - External Data -*****************************************************************************/ - - - -/***************************************************************************** - Section D - External Functions -*****************************************************************************/ - - - -/***************************************************************************** - Section E - Local Functions -*****************************************************************************/ - -void SCI_output_char(char c); - -/*rtems_isr SciIsr( rtems_vector_number vector ); interrupt handler */ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); - -rtems_device_driver SciInitialize( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciOpen( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciClose( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciRead( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciWrite( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciControl( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciRead ( - rtems_device_major_number, rtems_device_minor_number, void *); - -rtems_isr SciIsr( rtems_vector_number vector ); - -int SciInterruptOpen(int, int, void *); /* termios api */ -int SciInterruptClose(int, int, void *); /* termios api */ -ssize_t SciInterruptWrite(int, const char *, size_t); /* termios api */ - -int SciSetAttributes(int, const struct termios*); /* termios api */ -int SciPolledOpen(int, int, void *); /* termios api */ -int SciPolledClose(int, int, void *); /* termios api */ -int SciPolledRead(int); /* termios api */ -ssize_t SciPolledWrite(int, const char *, size_t); /* termios api */ - -static void SciSetBaud(uint32_t rate); /* hardware routine */ -static void SciSetDataBits(uint16_t bits); /* hardware routine */ -static void SciSetParity(uint16_t parity); /* hardware routine */ - -static void inline SciDisableAllInterrupts( void ); /* hardware routine */ -static void inline SciDisableTransmitInterrupts( void );/* hardware routine */ -static void inline SciDisableReceiveInterrupts( void ); /* hardware routine */ - -static void inline SciEnableTransmitInterrupts( void ); /* hardware routine */ -static void inline SciEnableReceiveInterrupts( void ); /* hardware routine */ - -static void inline SciDisableReceiver( void ); /* hardware routine */ -static void inline SciDisableTransmitter( void ); /* hardware routine */ - -static void inline SciEnableReceiver( void ); /* hardware routine */ -static void inline SciEnableTransmitter( void ); /* hardware routine */ - -void SciWriteCharWait ( uint8_t ); /* hardware routine */ -void SciWriteCharNoWait( uint8_t ); /* hardware routine */ - -uint8_t inline SciCharAvailable( void ); /* hardware routine */ - -static uint8_t inline SciReadCharWait( void ); /* hardware routine */ -static uint8_t inline SciReadCharNoWait( void ); /* hardware routine */ - -void SciSendBreak( void ); /* test routine */ - -static int8_t SciRcvBufGetChar(void); /* circular rcv buf */ -static void SciRcvBufPutChar( uint8_t); /* circular rcv buf */ -#if 0 -static void SciRcvBufFlush( void ); /* unused routine */ -#endif - -void SciUnitTest(void); /* test routine */ -void SciPrintStats(void); /* test routine */ - - -/***************************************************************************** - Section F - Local Variables -*****************************************************************************/ - -static struct rtems_termios_tty *SciTermioTty; - -static uint8_t SciInited = 0; /* has the driver been inited */ - -static uint8_t SciOpened; /* has the driver been opened */ - -static uint8_t SciMajor; /* major device number */ - -static uint16_t SciBaud; /* current value in baud register */ - -static uint32_t SciBytesIn = 0; /* bytes received */ -static uint32_t SciBytesOut = 0; /* bytes transmitted */ - -static uint32_t SciErrorsParity = 0; /* error counter */ -static uint32_t SciErrorsNoise = 0; /* error counter */ -static uint32_t SciErrorsFraming = 0; /* error counter */ -static uint32_t SciErrorsOverrun = 0; /* error counter */ - -#if defined(CONSOLE_SCI) - -/* this is what rtems printk uses to do polling based output */ - -BSP_output_char_function_type BSP_output_char = SCI_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#endif - -/***************************************************************************** - Section G - A circular buffer for rcv chars when the driver interface is used. -*****************************************************************************/ - -/* it is trivial to wrap your buffer pointers when size is a power of two */ - -#define SCI_RCV_BUF_SIZE 256 /* must be a power of 2 !!! */ - -/* if someone opens the sci device using the device driver interface, - * then the receive data interrupt handler will put characters in this buffer - * instead of sending them up to the termios module for the console - */ -static uint8_t SciRcvBuffer[SCI_RCV_BUF_SIZE]; - -static uint8_t SciRcvBufPutIndex = 0; /* array index to put in next char */ - -static uint8_t SciRcvBufGetIndex = 0; /* array index to take out next char */ - -static uint16_t SciRcvBufCount = 0; /* how many bytes are in the buffer */ - - - -/***************************************************************************** - Section H - RTEMS termios callbacks for the interrupt version of the driver -*****************************************************************************/ - -static const rtems_termios_callbacks SciInterruptCallbacks = -{ - SciInterruptOpen, /* first open */ - SciInterruptClose, /* last close */ - NULL, /* polled read (not required) */ - SciInterruptWrite, /* write */ - SciSetAttributes, /* set attributes */ - NULL, /* stop remote xmit */ - NULL, /* start remote xmit */ - TRUE /* output uses interrupts */ -}; - -/***************************************************************************** - Section I - RTEMS termios callbacks for the polled version of the driver -*****************************************************************************/ - -static const rtems_termios_callbacks SciPolledCallbacks = -{ - SciPolledOpen, /* first open */ - SciPolledClose, /* last close */ - SciPolledRead, /* polled read */ - SciPolledWrite, /* write */ - SciSetAttributes, /* set attributes */ - NULL, /* stop remote xmit */ - NULL, /* start remote xmit */ - FALSE /* output uses interrupts */ -}; - - -/* - * SECTION 0 - * MISCELLANEOUS ROUTINES - */ - -/**************************************************************************** - * Func: SCI_output_char - * Desc: used by rtems printk function to send a char to the uart - * Inputs: the character to transmit - * Outputs: none - * Errors: none - * Scope: public - ****************************************************************************/ - -void SCI_output_char(char c) -{ -/* ( minor device number, pointer to the character, length ) */ - - SciPolledWrite( SCI_MINOR, &c, 1); - - return; -} - - -/**************************************************************************** -* Func: SciGetTermiosHandlers -* Desc: returns a pointer to the table of serial io functions -* this is called from console_open with polled set to false -* Inputs: flag indicating whether we want polled or interrupt driven io -* Outputs: pointer to function table -* Errors: none -* Scope: public -****************************************************************************/ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ) -{ - if ( polled ) - { - return &SciPolledCallbacks; /* polling based */ - } - else - { - return &SciInterruptCallbacks; /* interrupt driven */ - } -} - - -/**************************************************************************** -* Func: SciIsr -* Desc: interrupt handler for serial communications interface -* Inputs: vector number - unused -* Outputs: none -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_isr SciIsr( rtems_vector_number vector ) -{ - uint8_t ch; - - if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++; - if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++; - if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++; - if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++; - - /* see if it was a transmit interrupt */ - /* data reg empty, xmt complete */ - if ( ( *SCCR1 & SCI_ENABLE_INT_TX ) && ( (*SCSR) & SCI_XMTR_AVAILABLE ) ) - { - SciDisableTransmitInterrupts(); - - /* tell termios module that the charcter was sent */ - /* he will call us later to transmit more if there are any */ - - if (rtems_termios_dequeue_characters( SciTermioTty, 1 )) - { - /* there are more bytes to transmit so enable TX interrupt */ - - SciEnableTransmitInterrupts(); - } - } - - /* see if it was a receive interrupt */ - /* on the sci uart we just get one character per interrupt */ - - while ( SciCharAvailable() ) /* char in data register? */ - { - ch = SciReadCharNoWait(); /* get the char from the uart */ - - /* IMPORTANT!!! */ - /* either send it to the termios module or keep it locally */ - - if ( SciOpened == DRIVER_OPENED ) /* the driver is open */ - { - SciRcvBufPutChar(ch); /* keep it locally */ - } - else /* put in termios buffer */ - { - char c = (char) ch; - rtems_termios_enqueue_raw_characters( SciTermioTty, &c, 1 ); - } - - *SCSR &= SCI_CLEAR_RX_INT; /* clear the interrupt */ - } -} - - -/* - * SECTION 1 - * ROUTINES TO MANIPULATE THE CIRCULAR BUFFER - */ - -/**************************************************************************** -* Func: SciRcvBufGetChar -* Desc: read a character from the circular buffer -* make sure there is data before you call this! -* Inputs: none -* Outputs: the character or -1 -* Errors: none -* Scope: private -****************************************************************************/ - -static int8_t SciRcvBufGetChar(void) -{ - rtems_interrupt_level level; - uint8_t ch; - - if ( SciRcvBufCount == 0 ) - { - rtems_fatal_error_occurred(0xDEAD); /* check the count first! */ - } - - rtems_interrupt_disable( level ); /* disable interrupts */ - - ch = SciRcvBuffer[SciRcvBufGetIndex]; /* get next byte */ - - SciRcvBufGetIndex++; /* bump the index */ - - SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ - - SciRcvBufCount--; /* decrement counter */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return ch; /* return the char */ -} - - -/**************************************************************************** -* Func: SciRcvBufPutChar -* Desc: put a character into the rcv data circular buffer -* Inputs: the character -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciRcvBufPutChar( uint8_t ch ) -{ - rtems_interrupt_level level; - - if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) /* is there room? */ - { - return; /* no, throw it away */ - } - - rtems_interrupt_disable( level ); /* disable interrupts */ - - SciRcvBuffer[SciRcvBufPutIndex] = ch; /* put it in the buf */ - - SciRcvBufPutIndex++; /* bump the index */ - - SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ - - SciRcvBufCount++; /* increment counter */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return; /* return */ -} - - -/**************************************************************************** -* Func: SciRcvBufFlush -* Desc: completely reset and clear the rcv buffer -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -#if 0 /* prevents compiler warning */ -static void SciRcvBufFlush( void ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable( level ); /* disable interrupts */ - - memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) ); - - SciRcvBufPutIndex = 0; /* clear */ - - SciRcvBufGetIndex = 0; /* clear */ - - SciRcvBufCount = 0; /* clear */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return; /* return */ -} -#endif - - -/* - * - * SECTION 2 - * INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE - */ - -/**************************************************************************** -* Func: SciInterruptOpen -* Desc: open routine for the interrupt based device driver -* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ?? -**CHANGED** Default baud rate is now 19200, 8N1 -* called from rtems_termios_open which is called from console_open -* Inputs: major - device number -* minor - device number -* args - points to terminal info -* Outputs: success/fail -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciInterruptOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t * args = arg; - rtems_isr_entry old_vector; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( !args ) /* must have args */ - { - return -1; - } - - SciTermioTty = args->iop->data1; /* save address of struct */ - - SciDisableAllInterrupts(); /* turn off sci interrupts */ - - /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ - /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ - -/* SciSetBaud(115200); set the baud rate */ -/* SciSetBaud( 57600); set the baud rate */ -/* SciSetBaud( 38400); set the baud rate */ -/* SciSetBaud( 19200); set the baud rate */ - SciSetBaud( 9600); /* set the baud rate */ - - SciSetParity(SCI_PARITY_NONE); /* set parity to none */ - - SciSetDataBits(SCI_8_DATA_BITS); /* set data bits to 8 */ - - /* Install our interrupt handler into RTEMS. */ - /* 68 is an unused user-defined vector. Note that the vector must be */ - /* even - it sets the low bit for SPI interrupts, and clears it for */ - /* SCI interrupts. Also note that vector 66 is used by CPU32bug on */ - /* the mrm332. */ - - rtems_interrupt_catch( SciIsr, 68, &old_vector ); - - *QSMCR = (*QSMCR & ~IARB) | 1; // Is 1 a good value for qsm iarb? - *QIVR = 68; - *QILR &= 0xf8; - *QILR |= 0x06 & 0x07; - - SciEnableTransmitter(); /* enable the transmitter */ - - SciEnableReceiver(); /* enable the receiver */ - - SciEnableReceiveInterrupts(); /* enable rcv interrupts */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciInterruptClose -* Desc: close routine called by the termios module -* Inputs: major - device number -* minor - device number -* args - unused -* Outputs: success/fail -* Errors: none -* Scope: public - termio entry point -****************************************************************************/ - -int SciInterruptClose( - int major, - int minor, - void *arg -) -{ - SciDisableAllInterrupts(); - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciInterruptWrite -* Desc: writes data to the uart using transmit interrupts -* Inputs: minor - device number -* buf - points to the data -* len - number of bytes to send -* Outputs: success/fail -* Errors: none -* Scope: public API -****************************************************************************/ - -ssize_t SciInterruptWrite( - int minor, - const char *buf, - size_t len -) -{ - /* We are using interrupt driven output so termios only sends us */ - /* one character at a time. The sci does not have a fifo. */ - - if ( !len ) /* no data? */ - { - return -1; /* return error */ - } - - if ( minor != SCI_MINOR ) /* check the minor dev num */ - { - return -1; /* return error */ - } - - if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ - { - return -1; /* yep, throw this away */ - } - - SciWriteCharNoWait(*buf); /* try to send a char */ - - *SCSR &= SCI_CLEAR_TDRE; /* clear tx data reg empty flag */ - - SciEnableTransmitInterrupts(); /* enable the tx interrupt */ - - return 0; /* return success */ -} - - -/**************************************************************************** -* Func: SciSetAttributes -* Desc: setup the uart based on the termios modules requests -* Inputs: minor - device number -* t - pointer to the termios info struct -* Outputs: none -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciSetAttributes( - int minor, - const struct termios *t -) -{ - uint32_t baud_requested; - uint32_t sci_rate = 0; - uint16_t sci_parity = 0; - uint16_t sci_databits = 0; - - if ( minor != SCI_MINOR ) /* check the minor dev num */ - { - return -1; /* return error */ - } - - /* if you look closely you will see this is the only thing we use */ - /* set the baud rate */ - - baud_requested = t->c_ospeed; /* baud rate */ - - if (!baud_requested) - { - baud_requested = B9600; /* default to 9600 baud */ - /* baud_requested = B19200; default to 19200 baud */ - } - - sci_rate = rtems_termios_baud_to_number( baud_requested ); - - /* parity error detection */ - - if (t->c_cflag & PARENB) /* enable parity detection? */ - { - if (t->c_cflag & PARODD) - { - sci_parity = SCI_PARITY_ODD; /* select odd parity */ - } - else - { - sci_parity = SCI_PARITY_EVEN; /* select even parity */ - } - } - else - { - sci_parity = SCI_PARITY_NONE; /* no parity, most common */ - } - - /* set the number of data bits, 8 is most common */ - - if (t->c_cflag & CSIZE) /* was it specified? */ - { - switch (t->c_cflag & CSIZE) - { - case CS8: sci_databits = SCI_8_DATA_BITS; break; - default : sci_databits = SCI_9_DATA_BITS; break; - } - } - else - { - sci_databits = SCI_8_DATA_BITS; /* default to 8 data bits */ - } - - /* the number of stop bits; always 1 for SCI */ - - if (t->c_cflag & CSTOPB) - { - /* do nothing */ - } - - /* setup the hardware with these serial port parameters */ - - SciSetBaud(sci_rate); /* set the baud rate */ - SciSetParity(sci_parity); /* set the parity type */ - SciSetDataBits(sci_databits); /* set the data bits */ - - return RTEMS_SUCCESSFUL; -} - - -/* - * - * SECTION 3 - * POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE - */ - -/**************************************************************************** -* Func: SciPolledOpen -* Desc: open routine for the polled i/o version of the driver -* called from rtems_termios_open which is called from console_open -* Inputs: major - device number -* minor - device number -* args - points to terminal info struct -* Outputs: success/fail -* Errors: none -* Scope: public - termios entry point -****************************************************************************/ - -int SciPolledOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t * args = arg; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( !args ) /* must have args */ - { - return -1; - } - - SciTermioTty = args->iop->data1; /* Store tty pointer */ - - SciDisableAllInterrupts(); /* don't generate interrupts */ - - /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ - /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ - -/* SciSetBaud(115200); set the baud rate */ -/* SciSetBaud( 57600); set the baud rate */ -/* SciSetBaud( 38400); set the baud rate */ -/* SciSetBaud( 19200); * set the baud rate */ - SciSetBaud( 9600); /* set the baud rate */ - - SciSetParity(SCI_PARITY_NONE); /* set no parity */ - - SciSetDataBits(SCI_8_DATA_BITS); /* set 8 data bits */ - - SciEnableTransmitter(); /* enable the xmitter */ - - SciEnableReceiver(); /* enable the rcvr */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciPolledClose -* Desc: close routine for the device driver, same for both -* Inputs: major - device number -* minor - device number -* args - unused -* Outputs: success/fail -* Errors: none -* Scope: public termios API -****************************************************************************/ - -int SciPolledClose( - int major, - int minor, - void *arg -) -{ - SciDisableAllInterrupts(); - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciPolledRead -* Desc: polling based read routine for the uart -* Inputs: minor - device number -* Outputs: error or the character read -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciPolledRead( - int minor -) -{ - if ( minor != SCI_MINOR ) /* check the type-punned dev num */ - { - return -1; /* return error */ - } - - if ( SciCharAvailable() ) /* if a char is available */ - { - return SciReadCharNoWait(); /* read the rx data register */ - } - - return -1; /* return error */ -} - - -/**************************************************************************** -* Func: SciPolledWrite -* Desc: writes out characters in polled mode, waiting for the uart -* check in console_open, but we only seem to use interrupt mode -* Inputs: minor - device number -* buf - points to the data -* len - how many bytes -* Outputs: error or number of bytes written -* Errors: none -* Scope: public termios API -****************************************************************************/ - -ssize_t SciPolledWrite( - int minor, - const char *buf, - size_t len -) -{ - ssize_t written = 0; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ - { - return -1; /* toss the data */ - } - - /* send each byte in the string out the port */ - - while ( written < len ) - { - SciWriteCharWait(*buf++); /* send a byte */ - - written++; /* increment counter */ - } - - return written; /* return count */ -} - - -/* - * - * SECTION 4 - * DEVICE DRIVER PUBLIC API ENTRY POINTS - */ - -/**************************************************************************** -* Func: SciInit -* Desc: Initialize the lasers device driver and hardware -* Inputs: major - the major device number which is assigned by rtems -* minor - the minor device number which is undefined at this point -* arg - ????? -* Outputs: RTEMS_SUCCESSFUL -* Errors: None. -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciInitialize ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/* rtems_status_code status; */ - -/*printk("%s\r\n", __FUNCTION__); */ - - /* register the SCI device name for termios console i/o - * this is done over in console.c which doesn't seem exactly right - * but there were problems doing it here... - */ - -/* status = rtems_io_register_name( "/dev/sci", major, 0 ); */ - -/* if (status != RTEMS_SUCCESSFUL) */ -/* rtems_fatal_error_occurred(status); */ - - SciMajor = major; /* save the rtems major number */ - - SciOpened = DRIVER_CLOSED; /* initial state is closed */ - - /* if you have an interrupt handler, install it here */ - - SciInited = 1; /* set the inited flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciOpen -* Desc: device driver open routine -* you must open a device before you can anything else -* only one process can have the device opened at a time -* you could look at the task id to restrict access if you want -* Inputs: major - the major device number assigned by rtems -* minor - the minor device number assigned by us -* arg - ????? -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciOpen ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - if (SciInited == 0) /* must be initialized first! */ - { - return RTEMS_NOT_CONFIGURED; - } - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* verify minor number */ - } - - if (SciOpened == DRIVER_OPENED) - { - return RTEMS_RESOURCE_IN_USE; /* already opened! */ - } - - SciOpened = DRIVER_OPENED; /* set the opened flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciClose -* Desc: device driver close routine -* the device must be opened before you can close it -* the device must be closed before someone (else) can open it -* Inputs: major - the major device number -* minor - the minor device number -* arg - ????? -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciClose ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened != DRIVER_OPENED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - SciOpened = DRIVER_CLOSED; /* set the flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciRead -* Desc: device driver read routine -* this function is not meaningful for the laser devices -* Inputs: major - the major device number -* minor - the minor device number -* arg - read/write arguments -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciRead ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; /* arguments to read() */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - buffer = rw_args->buffer; /* points to user's buffer */ - -/* *buffer = SciReadCharWait(); wait for a character */ - - /* if there isn't a character available, wait until one shows up */ - /* or the timeout period expires, which ever happens first */ - - if ( SciRcvBufCount == 0 ) /* no chars */ - { - /* wait for someone to wake me up... */ - /*rtems_task_wake_after(SciReadTimeout); */ - } - - if ( SciRcvBufCount ) /* any characters locally? */ - { - *buffer = SciRcvBufGetChar(); /* get the character */ - - rw_args->bytes_moved = 1; /* how many we actually read */ - } - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciWrite -* Desc: device driver write routine -* this function is not meaningful for the laser devices -* Inputs: major - the major device number -* minor - the minor device number -* arg - read/write arguments -* Outputs: see below -* Errors: non3 -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciWrite ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ - uint8_t *buffer; - size_t length; - - rw_args = (rtems_libio_rw_args_t *) arg; - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - buffer = (uint8_t*)rw_args->buffer; /* points to data */ - - length = rw_args->count; /* how many bytes */ - - while (length--) - { - SciWriteCharWait(*buffer++); /* send the bytes out */ - } - - rw_args->bytes_moved = rw_args->count; /* how many we wrote */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciControl -* Desc: device driver control routine -* see below for an example of how to use the ioctl interface -* Inputs: major - the major device number -* minor - the minor device number -* arg - io control args -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciControl ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_ioctl_args_t *args = arg; /* rtems arg struct */ - uint16_t command; /* the cmd to execute */ - -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - /* do some sanity checking */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be open first */ - } - - if (args == 0) - { - return RTEMS_INVALID_ADDRESS; /* must have args */ - } - - args->ioctl_return = -1; /* assume an error */ - - command = args->command; /* get the command */ - - if (command == SCI_SEND_BREAK) /* process the command */ - { - SciSendBreak(); /* send break char */ - } - - args->ioctl_return = 0; /* return status */ - - return RTEMS_SUCCESSFUL; -} - - -/* - * - * SECTION 5 - * HARDWARE LEVEL ROUTINES - */ - -/**************************************************************************** -* Func: SciSetBaud -* Desc: setup the uart based on the termios modules requests -* Inputs: baud rate -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetBaud(uint32_t rate) -{ - uint16_t value; - uint16_t save_sccr1; - -/* when you open the console you need to set the termio struct baud rate */ -/* it has a default value of 9600, when someone calls tcsetattr it reverts! */ - - SciBaud = rate; /* save the rate */ - - /* calculate the register value as a float and convert to an int */ - /* set baud rate - you must define the system clock constant */ - /* see mrm332.h for an example */ - - value = ( (uint16_t) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff ); - - save_sccr1 = *SCCR1; /* save register */ - - /* also turns off the xmtr and rcvr */ - - *SCCR1 &= SCI_DISABLE_INT_ALL; /* disable interrupts */ - - *SCCR0 = value; /* write the register */ - - *SCCR1 = save_sccr1; /* restore register */ - - return; -} - - -/**************************************************************************** -* Func: SciSetParity -* Desc: setup the uart based on the termios modules requests -* Inputs: parity -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetParity(uint16_t parity) -{ - uint16_t value; - - value = *SCCR1; /* get the register */ - - if (parity == SCI_PARITY_ODD) - { - value |= SCI_PARITY_ENABLE; /* parity enabled */ - value |= SCI_PARITY_ODD; /* parity odd */ - } - - else if (parity == SCI_PARITY_EVEN) - { - value |= SCI_PARITY_ENABLE; /* parity enabled */ - value &= ~SCI_PARITY_ODD; /* parity even */ - } - - else if (parity == SCI_PARITY_NONE) - { - value &= ~SCI_PARITY_ENABLE; /* disabled, most common */ - } - - /* else no changes */ - - *SCCR1 = value; /* write the register */ - - return; -} - - -/**************************************************************************** -* Func: SciSetDataBits -* Desc: setup the uart based on the termios modules requests -* Inputs: data bits -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetDataBits(uint16_t bits) -{ - uint16_t value; - - value = *SCCR1; /* get the register */ - - /* note - the parity setting affects the number of data bits */ - - if (bits == SCI_9_DATA_BITS) - { - value |= SCI_9_DATA_BITS; /* 9 data bits */ - } - - else if (bits == SCI_8_DATA_BITS) - { - value &= SCI_8_DATA_BITS; /* 8 data bits */ - } - - /* else no changes */ - - *SCCR1 = value; /* write the register */ - - return; -} - - -/**************************************************************************** -* Func: SciDisableAllInterrupts -* Func: SciEnableTransmitInterrupts -* Func: SciEnableReceiveInterrupts -* Desc: handles generation of interrupts by the sci module -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void inline SciDisableAllInterrupts( void ) -{ - /* this also turns off the xmtr and rcvr */ - - *SCCR1 &= SCI_DISABLE_INT_ALL; -} - -static void inline SciEnableReceiveInterrupts( void ) -{ - *SCCR1 |= SCI_ENABLE_INT_RX; -} - -static void inline SciDisableReceiveInterrupts( void ) -{ - *SCCR1 &= SCI_DISABLE_INT_RX; -} - -static void inline SciEnableTransmitInterrupts( void ) -{ - *SCCR1 |= SCI_ENABLE_INT_TX; -} - -static void inline SciDisableTransmitInterrupts( void ) -{ - *SCCR1 &= SCI_DISABLE_INT_TX; -} - - -/**************************************************************************** -* Func: SciEnableTransmitter, SciDisableTransmitter -* Func: SciEnableReceiver, SciDisableReceiver -* Desc: turns the transmitter and receiver on and off -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void inline SciEnableTransmitter( void ) -{ - *SCCR1 |= SCI_ENABLE_XMTR; -} - -static void inline SciDisableTransmitter( void ) -{ - *SCCR1 &= SCI_DISABLE_XMTR; -} - -static void inline SciEnableReceiver( void ) -{ - *SCCR1 |= SCI_ENABLE_RCVR; -} - -static void inline SciDisableReceiver( void ) -{ - *SCCR1 &= SCI_DISABLE_RCVR; -} - - -/**************************************************************************** -* Func: SciWriteCharWait -* Desc: wait for room in the fifo and then put a char in -* Inputs: a byte to send -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciWriteCharWait(uint8_t c) -{ - /* poll the fifo, waiting for room for another character */ - - while ( ( *SCSR & SCI_XMTR_AVAILABLE ) != SCI_XMTR_AVAILABLE ) - { - /* Either we are writing to the fifo faster than - * the uart can clock bytes out onto the cable, - * or we are in flow control (actually no, we - * are ignoring flow control from the other end). - * In the first case, higher baud rates will help. - */ - /* relinquish processor while waiting */ - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } - - *SCDR = c; /* send the charcter */ - - SciBytesOut++; /* increment the counter */ - - return; -} - -/**************************************************************************** -* Func: SciWriteCharNoWait -* Desc: if no room in the fifo throw the char on the floor -* Inputs: a byte to send -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciWriteCharNoWait(uint8_t c) -{ - if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) - { - return; /* no room, throw it away */ - } - - *SCDR = c; /* put the char in the fifo */ - - SciBytesOut++; /* increment the counter */ - - return; -} - - -/**************************************************************************** -* Func: SciReadCharWait -* Desc: read a character, waiting for one to show up, if need be -* Inputs: none -* Outputs: a character -* Errors: none -* Scope: public -****************************************************************************/ - -static uint8_t inline SciReadCharWait( void ) -{ - uint8_t ch; - - while ( SciCharAvailable() == 0 ) /* anything there? */ - { - /* relinquish processor while waiting */ - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } - - /* if you have rcv ints enabled, then the isr will probably */ - /* get the character before you will unless you turn off ints */ - /* ie polling and ints don't mix that well */ - - ch = *SCDR; /* get the charcter */ - - SciBytesIn++; /* increment the counter */ - - return ch; /* return the char */ -} - -/**************************************************************************** -* Func: SciReadCharNoWait -* Desc: try to get a char but dont wait for one -* Inputs: none -* Outputs: a character or -1 if none -* Errors: none -* Scope: public -****************************************************************************/ - -static uint8_t inline SciReadCharNoWait( void ) -{ - uint8_t ch; - - if ( SciCharAvailable() == 0 ) /* anything there? */ - return -1; - - ch = *SCDR; /* get the character */ - - SciBytesIn++; /* increment the count */ - - return ch; /* return the char */ -} - - -/**************************************************************************** -* Func: SciCharAvailable -* Desc: is there a receive character in the data register -* Inputs: none -* Outputs: false if no char available, else true -* Errors: none -* Scope: public -****************************************************************************/ - -uint8_t inline SciCharAvailable( void ) -{ - return ( *SCSR & SCI_RCVR_READY ); /* char in data register? */ -} - - -/**************************************************************************** -* Func: SciSendBreak -* Desc: send 1 or tow breaks (all zero bits) -* Inputs: none -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciSendBreak( void ) -{ - /* From the Motorola QSM reference manual - */ - - /* "if SBK is toggled by writing it first to a one and then immediately */ - /* to a zero (in less than one serial frame interval), the transmitter */ - /* sends only one or two break frames before reverting to mark (idle) */ - /* or before commencing to send more data" */ - - *SCCR1 |= SCI_SEND_BREAK; /* set the bit */ - - *SCCR1 &= ~SCI_SEND_BREAK; /* clear the bit */ - - return; -} - - -/* - * - * SECTION 6 - * TEST CODE - */ - -/**************************************************************************** -* Func: SciUnitTest -* Desc: test the device driver -* Inputs: nothing -* Outputs: nothing -* Scope: public -****************************************************************************/ - -#if 0 -void SciUnitTest() -{ - uint8_t byte; /* a character */ - uint16_t fd; /* file descriptor for device */ - uint16_t result; /* result of ioctl */ - - fd = open("/dev/sci",O_RDWR); /* open the device */ - -printk("SCI open fd=%d\r\n",fd); - - result = write(fd, "abcd\r\n", 6); /* send a string */ - -printk("SCI write result=%d\r\n",result); - - result = read(fd, &byte, 1); /* read a byte */ - -printk("SCI read result=%d,byte=%x\r\n",result,byte); - - return; -} -#endif - - -/**************************************************************************** -* Func: SciPrintStats -* Desc: print out some driver information -* Inputs: nothing -* Outputs: nothing -* Scope: public -****************************************************************************/ - -void SciPrintStats ( void ) -{ - printk("\r\n"); - - printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 ); - - printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 ); - - printk( "SCI Uart chars in %8" PRIu32 "\r\n", SciBytesIn ); - printk( "SCI Uart chars out %8" PRIu32 "\r\n", SciBytesOut ); - printk( "SCI Uart framing errors %8" PRIu32 "\r\n", SciErrorsFraming ); - printk( "SCI Uart parity errors %8" PRIu32 "\r\n", SciErrorsParity ); - printk( "SCI Uart overrun errors %8" PRIu32 "\r\n", SciErrorsOverrun ); - printk( "SCI Uart noise errors %8" PRIu32 "\r\n", SciErrorsNoise ); - - return; -} diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.h b/c/src/lib/libbsp/m68k/mrm332/console/sci.h deleted file mode 100644 index 93893ecbfc..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/sci.h +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -* File: sci.h -* -* Desc: This is the include file for the serial communications interface. -* -* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. -* -****************************************************************************/ - -#ifndef _sci_h_ -#define _sci_h_ - -/******************************************************************************* - IOCTL commands for the sci driver. - I'm still working on these... -*******************************************************************************/ - -#define SCI_IOCTL_PARITY_NONE 0x00 /* no parity bit after the data bits */ -#define SCI_IOCTL_PARITY_ODD 0x01 /* parity bit added after data bits */ -#define SCI_IOCTL_PARITY_EVEN 0x02 /* parity bit added after data bits */ -#define SCI_IOCTL_PARITY_MARK 0x03 /* parity bit is lo, -12 volts, logical 1 */ -#define SCI_IOCTL_PARITY_SPACE 0x04 /* parity bit is hi, +12 volts, logical 0 */ -#define SCI_IOCTL_PARITY_FORCED_ON 0x03 /* parity bit is forced hi or lo */ -#define SCI_IOCTL_PARITY_FORCED_OFF 0x04 /* parity bit is forced hi or lo */ - -#define SCI_IOCTL_BAUD_RATE 0x20 /* set the baud rate, arg is baud */ - -#define SCI_IOCTL_DATA_BITS 0x30 /* set the data bits, arg is # bits */ - -#define SCI_IOCTL_STOP_BITS_1 0x40 /* 1 stop bit after char frame */ -#define SCI_IOCTL_STOP_BITS_2 0x41 /* 2 stop bit after char frame */ - -#define SCI_IOCTL_MODE_NORMAL 0x50 /* normal operating mode */ -#define SCI_IOCTL_MODE_LOOP 0x51 /* internal loopback mode */ - -#define SCI_IOCTL_FLOW_NONE 0x60 /* no flow control */ -#define SCI_IOCTL_FLOW_RTS_CTS 0x61 /* hardware flow control */ - -#define SCI_IOCTL_SEND_BREAK 0x70 /* send an rs-232 break */ - -#define SCI_IOCTL_MODE_1200 0x80 /* 1200,n,8,1 download mode */ -#define SCI_IOCTL_MODE_9600 0x81 /* 9600,n,8,1 download mode */ -#define SCI_IOCTL_MODE_9_BIT 0x82 /* 9600,forced,8,1 command mode */ - - -/******************************************************************************* - SCI Registers -*******************************************************************************/ - -/* SCI Control Register 0 (SCCR0) $FFFC08 - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 baud rate divisor - | | | | | | | | | | | | | | +------- 1 baud rate divisor - | | | | | | | | | | | | | +--------- 2 baud rate divisor - | | | | | | | | | | | | +----------- 3 baud rate divisor - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 baud rate divisor - | | | | | | | | | | +----------------- 5 baud rate divisor - | | | | | | | | | +------------------- 6 baud rate divisor - | | | | | | | | +--------------------- 7 baud rate divisor - | | | | | | | | - | | | | | | | +------------------------- 8 baud rate divisor - | | | | | | +--------------------------- 9 baud rate divisor - | | | | | +----------------------------- 10 baud rate divisor - | | | | +------------------------------- 11 baud rate divisor - | | | | - | | | +----------------------------------- 12 baud rate divisor - | | +------------------------------------- 13 unused - | +--------------------------------------- 14 unused - +----------------------------------------- 15 unused - - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 1 0 0 reset value - (64k baud?) - */ - -#define SCI_BAUD_57_6K 9 -#define SCI_BAUD_38_4K 14 -#define SCI_BAUD_19_2K 27 -#define SCI_BAUD_9600 55 -#define SCI_BAUD_4800 109 -#define SCI_BAUD_2400 218 -#define SCI_BAUD_1200 437 - - -/* SCI Control Register 1 (SCCR1) $FFFC0A - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 send a break - | | | | | | | | | | | | | | +------- 1 rcvr wakeup mode - | | | | | | | | | | | | | +--------- 2 rcvr enable - | | | | | | | | | | | | +----------- 3 xmtr enable - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 idle line intr enable - | | | | | | | | | | +----------------- 5 rcvr intr enable - | | | | | | | | | +------------------- 6 xmit complete intr enable - | | | | | | | | +--------------------- 7 xmtr intr enable - | | | | | | | | - | | | | | | | +------------------------- 8 wakeup on address mark - | | | | | | +--------------------------- 9 mode 1=9 bits, 0=8 bits - | | | | | +----------------------------- 10 parity enable 1=on, 0=off - | | | | +------------------------------- 11 parity type 1=odd, 0=even - | | | | - | | | +----------------------------------- 12 idle line select - | | +------------------------------------- 13 wired-or mode - | +--------------------------------------- 14 loop mode - +----------------------------------------- 15 unused - - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 reset value -*/ - -#define SCI_SEND_BREAK 0x0001 /* 0000-0000-0000-0001 */ -#define SCI_RCVR_WAKEUP 0x0002 /* 0000-0000-0000-0010 */ -#define SCI_ENABLE_RCVR 0x0004 /* 0000-0000-0000-0100 */ -#define SCI_ENABLE_XMTR 0x0008 /* 0000-0000-0000-1000 */ - -#define SCI_DISABLE_RCVR 0xFFFB /* 1111-1111-1111-1011 */ -#define SCI_DISABLE_XMTR 0xFFF7 /* 1111-1111-1111-0111 */ - -#define SCI_ENABLE_INT_IDLE 0x0010 /* 0000-0000-0001-0000 */ -#define SCI_ENABLE_INT_RX 0x0020 /* 0000-0000-0010-0000 */ -#define SCI_ENABLE_INT_TX_DONE 0x0040 /* 0000-0000-0100-0000 */ -#define SCI_ENABLE_INT_TX 0x0080 /* 0000-0000-1000-0000 */ - -#define SCI_DISABLE_INT_ALL 0xFF00 /* 1111-1111-0000-0000 ??? */ - -#define SCI_DISABLE_INT_RX 0xFFDF /* 1111-1111-1101-1111 */ -#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ -#define SCI_DISABLE_INT_TX 0xFF7F /* 1111-1111-0111-1111 */ -#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ - -#define SCI_RCVR_WAKE_ON_MARK 0x0100 /* 0000-0001-0000-0000 */ -#define SCI_9_DATA_BITS 0x0200 /* 0000-0010-0000-0000 */ -#define SCI_PARITY_ENABLE 0x0400 /* 0000-0100-0000-0000 */ -#define SCI_PARITY_ODD 0x0800 /* 0000-1000-0000-0000 */ - -#define SCI_RCVR_WAKE_ON_IDLE 0xFEFF /* 1111-1110-1111-1111 */ -#define SCI_8_DATA_BITS 0xFDFF /* 1111-1101-1111-1111 */ -#define SCI_PARITY_DISABLE 0xFBFF /* 1111-1011-1111-1111 */ -#define SCI_PARITY_EVEN 0xF7FF /* 1111-0111-1111-1111 */ - -#define SCI_PARITY_NONE 0xF3FF /* 1111-0011-1111-1111 */ - -#define SCI_IDLE_LINE_LONG 0x1000 /* 0001-0000-0000-0000 */ -#define SCI_TXD_OPEN_DRAIN 0x2000 /* 0010-0000-0000-0000 */ -#define SCI_LOOPBACK_MODE 0x4000 /* 0100-0000-0000-0000 */ -#define SCI_SCCR1_UNUSED 0x8000 /* 1000-0000-0000-0000 */ - - -/* SCI Status Register (SCSR) $FFFC0C - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 PF - parity error - | | | | | | | | | | | | | | +------- 1 FE - framing error - | | | | | | | | | | | | | +--------- 2 NF - noise flag - | | | | | | | | | | | | +----------- 3 OR - overrun flag - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 IDLE - idle line detected - | | | | | | | | | | +----------------- 5 RAF - rcvr active flag - | | | | | | | | | +------------------- 6 RDRF - rcv data reg full - | | | | | | | | +--------------------- 7 TC - xmt complete flag - | | | | | | | | - | | | | | | | +------------------------- 8 TDRE - xmt data reg empty - | | | | | | +--------------------------- 9 always zero - | | | | | +----------------------------- 10 always zero - | | | | +------------------------------- 11 always zero - | | | | - | | | +----------------------------------- 12 always zero - | | +------------------------------------- 13 always zero - | +--------------------------------------- 14 always zero - +----------------------------------------- 15 always zero - - 0 0 0 0 - 0 0 0 1 - 1 0 0 0 - 0 0 0 0 reset value -*/ - -#define SCI_ERROR_PARITY 0x0001 /* 0000-0000-0000-0001 */ -#define SCI_ERROR_FRAMING 0x0002 /* 0000-0000-0000-0010 */ -#define SCI_ERROR_NOISE 0x0004 /* 0000-0000-0000-0100 */ -#define SCI_ERROR_OVERRUN 0x0008 /* 0000-0000-0000-1000 */ - -#define SCI_IDLE_LINE 0x0010 /* 0000-0000-0001-0000 */ -#define SCI_RCVR_ACTIVE 0x0020 /* 0000-0000-0010-0000 */ -#define SCI_RCVR_READY 0x0040 /* 0000-0000-0100-0000 */ -#define SCI_XMTR_IDLE 0x0080 /* 0000-0000-1000-0000 */ - -#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ - -#define SCI_XMTR_READY 0x0100 /* 0000-0001-0000-0000 */ - -#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ - -#define SCI_XMTR_AVAILABLE 0x0180 /* 0000-0001-1000-0000 */ - - - -/******************************************************************************* - Function prototypes -*******************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* look at console_open to see how this is called */ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); - -/* SCI interrupt */ - -/*rtems_isr SciIsr( rtems_vector_number vector ); */ - -/*int32_t SciOpenPolled ( int32_t major, int32_t minor, void *arg ); */ -/*int32_t SciOpenInterrupt ( int32_t major, int32_t minor, void *arg ); */ - -/*int32_t SciClose ( int32_t major, int32_t minor, void *arg ); */ - -/*int32_t SciWritePolled ( int32_t minor, const char *buf, int32_t len ); */ -/*int32_t SciWriteInterrupt( int32_t minor, const char *buf, int32_t len ); */ - -/*int32_t SciReadPolled ( int32_t minor ); */ - -/*int32_t SciSetAttributes ( int32_t minor, const struct termios *t ); */ - -#ifdef __cplusplus -} -#endif - -#endif /* _sci_h_ */ diff --git a/c/src/lib/libbsp/m68k/mvme147/Makefile.am b/c/src/lib/libbsp/m68k/mvme147/Makefile.am index d8397be9a4..846c77e37c 100644 --- a/c/src/lib/libbsp/m68k/mvme147/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme147/Makefile.am @@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme147/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme147/console/console.c b/c/src/lib/libbsp/m68k/mvme147/console/console.c deleted file mode 100644 index f26ca6485a..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147/console/console.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * This file contains the MVME147 console IO package. - */ - -/* - * COPYRIGHT (c) 1989-1999. - * 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. - * - * MVME147 port for TNI - Telecom Bretagne - * by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr) - * May 1996 - * - * This file was taken from the DMV152 bsp - */ - -#define M147_INIT - -#include -#include -#include -#include -#include - -/* console_initialize - * - * This routine initializes the console IO driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SCC. - */ -static char inbyte( void ) -{ - uint8_t rr_0; - char ch; - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 ) - break; - } - - Z8x30_READ_DATA( CONSOLE_DATA, ch ); - return ( ch ); -} - -/* outbyte - * - * This routine transmits a character out the SCC. It supports - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - uint8_t rr_0; - char flow_control; - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 ) - break; - } - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ) - break; - - Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); - - if ( flow_control == XOFF ) - do { - do { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - } while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ); - Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); - } while ( flow_control != XON ); - } - - Z8x30_WRITE_DATA( CONSOLE_DATA, ch ); -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am index d6994289b8..f985e5454a 100644 --- a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am @@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147/clock/ckinit.c # console librtemsbsp_a_SOURCES += ../mvme147/console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += ../mvme147/timer/timer.c librtemsbsp_a_SOURCES += ../mvme147/timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme162/Makefile.am b/c/src/lib/libbsp/m68k/mvme162/Makefile.am index 8af4d1d415..72313a9473 100644 --- a/c/src/lib/libbsp/m68k/mvme162/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme162/Makefile.am @@ -31,7 +31,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme162/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme162/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme162/console/console.c b/c/src/lib/libbsp/m68k/mvme162/console/console.c deleted file mode 100644 index 985254d483..0000000000 --- a/c/src/lib/libbsp/m68k/mvme162/console/console.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * This file contains the MVME162 console IO package. - */ - -/* - * COPYRIGHT (c) 1989-2013. - * 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. - * - * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. - * EISCAT Scientific Association. M.Savitski - * - * This material is a part of the MVME162 Board Support Package - * for the RTEMS executive. Its licensing policies are those of the - * RTEMS above. - */ - -#define M162_INIT - -#include -#include -#include -#include -#include - -Ring_buffer_t Console_Buffer[2]; - -/* - * Interrupt handler for receiver interrupts - */ -static rtems_isr C_Receive_ISR(rtems_vector_number vector) -{ - register int ipend, port; - - ZWRITE0(1, 0x38); /* reset highest IUS */ - - ipend = ZREAD(1, 3); /* read int pending from A side */ - - if (ipend == 0x04) port = 0; /* channel B intr pending */ - else if (ipend == 0x20) port = 1; /* channel A intr pending */ - else return; - - Ring_buffer_Add_character(&Console_Buffer[port], ZREADD(port)); - - if (ZREAD(port, 1) & 0x70) { /* check error stat */ - ZWRITE0(port, 0x30); /* reset error */ - } -} - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - int i; - rtems_status_code status; - - /* - * Initialise receiver interrupts on both ports - */ - for (i = 0; i <= 1; i++) { - Ring_buffer_Initialize( &Console_Buffer[i] ); - ZWRITE(i, 2, SCC_VECTOR); - ZWRITE(i, 10, 0); - ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */ - ZWRITE(i, 9, 8); /* master interrupt enable */ - } - - set_vector(C_Receive_ISR, SCC_VECTOR, 1); /* install ISR for ports A and B */ - - mcchip->vector_base = 0; - mcchip->gen_control = 2; /* MIEN */ - mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */ - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 1 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_io_register_name( - "/dev/tty00", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_io_register_name( - "/dev/tty01", - major, - (rtems_device_minor_number) 1 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* - * Non-blocking char input - */ -bool char_ready(int port, char *ch) -{ - if ( Ring_buffer_Is_empty( &Console_Buffer[port] ) ) - return false; - - Ring_buffer_Remove_character( &Console_Buffer[port], *ch ); - - return true; -} - -/* - * Block on char input - */ -static char inbyte(int port) -{ - char tmp_char; - - while ( !char_ready(port, &tmp_char) ); - return tmp_char; -} - -/* - * This routine transmits a character out the SCC. It no longer supports - * XON/XOFF flow control. - */ -static void outbyte(char ch, int port) -{ - while (1) { - if (ZREAD0(port) & TX_BUFFER_EMPTY) break; - } - ZWRITED(port, ch); -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - if ( minor > 1 ) - return RTEMS_INVALID_NUMBER; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte( minor ); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - if ( minor > 1 ) - return RTEMS_INVALID_NUMBER; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r', minor ); - } - outbyte( buffer[ count ], minor ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * _162Bug_output_char - * - * Output a single character using the 162Bug functions. The character - * will be written to the default output port. - */ -static void _162Bug_output_char( char c ) -{ - asm volatile( "moveb %0, -(%%sp)\n\t" /* char to output */ - "trap #15\n\t" /* Trap to 162Bug */ - ".short 0x20" /* Code for .OUTCHR */ - :: "d" (c) ); -} - -/* - * _BSP_output_char - * - * printk() function prototyped in bspIo.h. Does not use termios. - * - * If we have initialized the console device then use it, otherwise - * use the 162Bug routines to send it to the default output port. - */ -static void _BSP_output_char(char c) -{ - _162Bug_output_char(c); -} - -/* Printk function */ -BSP_output_char_function_type BSP_output_char = _BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/m68k/mvme167/Makefile.am b/c/src/lib/libbsp/m68k/mvme167/Makefile.am index 1632a35b8b..ac80bf6014 100644 --- a/c/src/lib/libbsp/m68k/mvme167/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme167/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme167/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h b/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h deleted file mode 100644 index 4d8d3fc66c..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2000, National Research Council of Canada - * - * 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. - */ - -/* CD2401 CONSOLE DRIVER DEBUG INFO RECORDING */ - -#ifdef CD2401_RECORD_DEBUG_INFO - -/* Control individual recording here. That way, we don't clutter console.c */ -#define CD2401_RECORD_WRITE -#define CD2401_RECORD_TX_ISR -#define CD2401_RECORD_RX_ISR -#define CD2401_RECORD_RE_ISR -#define CD2401_RECORD_MODEM_ISR -#define CD2401_RECORD_SET_ATTRIBUTE -#define CD2401_RECORD_FIRST_OPEN -#define CD2401_RECORD_LAST_CLOSE -#define CD2401_RECORD_START_REMOTE_TX -#define CD2401_RECORD_STOP_REMOTE_TX -#define CD2401_RECORD_DRAIN_OUTPUT -#define CD2401_RECORD_DELAY - -/* Call the data recording functions */ -#ifdef CD2401_RECORD_WRITE -#define CD2401_RECORD_WRITE_INFO( args ) cd2401_record_write_info args -#else -#define CD2401_RECORD_WRITE_INFO( args ) -#endif - -#ifdef CD2401_RECORD_TX_ISR -#define CD2401_RECORD_TX_ISR_INFO( args ) cd2401_record_tx_isr_info args -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) cd2401_record_tx_isr_spurious_info args -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) cd2401_record_tx_isr_buserr_info args -#else -#define CD2401_RECORD_TX_ISR_INFO( args ) -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) -#endif - -#ifdef CD2401_RECORD_RX_ISR -#define CD2401_RECORD_RX_ISR_INFO( args ) cd2401_record_rx_isr_info args -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) cd2401_record_rx_isr_spurious_info args -#else -#define CD2401_RECORD_RX_ISR_INFO( args ) -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_RE_ISR -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) cd2401_record_re_isr_spurious_info args -#else -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_MODEM_ISR -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) cd2401_record_modem_isr_spurious_info args -#else -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_SET_ATTRIBUTES -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) cd2401_record_set_attributes_info args -#else -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) -#endif - -#ifdef CD2401_RECORD_FIRST_OPEN -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) cd2401_record_first_open_info args -#else -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) -#endif - -#ifdef CD2401_RECORD_LAST_CLOSE -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) cd2401_record_last_close_info args -#else -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) -#endif - -#ifdef CD2401_RECORD_START_REMOTE_TX -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) cd2401_record_start_remote_tx_info args -#else -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) -#endif - -#ifdef CD2401_RECORD_STOP_REMOTE_TX -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) cd2401_record_stop_remote_tx_info args -#else -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) -#endif - -#ifdef CD2401_RECORD_DRAIN_OUTPUT -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) cd2401_record_drain_output_info args -#else -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) -#endif - -#ifdef CD2401_RECORD_DELAY -#define CD2401_RECORD_DELAY_INFO( args ) cd2401_record_delay_info args -#else -#define CD2401_RECORD_DELAY_INFO( args ) -#endif - -/* Define the data and the recording functions */ -#define CD2401_DEBUG_BUFFER_SIZE 256 -#define CD2401_DEBUG_CHAR_BUFSIZE 64 -#define CD2401_WRITE_INFO 1 -#define CD2401_TX_ISR_INFO 2 -#define CD2401_TX_ISR_SPURIOUS_INFO 3 -#define CD2401_TX_ISR_BUSERR_INFO 4 -#define CD2401_RX_ISR_INFO 5 -#define CD2401_RX_ISR_SPURIOUS_INFO 6 -#define CD2401_RE_ISR_SPURIOUS_INFO 7 -#define CD2401_MODEM_ISR_SPURIOUS_INFO 8 -#define CD2401_FIRST_OPEN_INFO 9 -#define CD2401_LAST_CLOSE_INFO 10 -#define CD2401_START_REMOTE_TX_INFO 11 -#define CD2401_STOP_REMOTE_TX_INFO 12 -#define CD2401_SET_ATTRIBUTE_INFO 13 -#define CD2401_DRAIN_OUTPUT_INFO 14 -#define CD2401_DELAY_INFO 15 - -struct cd2401_debug_info { - short discriminant; - short record_size; - union { - struct cd2401_write_info { - int length; - char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; - char dmabuf; - } write_info; - struct cd2401_tx_isr_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char final_ier; - uint8_t txEmpty; - } tx_isr_info; - struct cd2401_tx_isr_spurious_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char final_ier; - unsigned long spurdev; - unsigned long spurcount; - } tx_isr_spurious_info; - struct cd2401_tx_isr_buserr_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char buserr; - unsigned long type; - unsigned long addr; - } tx_isr_buserr_info; - struct cd2401_rx_isr_info { - unsigned char channel; - int length; - char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; - } rx_isr_info; - struct cd2401_rx_isr_spurious_info { - unsigned char channel; - unsigned char status; - unsigned long spurdev; - unsigned long spurcount; - } rx_isr_spurious_info; - struct cd2401_re_isr_spurious_info { - unsigned char channel; - unsigned long spurdev; - unsigned long spurcount; - } re_isr_spurious_info; - struct cd2401_modem_isr_spurious_info { - unsigned char channel; - unsigned long spurdev; - unsigned long spurcount; - } modem_isr_spurious_info; - struct cd2401_first_open_info { - unsigned char channel; - uint8_t init_count; - } first_open_info; - struct cd2401_last_close_info { - unsigned char channel; - uint8_t init_count; - } last_close_info; - struct cd2401_start_remote_tx_info { - unsigned char channel; - } start_remote_tx_info; - struct cd2401_stop_remote_tx_info { - unsigned char channel; - } stop_remote_tx_info; - struct cd2401_set_attribute_info { - int minor; - uint8_t need_reinit; - uint8_t txEmpty; - uint8_t csize; - uint8_t cstopb; - uint8_t parodd; - uint8_t parenb; - uint8_t ignpar; - uint8_t inpck; - uint8_t hw_flow_ctl; - uint8_t sw_flow_ctl; - uint8_t extra_flow_ctl; - uint8_t icrnl; - uint8_t igncr; - uint8_t inlcr; - uint8_t brkint; - uint8_t ignbrk; - uint8_t parmrk; - uint8_t istrip; - uint16_t tx_period; - uint16_t rx_period; - uint32_t out_baud; - uint32_t in_baud; - } set_attribute_info; - struct cd2401_drain_output_info { - uint8_t txEmpty; - uint8_t own_buf_A; - uint8_t own_buf_B; - } drain_output_info; - struct cd2401_delay_info { - rtems_interval start; - rtems_interval end; - rtems_interval current; - unsigned long loop_count; - } delay_info; - } u; -}; - -struct cd2401_debug_info cd2401_debug_buffer[CD2401_DEBUG_BUFFER_SIZE]; -int cd2401_debug_index = 0; - -#include - -int cd2401_get_record_size( - int size -) -{ - /* Not the best way to do this */ - return size + 4; -} - -void cd2401_record_write_info( - int len, - const char * buf, - char dmabuf -) -{ - int max_length; - - max_length = (len < CD2401_DEBUG_CHAR_BUFSIZE ) ? len : CD2401_DEBUG_CHAR_BUFSIZE; - - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_WRITE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_write_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.write_info.length = len; - memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.write_info.buffer), buf, max_length ); - cd2401_debug_buffer[cd2401_debug_index].u.write_info.dmabuf = dmabuf; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char final_ier, - uint8_t txEmpty -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.final_ier = final_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.txEmpty = txEmpty; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_spurious_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char final_ier, - unsigned char spur_dev, - unsigned char spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.final_ier = final_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_buserr_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char buserr, - unsigned long buserr_type, - unsigned long buserr_addr -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_BUSERR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_buserr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.buserr = buserr; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.type = buserr_type; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.addr = buserr_addr; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_rx_isr_info( - unsigned char ch, - unsigned char total, - char * buffer -) -{ - int max_length; - - max_length = (total < CD2401_DEBUG_CHAR_BUFSIZE ) ? total : CD2401_DEBUG_CHAR_BUFSIZE; - - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_rx_isr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.length = max_length; - memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.buffer), buffer, max_length ); - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_rx_isr_spurious_info( - unsigned char ch, - unsigned char status, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_rx_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_re_isr_spurious_info( - unsigned char ch, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RE_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_re_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_modem_isr_spurious_info( - unsigned char ch, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_MODEM_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_modem_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_first_open_info( - unsigned char ch, - uint8_t init_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_FIRST_OPEN_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_first_open_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.init_count = init_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_last_close_info( - unsigned char ch, - uint8_t init_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_LAST_CLOSE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_last_close_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.init_count = init_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_start_remote_tx_info( - unsigned char ch -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_START_REMOTE_TX_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_start_remote_tx_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.start_remote_tx_info.channel = ch; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_stop_remote_tx_info( - unsigned char ch -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_STOP_REMOTE_TX_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_stop_remote_tx_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.stop_remote_tx_info.channel = ch; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_set_attributes_info( - int minor, - uint8_t need_reinit, - uint8_t csize, - uint8_t cstopb, - uint8_t parodd, - uint8_t parenb, - uint8_t ignpar, - uint8_t inpck, - uint8_t hw_flow_ctl, - uint8_t sw_flow_ctl, - uint8_t extra_flow_ctl, - uint8_t icrnl, - uint8_t igncr, - uint8_t inlcr, - uint8_t brkint, - uint8_t ignbrk, - uint8_t parmrk, - uint8_t istrip, - uint16_t tx_period, - uint16_t rx_period, - uint32_t out_baud, - uint32_t in_baud -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_SET_ATTRIBUTE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_set_attribute_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.minor = minor; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.need_reinit = need_reinit; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.txEmpty = CD2401_Channel_Info[minor].txEmpty; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.csize = csize; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.cstopb = cstopb; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parodd = parodd; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parenb = parenb; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignpar = ignpar; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inpck = inpck; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.hw_flow_ctl = hw_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.sw_flow_ctl = sw_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.extra_flow_ctl = extra_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.icrnl = icrnl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.igncr = igncr; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inlcr = inlcr; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.brkint = brkint; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignbrk = ignbrk; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parmrk = parmrk; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.istrip = istrip; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.tx_period = tx_period; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.rx_period = rx_period; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.out_baud = out_baud; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.in_baud = in_baud; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_drain_output_info( - uint8_t txEmpty, - uint8_t own_buf_A, - uint8_t own_buf_B -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DRAIN_OUTPUT_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_drain_output_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.txEmpty = txEmpty; - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_A = own_buf_A; - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_B = own_buf_B; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_delay_info( - rtems_interval start, - rtems_interval end, - rtems_interval current, - unsigned long loop_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DELAY_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_delay_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.start = start; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.end = end; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.current = current; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.loop_count = loop_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -#else - -/* Do not call the data recording functions */ -#define CD2401_RECORD_WRITE_INFO( args ) -#define CD2401_RECORD_TX_ISR_INFO( args ) -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) -#define CD2401_RECORD_RX_ISR_INFO( args ) -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) -#define CD2401_RECORD_DELAY_INFO( args ) - -#endif diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console.c b/c/src/lib/libbsp/m68k/mvme167/console/console.c deleted file mode 100644 index 0499ac46b3..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/console/console.c +++ /dev/null @@ -1,1676 +0,0 @@ -/* - * This file contains the MVME167 termios console package. Only asynchronous - * I/O is supported. - * - * /dev/tty0 is channel 0, Serial Port 1/Console on the MVME712M. - * /dev/tty1 is channel 1, Serial Port 2/TTY01 on the MVME712M. - * /dev/tty2 is channel 2, Serial Port 3 on the MVME712M. - * /dev/tty3 is channel 3, Serial Port 4 on the MVME712M. - * - * Normal I/O uses DMA for output, interrupts for input. /dev/console is - * fixed to be /dev/tty01, Serial Port 2. Very limited support is provided - * for polled I/O. Polled I/O is intended only for running the RTEMS test - * suites. In all cases, Serial Port 1/Console is allocated to 167Bug and - * is the dedicated debugger port. We configure GDB to use 167Bug for - * debugging. When debugging with GDB or 167Bug, do not open /dev/tty00. - * - * Modern I/O chips often contain a number of I/O devices that can operate - * almost independently of each other. Typically, in RTEMS, all devices in - * an I/O chip are handled by a single device driver, but that need not be - * always the case. Each device driver must supply six entry points in the - * Device Driver Table: a device initialization function, as well as an open, - * close, read, write and a control function. RTEMS assigns a device major - * number to each device driver. This major device number is the index of the - * device driver entries in the Device Driver Table, and it used to identify - * a particular device driver. To distinguish multiple I/O sub-devices within - * an I/O chip, RTEMS supports device minor numbers. When a I/O device is - * initialized, the major number is supplied to the initialization function. - * That function must register each sub-device with a separate name and minor - * number (as well as the supplied major number). When an application opens a - * device by name, the corresponding major and minor numbers are returned to - * the caller to be used in subsequent I/O operations (although these details - * are typically hidden within the library functions). - * - * Such a scheme recognizes that the initialization of the individual - * sub-devices is generally not completely independent. For example, the - * four serial ports of the CD2401 can be configured almost independently - * from each other. One port could be configured to operate in asynchronous - * mode with interrupt-driven I/O, while another port could be configured to - * operate in HDLC mode with DMA I/O. However, a device reset command will - * reset all four channels, and the width of DMA transfers and the number of - * retries following bus errors selected applies to all four channels. - * Consequently, when initializing one channel, one must be careful not to - * destroy the configuration of other channels that are already configured. - * - * One problem with the RTEMS I/O initialization model is that no information - * other than a device major number is passed to the initialization function. - * Consequently, the sub-devices must be initialized with some pre-determined - * configuration. To change the configuration of a sub-device, it is - * necessary to either rewrite the initialization function, or to make a - * series of rtems_io_control() calls after initialization. The first - * approach is not very elegant. The second approach is acceptable if an - * application is simply changing baud rates, parity or other such - * asynchronous parameters (as supplied by the termios package). But what if - * an application requires one channel to run in HDLC or Bisync mode and - * another in async mode? With a single driver per I/O chip approach, the - * device driver must support multiple protocols. This is feasible, but it - * often means that an application that only does asynchronous I/O now links - * in code for other unused protocols, thus wasting precious ROM space. - * Worse, it requires that the sub-devices be initialized in some - * configuration, and that configuration then changed through a series of - * device driver control calls. There is no standard API in RTEMS to switch - * a serial line to some synchronous protocol. - * - * A better approach is to treat each channel as a separate device, each with - * its own device device driver. The application then supplies its own device - * driver table with only the required protocols (drivers) on each line. The - * problem with this approach is that the device drivers are not really - * independent, given that the I/O sub-devices within a common chip are not - * independent themselves. Consequently, the related device drivers must - * share some information. In RTEMS, there is no standard location in which - * to share information. - * - * This driver handles all four channels, i.e. it distinguishes the - * sub-devices using minor device numbers. Only asynchronous I/O is - * supported. The console is currently fixed to be channel 1 on the CD2401, - * which corresponds to the TTY01 port (Serial Port 2) on the MVME712M - * Transition Module. - * - * The CD2401 does either interrupt-driven or DMA I/O; it does not support - * polling. In interrupt-driven or DMA I/O modes, interrupts from the CD2401 - * are routed to the MC68040, and the processor generates an interrupt - * acknowledge cycle directly to the CD2401 to obtain an interrupt vector. - * The PCCchip2 supports a pseudo-polling mode in which interrupts from the - * CD2401 are not routed to the MC68040, but can be detected by the processor - * by reading the appropriate CD2401 registers. In this mode, interrupt - * acknowledge cycles must be generated to the CD2401 by reading the - * appropriate PCCchip2 registers. - * - * Interrupts from the four channels cannot be routed independently; either - * all channels are used in the pseudo-polling mode, or all channels are used - * in interrupt-driven/DMA mode. There is no advantage in using the speudo- - * polling mode. Consenquently, this driver performs DMA input and output. - * Output is performed directly from the termios raw output buffer, while - * input is accumulated into a separate buffer. - * - * THIS MODULE IS NOT RE-ENTRANT! Simultaneous access to a device from - * multiple tasks is likely to cause significant problems! Concurrency - * control is implemented in the termios package. - * - * THE INTERRUPT LEVEL IS SET TO 1 FOR ALL CHANNELS. - * If the CD2401 is to be used for high speed synchronous serial I/O, the - * interrupt priority might need to be increased. - * - * ALL INTERRUPT HANDLERS ARE SHARED. - * When adding extra device drivers, either rewrite the interrupt handlers - * to demultiplex the interrupts, or install separate vectors. Common vectors - * are currently used to catch spurious interrupts. We could already have - * installed separate vectors for each channel and used the spurious - * interrupt handler defined in some other BSPs, but handling spurious - * interrupts from the CD2401 in this device driver allows us to record more - * information on the source of the interrupts. Furthermore, we have observed - * the occasional spurious interrupt from channel 0. We definitely do not - * to call a debugger for those. - * - * All page references are to the MVME166/MVME167/MVME187 Single Board - * Computer Programmer's Reference Guide (MVME187PG/D2) with the April - * 1993 supplements/addenda (MVME187PG/D2A1). - */ - -/* - * Copyright (c) 1998, National Research Council of Canada - * - * 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. - */ - -#define M167_INIT - -#include -#include -#include - -#include -#include -#include -#include /* Must be before libio.h */ - -/* Utility functions */ -void cd2401_udelay( unsigned long delay ); -void cd2401_chan_cmd( uint8_t channel, uint8_t cmd, uint8_t wait ); -uint16_t cd2401_bitrate_divisor( uint32_t clkrate, uint32_t * bitrate ); -void cd2401_initialize( void ); -void cd2401_interrupts_initialize( bool enable ); - -/* ISRs */ -rtems_isr cd2401_modem_isr( rtems_vector_number vector ); -rtems_isr cd2401_re_isr( rtems_vector_number vector ); -rtems_isr cd2401_rx_isr( rtems_vector_number vector ); -rtems_isr cd2401_tx_isr( rtems_vector_number vector ); - -/* Termios callbacks */ -int cd2401_firstOpen( int major, int minor, void *arg ); -int cd2401_lastClose( int major, int minor, void *arg ); -int cd2401_setAttributes( int minor, const struct termios *t ); -int cd2401_startRemoteTx( int minor ); -int cd2401_stopRemoteTx( int minor ); -ssize_t cd2401_write( int minor, const char *buf, size_t len ); -int cd2401_drainOutput( int minor ); -int _167Bug_pollRead( int minor ); -ssize_t _167Bug_pollWrite( int minor, const char *buf, size_t len ); - -/* Printk function */ -static void _BSP_output_char( char c ); -BSP_output_char_function_type BSP_output_char = _BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -/* '\r' character in memory. This used to live on - * the stack but storing the '\r' character is - * optimized away by gcc-4.3.2 (since it seems to - * be unused [only referenced from inline assembly - * code in _167Bug_pollWrite()]). - * Hence we make it a global constant. - */ -static const char cr_char = '\r'; - -/* Channel info */ -/* static */ volatile struct { - void *tty; /* Really a struct rtems_termios_tty * */ - int len; /* Record nb of chars being TX'ed */ - const char *buf; /* Record where DMA is coming from */ - uint32_t spur_cnt; /* Nb of spurious ints so far */ - uint32_t spur_dev; /* Indo on last spurious int */ - uint32_t buserr_addr; /* Faulting address */ - uint32_t buserr_type; /* Reason of bus error during DMA */ - uint8_t own_buf_A; /* If true, buffer A belongs to the driver */ - uint8_t own_buf_B; /* If true, buffer B belongs to the driver */ - uint8_t txEmpty; /* If true, the output FIFO should be empty */ -} CD2401_Channel_Info[4]; - -/* - * The number of channels already opened. If zero, enable the interrupts. The - * initial value must be 0. If initialized explicitly, the variable ends up - * in the .data section. Its value is not re-initialized on system restart. - * Furthermore, because the variable is changed, the .data section would not - * be ROMable. We thus leave the variable uninitialized, which causes it to - * be allocated in the .bss section, and rely on RTEMS to zero the .bss - * section on every startup. - */ -uint8_t Init_count; - -/* Record previous handlers */ -rtems_isr_entry Prev_re_isr; /* Previous rx exception isr */ -rtems_isr_entry Prev_rx_isr; /* Previous rx isr */ -rtems_isr_entry Prev_tx_isr; /* Previous tx isr */ -rtems_isr_entry Prev_modem_isr; /* Previous modem/timer isr */ - -/* Define the following symbol to trace the calls to this driver */ -/* #define CD2401_RECORD_DEBUG_INFO */ -#include "console-recording.h" - -/* - * Utility functions. - */ - -/* - * Assumes that clock ticks 1 million times per second. - * - * MAXIMUM DELAY IS ABOUT 20 ms - * - * Input parameters: - * delay: Number of microseconds to delay. - * - * Output parameters: NONE - * - * Return values: NONE - */ - void cd2401_udelay -( - unsigned long delay -) -{ - unsigned long i = 20000; /* In case clock is off */ - rtems_interval start_ticks, end_ticks, current_ticks; - - start_ticks = rtems_clock_get_ticks_since_boot(); - end_ticks = start_ticks + delay; - - do { - current_ticks = rtems_clock_get_ticks_since_boot(); - } while ( --i && (current_ticks <= end_ticks) ); - - CD2401_RECORD_DELAY_INFO(( start_ticks, end_ticks, current_ticks, i )); -} - -/* - * cd2401_chan_cmd - * - * Sends a CCR command to the specified channel. Waits for any unfinished - * previous command to complete, then sends the specified command. Optionally - * wait for the current command to finish before returning. - * - * Input parameters: - * channel - CD2401 channel number - * cmd - command byte - * wait - if non-zero, wait for specified command to complete before - * returning. - * - * Output parameters: NONE - * - * Return values: NONE - */ -void cd2401_chan_cmd( - uint8_t channel, - uint8_t cmd, - uint8_t wait -) -{ - if ( channel < 4 ) { - cd2401->car = channel; /* Select channel */ - - while ( cd2401->ccr != 0 ); /* Wait for completion of previous command */ - cd2401->ccr = cmd; /* Send command */ - if ( wait ) - while( cd2401->ccr != 0 );/* Wait for completion */ - } - else { - /* This may not be the best error message */ - rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); - } -} - -/* - * cd2401_bitrate_divisor - * - * Compute the divisor and clock source to use to obtain the desired bitrate. - * - * Input parameters: - * clkrate - system clock rate (CLK input frequency) - * bitrate - the desired bitrate - * - * Output parameters: - * bitrate - The actual bitrate achievable, to the nearest bps. - * - * Return values: - * Returns divisor in lower byte and clock source in upper byte for the - * specified bitrate. - */ -uint16_t cd2401_bitrate_divisor( - uint32_t clkrate, - uint32_t * bitrate -) -{ - uint32_t divisor; - uint16_t clksource; - - divisor = *bitrate << 3; /* temporary; multiply by 8 for CLK/8 */ - divisor = (clkrate + (divisor>>1)) / divisor; /* divisor for clk0 (CLK/8) */ - - /* Use highest speed clock source for best precision - try clk0 to clk4 */ - for( clksource = 0; clksource < 0x0400 && divisor > 0x100; clksource += 0x0100 ) - divisor >>= 2; - divisor--; /* adjustment, see specs */ - if( divisor < 1 ) - divisor = 1; - else if( divisor > 0xFF ) - divisor = 0xFF; - *bitrate = clkrate / (1 << ((clksource >> 7)+3)) / (divisor+1); - return( clksource | divisor ); -} - -/* - * cd2401_initialize - * - * Initializes the CD2401 device. Individual channels on the chip are left in - * their default reset state, and should be subsequently configured. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: NONE - */ -void cd2401_initialize( void ) -{ - int i; - - for ( i = 3; i >= 0; i-- ) { - CD2401_Channel_Info[i].tty = NULL; - CD2401_Channel_Info[i].len = 0; - CD2401_Channel_Info[i].buf = NULL; - CD2401_Channel_Info[i].spur_cnt = 0; - CD2401_Channel_Info[i].spur_dev = 0; - CD2401_Channel_Info[i].buserr_type = 0; - CD2401_Channel_Info[i].buserr_addr = 0; - CD2401_Channel_Info[i].own_buf_A = TRUE; - CD2401_Channel_Info[i].own_buf_B = TRUE; - CD2401_Channel_Info[i].txEmpty = TRUE; - } - - /* - * Normally, do a device reset here. If we do it, we will most likely clober - * the port settings for 167Bug on channel 0. So we just shut up all the - * ports by disabling their interrupts. - */ -#if 0 - cd2401->gfrcr = 0; /* So we can detect that device init is done */ - cd2401_chan_cmd( 0x10, 0); /* Reset all */ - while(cd2401->gfrcr == 0); /* Wait for reset all */ -#endif - - /* - * The CL-CD2400/2401 manual (part no 542400-003) states on page 87 that - * the LICR "contains the number of the interrupting channel being served. - * The channel number is always that of the current acknowledged interrupt." - * THE USER MUST PROGRAM CHANNEL NUMBER IN LICR! It is not set automatically - * by the hardware, as suggested by the manual. - * - * The updated manual (part no 542400-007) has the story straight. The - * CD2401 automatically initializes the LICR to contain the channel number - * in bits 2 and 3. However, these bits are not preserved when the user - * defined bits are written. - * - * The same vector number is used for all four channels. Different vector - * numbers could be programmed for each channel, thus avoiding the need to - * demultiplex the interrupts in the ISR. - */ - for ( i = 0; i < 4; i++ ) { - cd2401->car = i; /* Select channel */ - cd2401->livr = 0x5C; /* Motorola suggested value p. 3-15 */ - cd2401->licr = i << 2; /* Don't rely on reset value */ - cd2401->ier = 0; /* Disable all interrupts */ - } - - /* - * The content of the CD2401 xpilr registers must match the A7-A0 addresses - * generated by the PCCchip2 during interrupt acknowledge cycles in order - * for the CD2401 to recognize the IACK cycle and clear its interrupt - * request. - */ - cd2401->mpilr = 0x01; /* Match pccchip2->modem_piack p. 3-27 */ - cd2401->tpilr = 0x02; /* Match pccchip2->tx_piack p. 3-28 */ - cd2401->rpilr = 0x03; /* Match pccchip2->rx_piack p. 3-29 */ - - /* Global CD2401 registers */ - cd2401->dmr = 0; /* 16-bit DMA transfers when possible */ - cd2401->bercnt = 0; /* Do not retry DMA upon bus errors */ - - /* - * Setup timer prescaler period, which clocks timers 1 and 2 (or rx timeout - * and tx delay). The prescaler is clocked by the system clock) / 2048. The - * register must be in the range 0x0A..0xFF, ie. a rescaler period range of - * about 1ms..26ms for a nominal system clock rate of 20MHz. - */ - cd2401->tpr = 0x0A; /* Same value as 167Bug */ -} - -/* - * cd2401_interrupts_initialize - * - * This routine enables or disables the CD2401 interrupts to the MC68040. - * Interrupts cannot be enabled/disabled on a per-channel basis. - * - * Input parameters: - * enable - if true, enable the interrupts, else disable them. - * - * Output parameters: NONE - * - * Return values: NONE - * - * THE FIRST CD2401 CHANNEL OPENED SHOULD ENABLE INTERRUPTS. - * THE LAST CD2401 CHANNEL CLOSED SHOULD DISABLE INTERRUPTS. - */ -void cd2401_interrupts_initialize( - bool enable -) -{ - if ( enable ) { - /* - * Enable interrupts from the CD2401 in the PCCchip2. - * During DMA transfers, the MC68040 supplies dirty data during read cycles - * from the CD2401 and leaves the data dirty in its data cache if there is - * a cache hit. The MC68040 updates the data cache during write cycles from - * the CD2401 if there is a cache hit. - */ - pccchip2->SCC_error = 0x01; - pccchip2->SCC_modem_int_ctl = 0x10 | CD2401_INT_LEVEL; - pccchip2->SCC_tx_int_ctl = 0x10 | CD2401_INT_LEVEL; - pccchip2->SCC_rx_int_ctl = 0x50 | CD2401_INT_LEVEL; - - pccchip2->gen_control |= 0x02; /* Enable pccchip2 interrupts */ - } - else { - /* Disable interrupts */ - pccchip2->SCC_modem_int_ctl &= 0xEF; - pccchip2->SCC_tx_int_ctl &= 0xEF; - pccchip2->SCC_rx_int_ctl &= 0xEF; - } -} - -/* ISRs */ - -/* - * cd2401_modem_isr - * - * Modem/timer interrupt (group 1) from CD2401. These are not used, and not - * expected. Record as spurious and clear. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_modem_isr( - rtems_vector_number vector -) -{ - uint8_t ch; - - /* Get interrupting channel ID */ - ch = cd2401->licr >> 2; - - /* Record interrupt info for debugging */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->mir << 8) | cd2401->misr; - CD2401_Channel_Info[ch].spur_cnt++; - - cd2401->meoir = 0; /* EOI */ - CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); -} - -/* - * cd2401_re_isr - * - * RX exception interrupt (group 3, receiver exception) from CD2401. These are - * not used, and not expected. Record as spurious and clear. - * - * FIX THIS ISR TO DETECT BREAK CONDITIONS AND RAISE SIGINT - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_re_isr( - rtems_vector_number vector -) -{ - uint8_t ch; - - /* Get interrupting channel ID */ - ch = cd2401->licr >> 2; - - /* Record interrupt info for debugging */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; - CD2401_Channel_Info[ch].spur_cnt++; - - if ( cd2401->u5.b.risrl & 0x80 ) /* Timeout interrupt? */ - cd2401->ier &= 0xDF; /* Disable rx timeout interrupt */ - cd2401->reoir = 0x08; /* EOI; exception char not read */ - CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); -} - -/* - * cd2401_rx_isr - * - * RX interrupt (group 3, receiver data) from CD2401. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_rx_isr( - rtems_vector_number vector -) -{ - char c; - uint8_t ch, status, nchars, total; - #ifdef CD2401_RECORD_DEBUG_INFO - uint8_t i = 0; - char buffer[256]; - #endif - - (void) total; /* avoid set but not used warnings when not recording info */ - - status = cd2401->u5.b.risrl; - ch = cd2401->licr >> 2; - - /* Has this channel been initialized or is it a condition we ignore? */ - if ( CD2401_Channel_Info[ch].tty && !status ) { - /* Normal Rx Int, read chars, enqueue them, and issue EOI */ - total = nchars = cd2401->rfoc; /* Nb of chars to retrieve from rx FIFO */ - while ( nchars-- > 0 ) { - c = (char)cd2401->dr; /* Next char in rx FIFO */ - rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 ); - #ifdef CD2401_RECORD_DEBUG_INFO - buffer[i++] = c; - #endif - } - cd2401->reoir = 0; /* EOI */ - CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer )); - } else { - /* No, record as spurious interrupt */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; - CD2401_Channel_Info[ch].spur_cnt++; - cd2401->reoir = 0x04; /* EOI - character not read */ - CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - } -} - -/* - * cd2401_tx_isr - * - * TX interrupt (group 2) from CD2401. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_tx_isr( - rtems_vector_number vector -) -{ - uint8_t ch, status, buserr, initial_ier, final_ier; - - status = cd2401->tisr; - ch = cd2401->licr >> 2; - initial_ier = cd2401->ier; - - #ifndef CD2401_RECORD_DEBUG_INFO - /* - * When the debug is disabled, these variables are really not read. - * But when debug is enabled, they are. - */ - (void) initial_ier; /* avoid set but not used warning */ - (void) final_ier; /* avoid set but not used warning */ - #endif - - /* Has this channel been initialized? */ - if ( !CD2401_Channel_Info[ch].tty ) { - /* No, record as spurious interrupt */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].spur_cnt++; - final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */ - - cd2401->teoir = 0x88; /* EOI - Terminate buffer and no transfer */ - CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - return; - } - - if ( status & 0x80 ) { - /* - * Bus error occurred during DMA transfer. For now, just record. - * Get reason for DMA bus error and clear the report for the next - * occurrence - */ - buserr = pccchip2->SCC_error; - pccchip2->SCC_error = 0x01; - CD2401_Channel_Info[ch].buserr_type = - (vector << 24) | (buserr << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].buserr_addr = - (((uint32_t)cd2401->tcbadru) << 16) | cd2401->tcbadrl; - - cd2401->teoir = 0x80; /* EOI - terminate bad buffer */ - CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr, - CD2401_Channel_Info[ch].buserr_type, - CD2401_Channel_Info[ch].buserr_addr )); - return; - } - - if ( status & 0x20 ) { - /* DMA done -- Turn off TxD int, turn on TxMpty */ - final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02; - if( status & 0x08 ) { - /* Transmit buffer B was released */ - CD2401_Channel_Info[ch].own_buf_B = TRUE; - } - else { - /* Transmit buffer A was released */ - CD2401_Channel_Info[ch].own_buf_A = TRUE; - } - CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].txEmpty )); - - /* This call can result in a call to cd2401_write() */ - rtems_termios_dequeue_characters ( - CD2401_Channel_Info[ch].tty, - CD2401_Channel_Info[ch].len ); - cd2401->teoir = 0x08; /* EOI - no data transfered */ - } - else if ( status & 0x02 ) { - /* TxEmpty */ - CD2401_Channel_Info[ch].txEmpty = TRUE; - final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */ - cd2401->teoir = 0x08; /* EOI - no data transfered */ - CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].txEmpty )); - } - else { - /* Why did we get a Tx interrupt? */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].spur_cnt++; - cd2401->teoir = 0x08; /* EOI - no data transfered */ - CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - } -} - -/* - * termios callbacks - */ - -/* - * cd2401_firstOpen - * - * This is the first time that this minor device (channel) is opened. - * Complete the asynchronous initialization. - * - * Input parameters: - * major - device major number - * minor - channel number - * arg - pointer to a struct rtems_libio_open_close_args_t - * - * Output parameters: NONE - * - * Return value: IGNORED - */ -int cd2401_firstOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_libio_ioctl_args_t newarg; - struct termios termios; - rtems_status_code sc; - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - /* - * Set up the line with the specified parameters. The difficulty is that - * the line parameters are stored in the struct termios field of a - * struct rtems_termios_tty that is not defined in a public header file. - * Therefore, we do not have direct access to the termios passed in with - * arg. So we make a rtems_termios_ioctl() call to get a pointer to the - * termios structure. - * - * THIS KLUDGE MAY BREAK IN THE FUTURE! - * - * We could have made a tcgetattr() call if we had our fd. - */ - newarg.iop = args->iop; - newarg.command = TIOCGETA; - newarg.buffer = &termios; - sc = rtems_termios_ioctl (&newarg); - if (sc != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (sc); - - /* - * Turn off hardware flow control. It is a pain with 3-wire cables. - * The rtems_termios_ioctl() call below results in a call to - * cd2401_setAttributes to initialize the line. The caller will "wait" - * on the ttyMutex that it already owns; this is safe in RTEMS. - */ - termios.c_cflag |= CLOCAL; /* Ignore modem status lines */ - newarg.command = TIOCGETA; - sc = rtems_termios_ioctl (&newarg); - if (sc != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (sc); - - /* Mark that the channel as initialized */ - CD2401_Channel_Info[minor].tty = args->iop->data1; - - /* If the first of the four channels to open, set up the interrupts */ - if ( !Init_count++ ) { - /* Install the interrupt handlers */ - Prev_re_isr = (rtems_isr_entry) set_vector( cd2401_re_isr, 0x5C, 1 ); - Prev_modem_isr = (rtems_isr_entry) set_vector( cd2401_modem_isr, 0x5D, 1 ); - Prev_tx_isr = (rtems_isr_entry) set_vector( cd2401_tx_isr, 0x5E, 1 ); - Prev_rx_isr = (rtems_isr_entry) set_vector( cd2401_rx_isr, 0x5F, 1 ); - - cd2401_interrupts_initialize( TRUE ); - } - - CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_lastClose - * - * There are no more opened file descriptors to this device. Close it down. - * - * Input parameters: - * major - device major number - * minor - channel number - * arg - pointer to a struct rtems_libio_open_close_args_t - */ -int cd2401_lastClose( - int major, - int minor, - void *arg -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - /* Mark that the channel is no longer is use */ - CD2401_Channel_Info[minor].tty = NULL; - - /* If the last of the four channels to close, disable the interrupts */ - if ( !--Init_count ) { - cd2401_interrupts_initialize( FALSE ); - - /* De-install the interrupt handlers */ - set_vector( Prev_re_isr, 0x5C, 1 ); - set_vector( Prev_modem_isr, 0x5D, 1 ); - set_vector( Prev_tx_isr, 0x5E, 1 ); - set_vector( Prev_rx_isr, 0x5F, 1 ); - } - - CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count )); - - rtems_interrupt_enable (level); - - /* return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_setAttributes - * - * Set up the selected channel of the CD2401 chip for doing asynchronous - * I/O with DMA. - * - * The chip must already have been initialized by cd2401_initialize(). - * - * This code was written for clarity. The code space it occupies could be - * reduced. The code could also be compiled with aggressive optimization - * turned on. - * - * Input parameters: - * minor - the selected channel - * t - the termios parameters - * - * Output parameters: NONE - * - * Return value: IGNORED - */ -int cd2401_setAttributes( - int minor, - const struct termios *t -) -{ - uint8_t csize, cstopb, parodd, parenb, ignpar, inpck; - uint8_t hw_flow_ctl, sw_flow_ctl, extra_flow_ctl; - uint8_t icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip; - uint8_t need_reinitialization = FALSE; - uint8_t read_enabled; - uint16_t tx_period, rx_period; - uint32_t out_baud, in_baud; - rtems_interrupt_level level; - - /* Determine what the line parameters should be */ - - /* baud rates */ - out_baud = rtems_termios_baud_to_number(t->c_ospeed); - in_baud = rtems_termios_baud_to_number(t->c_ispeed); - - /* Number of bits per char */ - csize = 0x07; /* to avoid a warning */ - switch ( t->c_cflag & CSIZE ) { - case CS5: csize = 0x04; break; - case CS6: csize = 0x05; break; - case CS7: csize = 0x06; break; - case CS8: csize = 0x07; break; - } - - /* Parity */ - if ( t->c_cflag & PARODD ) - parodd = 0x80; /* Odd parity */ - else - parodd = 0; - - if ( t->c_cflag & PARENB ) - parenb = 0x40; /* Parity enabled on Tx and Rx */ - else - parenb = 0x00; /* No parity on Tx and Rx */ - - /* CD2401 IGNPAR and INPCK bits are inverted wrt POSIX standard? */ - if ( t->c_iflag & INPCK ) - ignpar = 0; /* Check parity on input */ - else - ignpar = 0x10; /* Do not check parity on input */ - if ( t->c_iflag & IGNPAR ) { - inpck = 0x03; /* Discard error character */ - parmrk = 0; - } else { - if ( t->c_iflag & PARMRK ) { - inpck = 0x01; /* Translate to 0xFF 0x00 */ - parmrk = 0x04; - } else { - inpck = 0x01; /* Translate to 0x00 */ - parmrk = 0; - } - } - - /* Stop bits */ - if ( t->c_cflag & CSTOPB ) - cstopb = 0x04; /* Two stop bits */ - else - cstopb = 0x02; /* One stop bit */ - - /* Modem flow control */ - if ( t->c_cflag & CLOCAL ) - hw_flow_ctl = 0x04; /* Always assert RTS before Tx */ - else - hw_flow_ctl = 0x07; /* Always assert RTS before Tx, - wait for CTS and DSR */ - - /* XON/XOFF Tx flow control */ - if ( t->c_iflag & IXON ) { - sw_flow_ctl = 0x40; /* Tx in-band flow ctl enabled, wait for XON */ - extra_flow_ctl = 0x30; /* Eat XON/XOFF, XON/XOFF in SCHR1, SCHR2 */ - } - else { - sw_flow_ctl = 0; /* Tx in-band flow ctl disabled */ - extra_flow_ctl = 0; /* Pass on XON/XOFF */ - } - - /* CL/LF translation */ - if ( t->c_iflag & ICRNL ) - icrnl = 0x40; /* Map CR to NL on input */ - else - icrnl = 0; /* Pass on CR */ - if ( t->c_iflag & INLCR ) - inlcr = 0x20; /* Map NL to CR on input */ - else - inlcr = 0; /* Pass on NL */ - if ( t->c_iflag & IGNCR ) - igncr = 0x80; /* CR discarded on input */ - else - igncr = 0; - - /* Break handling */ - if ( t->c_iflag & IGNBRK ) { - ignbrk = 0x10; /* Ignore break on input */ - brkint = 0x08; - } else { - if ( t->c_iflag & BRKINT ) { - ignbrk = 0; /* Generate SIGINT (interrupt ) */ - brkint = 0; - } else { - ignbrk = 0; /* Convert to 0x00 */ - brkint = 0x08; - } - } - - /* Stripping */ - if ( t->c_iflag & ISTRIP ) - istrip = 0x80; /* Strip to 7 bits */ - else - istrip = 0; /* Leave as 8 bits */ - - rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud ); - tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud ); - - /* - * If this is the first time that the line characteristics are set up, then - * the device must be re-initialized. - * Also check if we need to change anything. It is preferable to not touch - * the device if nothing changes. As soon as we touch it, it tends to - * glitch. If anything changes, we reprogram all registers. This is - * harmless. - */ - if ( ( CD2401_Channel_Info[minor].tty == 0 ) || - ( cd2401->cor1 != (parodd | parenb | ignpar | csize) ) || - ( cd2401->cor2 != (sw_flow_ctl | hw_flow_ctl) ) || - ( cd2401->cor3 != (extra_flow_ctl | cstopb) ) || - ( cd2401->cor6 != (igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck) ) || - ( cd2401->cor7 != istrip ) || - ( cd2401->u1.async.schr1 != t->c_cc[VSTART] ) || - ( cd2401->u1.async.schr2 != t->c_cc[VSTOP] ) || - ( cd2401->rbpr != (unsigned char)rx_period ) || - ( cd2401->rcor != (unsigned char)(rx_period >> 8) ) || - ( cd2401->tbpr != (unsigned char)tx_period ) || - ( cd2401->tcor != ( (tx_period >> 3) & 0xE0 ) ) ) - need_reinitialization = TRUE; - - /* Write to the ports */ - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - read_enabled = cd2401->csr & 0x80 ? TRUE : FALSE; - - if ( (t->c_cflag & CREAD ? TRUE : FALSE ) != read_enabled ) { - /* Read enable status is changing */ - need_reinitialization = TRUE; - } - - if ( need_reinitialization ) { - /* - * Could not find a way to test whether the CD2401 was done transmitting. - * The TxEmpty interrupt does not seem to indicate that the FIFO is empty - * in DMA mode. So, just wait a while for output to drain. May not be - * enough, but it will have to do (should be long enough for 1 char at - * 9600 bsp)... - */ - cd2401_udelay( 2000L ); - - /* Clear channel */ - cd2401_chan_cmd (minor, 0x40, 1); - - cd2401->car = minor; /* Select channel */ - cd2401->cmr = 0x42; /* Interrupt Rx, DMA Tx, async mode */ - cd2401->cor1 = parodd | parenb | ignpar | csize; - cd2401->cor2 = sw_flow_ctl | hw_flow_ctl; - cd2401->cor3 = extra_flow_ctl | cstopb; - cd2401->cor4 = 0x0A; /* No DSR/DCD/CTS detect; FIFO threshold of 10 */ - cd2401->cor5 = 0x0A; /* No DSR/DCD/CTS detect; DTR threshold of 10 */ - cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck; - cd2401->cor7 = istrip; /* No LNext; ignore XON/XOFF if frame error; no tx translations */ - /* Special char 1: XON character */ - cd2401->u1.async.schr1 = t->c_cc[VSTART]; - /* special char 2: XOFF character */ - cd2401->u1.async.schr2 = t->c_cc[VSTOP]; - - /* - * Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC - * are unused, left as is. - */ - - /* Set baudrates for receiver and transmitter */ - cd2401->rbpr = (unsigned char)rx_period; - cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */ - cd2401->tbpr = (unsigned char)tx_period; - cd2401->tcor = (tx_period >> 3) & 0xE0; /* no x1 ext clk, no loopback */ - - /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */ - cd2401->u2.w.rtpr = 0x04; /* NEED TO LOOK AT THIS LINE! */ - - if ( t->c_cflag & CREAD ) { - /* Re-initialize channel, enable rx and tx */ - cd2401_chan_cmd (minor, 0x2A, 1); - /* Enable rx data ints */ - cd2401->ier = 0x08; - } else { - /* Re-initialize channel, enable tx, disable rx */ - cd2401_chan_cmd (minor, 0x29, 1); - } - } - - CD2401_RECORD_SET_ATTRIBUTES_INFO(( minor, need_reinitialization, csize, - cstopb, parodd, parenb, ignpar, inpck, - hw_flow_ctl, sw_flow_ctl, extra_flow_ctl, - icrnl, igncr, inlcr, brkint, ignbrk, - parmrk, istrip, tx_period, rx_period, - out_baud, in_baud )); - - rtems_interrupt_enable (level); - - /* - * Looks like the CD2401 needs time to settle after initialization. Give it - * 10 ms. I don't really believe it, but if output resumes to quickly after - * this call, the first few characters are not right. - */ - if ( need_reinitialization ) - cd2401_udelay( 10000L ); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_startRemoreTx - * - * Defined as a callback, but it would appear that it is never called. The - * POSIX standard states that when the tcflow() function is called with the - * TCION action, the system wall transmit a START character. Presumably, - * tcflow() is called internally when IXOFF is set in the termios c_iflag - * field when the input buffer can accomodate enough characters. It should - * probably be called from fillBufferQueue(). Clearly, the function is also - * explicitly callable by user code. The action is clearly to send the START - * character, regardless of whether START/STOP flow control is in effect. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * PROPER START CHARACTER MUST BE PROGRAMMED IN SCHR1. - */ -int cd2401_startRemoteTx( - int minor -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - cd2401->stcr = 0x01; /* Send SCHR1 ahead of chars in FIFO */ - - CD2401_RECORD_START_REMOTE_TX_INFO(( minor )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_stopRemoteTx - * - * Defined as a callback, but it would appear that it is never called. The - * POSIX standard states that when the tcflow() function is called with the - * TCIOFF function, the system wall transmit a STOP character. Presumably, - * tcflow() is called internally when IXOFF is set in the termios c_iflag - * field as the input buffer is about to overflow. It should probably be - * called from rtems_termios_enqueue_raw_characters(). Clearly, the function - * is also explicitly callable by user code. The action is clearly to send - * the STOP character, regardless of whether START/STOP flow control is in - * effect. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * PROPER STOP CHARACTER MUST BE PROGRAMMED IN SCHR2. - */ -int cd2401_stopRemoteTx( - int minor -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - cd2401->stcr = 0x02; /* Send SCHR2 ahead of chars in FIFO */ - - CD2401_RECORD_STOP_REMOTE_TX_INFO(( minor )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_write - * - * Initiate DMA output. Termios guarantees that the buffer does not wrap - * around, so we can do DMA strait from the supplied buffer. - * - * Input parameters: - * minor - selected channel - * buf - output buffer - * len - number of chars to output - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * MUST BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! - * The processor is placed at interrupt level CD2401_INT_LEVEL explicitly in - * console_write(). The processor is necessarily at interrupt level 1 in - * cd2401_tx_isr(). - */ -ssize_t cd2401_write( - int minor, - const char *buf, - size_t len -) -{ - if (len > 0) { - cd2401->car = minor; /* Select channel */ - - if ( (cd2401->dmabsts & 0x08) == 0 ) { - /* Next buffer is A. Wait for it to be ours. */ - while ( cd2401->atbsts & 0x01 ); - - CD2401_Channel_Info[minor].own_buf_A = FALSE; - CD2401_Channel_Info[minor].len = len; - CD2401_Channel_Info[minor].buf = buf; - cd2401->atbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); - cd2401->atbadrl = (uint16_t)( (uint32_t) buf ); - cd2401->atbcnt = len; - CD2401_RECORD_WRITE_INFO(( len, buf, 'A' )); - cd2401->atbsts = 0x03; /* CD2401 owns buffer, int when empty */ - } - else { - /* Next buffer is B. Wait for it to be ours. */ - while ( cd2401->btbsts & 0x01 ); - - CD2401_Channel_Info[minor].own_buf_B = FALSE; - CD2401_Channel_Info[minor].len = len; - CD2401_Channel_Info[minor].buf = buf; - cd2401->btbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); - cd2401->btbadrl = (uint16_t)( (uint32_t) buf ); - cd2401->btbcnt = len; - CD2401_RECORD_WRITE_INFO(( len, buf, 'B' )); - cd2401->btbsts = 0x03; /* CD2401 owns buffer, int when empty */ - } - /* Nuts -- Need TxD ints */ - CD2401_Channel_Info[minor].txEmpty = FALSE; - cd2401->ier |= 0x01; - } - - /* Return something */ - return len; -} - -#if 0 -/* - * cd2401_drainOutput - * - * Wait for the txEmpty indication on the specified channel. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * MUST NOT BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! - * The txEmpty flag is set by the tx ISR. - * - * DOES NOT WORK! DO NOT ENABLE THIS CODE. THE CD2401 DOES NOT COOPERATE! - * The code is here to document that the output FIFO is NOT empty when - * the CD2401 reports that the Tx buffer is empty. - */ -int cd2401_drainOutput( - int minor -) -{ - CD2401_RECORD_DRAIN_OUTPUT_INFO(( CD2401_Channel_Info[minor].txEmpty, - CD2401_Channel_Info[minor].own_buf_A, - CD2401_Channel_Info[minor].own_buf_B )); - - while( ! (CD2401_Channel_Info[minor].txEmpty && - CD2401_Channel_Info[minor].own_buf_A && - CD2401_Channel_Info[minor].own_buf_B) ); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} -#endif - -/* - * _167Bug_pollRead - * - * Read a character from the 167Bug console, and return it. Return -1 - * if there is no character in the input FIFO. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: char returned as positive signed int - * -1 if no character is present in the input FIFO. - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -int _167Bug_pollRead( - int minor -) -{ - int char_not_available; - unsigned char c; - rtems_interrupt_level previous_level; - - /* - * Redirection of .INSTAT does not work: 167-Bug crashes. - * Switch the input stream to the specified port. - * Make sure this is atomic code. - */ - rtems_interrupt_disable( previous_level ); - - __asm__ volatile( "movew %1, -(%%sp)\n\t"/* Channel */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x61\n\t" /* Code for .REDIR_I */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x01\n\t" /* Code for .INSTAT */ - "move %%cc, %0\n\t" /* Get condition codes */ - "andil #4, %0" /* Keep the Zero bit */ - : "=d" (char_not_available) : "d" (minor): "%%cc" ); - - if (char_not_available) { - rtems_interrupt_enable( previous_level ); - return -1; - } - - /* Read the char and return it */ - __asm__ volatile( "subq.l #2,%%a7\n\t" /* Space for result */ - "trap #15\n\t" /* Trap to 167 Bug */ - ".short 0x00\n\t" /* Code for .INCHR */ - "moveb (%%a7)+, %0" /* Pop char into c */ - : "=d" (c) : ); - - rtems_interrupt_enable( previous_level ); - - return (int)c; -} - -/* - * _167Bug_pollWrite - * - * Output buffer through 167Bug. Returns only once every character has been - * sent (polled output). - * - * Input parameters: - * minor - selected channel - * buf - output buffer - * len - number of chars to output - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -ssize_t _167Bug_pollWrite( - int minor, - const char *buf, - size_t len -) -{ - const char *endbuf = buf + len; - - __asm__ volatile( "pea (%0)\n\t" /* endbuf */ - "pea (%1)\n\t" /* buf */ - "movew #0x21, -(%%sp)\n\t" /* Code for .OUTSTR */ - "movew %2, -(%%sp)\n\t" /* Channel */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x60" /* Code for .REDIR */ - :: "a" (endbuf), "a" (buf), "d" (minor) ); - - /* Return something */ - return len; -} - -/* - * do_poll_read - * - * Input characters through 167Bug. Returns has soon as a character has been - * received. Otherwise, if we wait for the number of requested characters, we - * could be here forever! - * - * CR is converted to LF on input. The terminal should not send a CR/LF pair - * when the return or enter key is pressed. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel. - * arg->buffer - where to put the received characters. - * arg->count - number of characters to receive before returning--Ignored. - * - * Output parameters: - * arg->bytes_moved - the number of characters read. Always 1. - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - int c; - - while( (c = _167Bug_pollRead (minor)) == -1 ); - rw_args->buffer[0] = (uint8_t)c; - if( rw_args->buffer[0] == '\r' ) - rw_args->buffer[0] = '\n'; - rw_args->bytes_moved = 1; - return RTEMS_SUCCESSFUL; -} - -/* - * do_poll_write - * - * Output characters through 167Bug. Returns only once every character has - * been sent. - * - * CR is transmitted AFTER a LF on output. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel - * arg->buffer - where to get the characters to transmit. - * arg->count - the number of characters to transmit before returning. - * - * Output parameters: - * arg->bytes_moved - the number of characters read - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - uint32_t i; - - for( i = 0; i < rw_args->count; i++ ) { - _167Bug_pollWrite(minor, &(rw_args->buffer[i]), 1); - if ( rw_args->buffer[i] == '\n' ) - _167Bug_pollWrite(minor, &cr_char, 1); - } - rw_args->bytes_moved = i; - return RTEMS_SUCCESSFUL; -} - -/* - * _BSP_output_char - * - * printk() function prototyped in bspIo.h. Does not use termios. - */ -void _BSP_output_char(char c) -{ - rtems_device_minor_number printk_minor; - - /* - * Can't rely on console_initialize having been called before this function - * is used. - */ - if ( NVRAM_CONFIGURE ) - /* J1-4 is on, use NVRAM info for configuration */ - printk_minor = (nvram->console_printk_port & 0x30) >> 4; - else - printk_minor = PRINTK_MINOR; - - _167Bug_pollWrite(printk_minor, &c, 1); -} - -/* - *************** - * BOILERPLATE * - *************** - * - * All these functions are prototyped in rtems/c/src/lib/include/console.h. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - rtems_device_minor_number console_minor; - - /* - * Set up TERMIOS if needed - */ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - console_minor = nvram->console_printk_port & 0x03; - - if ( nvram->console_mode & 0x01 ) - /* termios */ - rtems_termios_initialize (); - } - else { - console_minor = CONSOLE_MINOR; -#if CD2401_USE_TERMIOS == 1 - rtems_termios_initialize (); -#endif - } - - /* - * Do device-specific initialization - * Does not affect 167-Bug. - */ - cd2401_initialize (); - - /* - * Register the devices - */ - status = rtems_io_register_name ("/dev/tty0", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty1", major, 1); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/console", major, console_minor); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty2", major, 2); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty3", major, 3); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - _167Bug_pollRead, /* pollRead */ - _167Bug_pollWrite, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - static const rtems_termios_callbacks intrCallbacks = { - cd2401_firstOpen, /* firstOpen */ - cd2401_lastClose, /* lastClose */ - NULL, /* pollRead */ - cd2401_write, /* write */ - cd2401_setAttributes, /* setAttributes */ - cd2401_stopRemoteTx, /* stopRemoteTx */ - cd2401_startRemoteTx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - - if ( NVRAM_CONFIGURE ) - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - if ( nvram->console_mode & 0x02 ) - /* interrupt-driven I/O */ - return rtems_termios_open (major, minor, arg, &intrCallbacks); - else - /* polled I/O */ - return rtems_termios_open (major, minor, arg, &pollCallbacks); - else - /* no termios -- default to polled I/O */ - return RTEMS_SUCCESSFUL; -#if CD2401_USE_TERMIOS == 1 -#if CD2401_IO_MODE != 1 - else - /* termios & polled I/O*/ - return rtems_termios_open (major, minor, arg, &pollCallbacks); -#else - else - /* termios & interrupt-driven I/O*/ - return rtems_termios_open (major, minor, arg, &intrCallbacks); -#endif -#else - else - /* no termios -- default to polled I/O */ - return RTEMS_SUCCESSFUL; -#endif -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_close (arg); - else - /* no termios */ - return RTEMS_SUCCESSFUL; - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_close (arg); -#else - else - /* no termios */ - return RTEMS_SUCCESSFUL; -#endif -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_read (arg); - else - /* no termios -- default to polled */ - return do_poll_read (major, minor, arg); - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_read (arg); -#else - else - /* no termios -- default to polled */ - return do_poll_read (major, minor, arg); -#endif -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_write (arg); - else - /* no termios -- default to polled */ - return do_poll_write (major, minor, arg); - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_write (arg); -#else - else - /* no termios -- default to polled */ - return do_poll_write (major, minor, arg); -#endif -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_ioctl (arg); - else - /* no termios -- default to polled */ - return RTEMS_SUCCESSFUL; - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_ioctl (arg); -#else - else - /* no termios -- default to polled */ - return RTEMS_SUCCESSFUL; -#endif -} diff --git a/c/src/lib/libbsp/m68k/uC5282/Makefile.am b/c/src/lib/libbsp/m68k/uC5282/Makefile.am index 237e2096c1..de7e43acb8 100644 --- a/c/src/lib/libbsp/m68k/uC5282/Makefile.am +++ b/c/src/lib/libbsp/m68k/uC5282/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/uC5282/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/uC5282/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/uC5282/console/console.c b/c/src/lib/libbsp/m68k/uC5282/console/console.c deleted file mode 100644 index 276d0c6f18..0000000000 --- a/c/src/lib/libbsp/m68k/uC5282/console/console.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * Author: W. Eric Norum - * - * COPYRIGHT (c) 2005. - * 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 -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ - MCF5282_UART_USR_FE | \ - MCF5282_UART_USR_PE | \ - MCF5282_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void -_BSP_null_char( char c ) -{ - int level; - - rtems_interrupt_disable(level); - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - MCF5282_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - rtems_interrupt_enable(level); -} - -BSP_polling_getchar_function_type BSP_poll_char = NULL; -BSP_output_char_function_type BSP_output_char = _BSP_null_char; - -/* - * The MCF5282 has three UARTs. Enable all them here. I/O pin selection - * is assumed to have been done elsewher. - */ -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UOP0(minor) = 1; - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = (clock_speed / ( 32 * baud )); - if ( divisor < 2 ) { - divisor = 2; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - umr1 |= MCF5282_UART_UMR1_RXRTS; - umr2 |= MCF5282_UART_UMR2_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; - MCF5282_UART_UMR(minor) = umr1; - MCF5282_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); - MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int)9600; - int databits = (int)MCF5282_UART_UMR1_BC_8; - int parity = (int)MCF5282_UART_UMR1_PM_NONE; - int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF5282_UART_UMR1_BC_5; - break; - case CS6: - databits = (int)MCF5282_UART_UMR1_BC_6; - break; - case CS7: - databits = (int)MCF5282_UART_UMR1_BC_7; - break; - case CS8: - databits = (int)MCF5282_UART_UMR1_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF5282_UART_UMR1_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF5282_UART_UMR1_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return( RTEMS_SUCCESSFUL ); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) - { - /* read data and put into the receive buffer */ - while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) - { - - if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) - { - /* clear the error */ - MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && - ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - - - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - - MCF5282_UART_UACR(chan) = 0; - MCF5282_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - bsp_allocate_interrupt(UART0_IRQ_LEVEL, UART0_IRQ_PRIORITY); - MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 1: - bsp_allocate_interrupt(UART1_IRQ_LEVEL, UART1_IRQ_PRIORITY); - MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 2: - bsp_allocate_interrupt(UART2_IRQ_LEVEL, UART2_IRQ_PRIORITY); - MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | - MCF5282_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF5282_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return 0; -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - /* - * Enable serial I/O pin assignments - */ - rtems_interrupt_disable(level); - switch(minor) { - case 0: - MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA1|MCF5282_GPIO_PUAPAR_PUAPA0; - break; - case 1: - MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA3|MCF5282_GPIO_PUAPAR_PUAPA2; - break; - case 2: - MCF5282_GPIO_PASPAR = - (MCF5282_GPIO_PASPAR - & ~(MCF5282_GPIO_PASPAR_PASPA3(3)|MCF5282_GPIO_PASPAR_PASPA2(3))) - | (MCF5282_GPIO_PASPAR_PASPA3(2)|MCF5282_GPIO_PASPAR_PASPA2(2)); - break; - } - rtems_interrupt_enable(level); - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - return( 0 ); -} - - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return( EOF ); -} - - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ - if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) - return(-1); - - return(MCF5282_UART_URB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5282_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, all uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - int chan; - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - IntUartInfo[chan].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other ports */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - status = rtems_io_register_name ("/dev/tty02", major, 2); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} - -- cgit v1.2.3