From 4106f7f74bb16af78ac461d75cde1a669db8c991 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 23 Oct 1997 18:47:43 +0000 Subject: Update from Eric Norum. --- c/src/lib/libbsp/m68k/gen68360/console/console.c | 314 +++++++++++------------ 1 file changed, 153 insertions(+), 161 deletions(-) (limited to 'c/src/lib/libbsp') diff --git a/c/src/lib/libbsp/m68k/gen68360/console/console.c b/c/src/lib/libbsp/m68k/gen68360/console/console.c index f3e617f08c..270d6b2bb7 100644 --- a/c/src/lib/libbsp/m68k/gen68360/console/console.c +++ b/c/src/lib/libbsp/m68k/gen68360/console/console.c @@ -1,19 +1,17 @@ /* - * Initialize SMC1 for console IO. + * SMC1 raw console serial I/O. * - * Based on the `gen68302' board support package, and covered by the - * original distribution terms. + * This driver is an example of `POLLING' or `INTERRUPT' input. * - * W. Eric Norum - * Saskatchewan Accelerator Laboratory - * University of Saskatchewan - * Saskatoon, Saskatchewan, CANADA - * eric@skatter.usask.ca + * To compile with interrupt-driven input, define M360_SMC1_INTERRUPT + * in the make customization file for this bsp (gen68360.cfg). * - * $Id$ - */ - -/* + * Author: + * W. Eric Norum + * Saskatchewan Accelerator Laboratory + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@skatter.usask.ca * * COPYRIGHT (c) 1989-1997. * On-Line Applications Research Corporation (OAR). @@ -21,45 +19,62 @@ * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at + * * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ */ -#define GEN68360_INIT - +#include #include #include #include "m68360.h" -/* console_initialize - * - * This routine initializes the console IO driver. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: - */ +#if (defined (M360_SMC1_INTERRUPT)) +# define RXBUFSIZE 16 +static void *smc1ttyp; +#else +# define RXBUFSIZE 1 +#endif /* - * I/O buffers can be in ordindary RAM + * I/O buffers and pointers to buffer descriptors */ -static volatile char rxBuf, txBuf; -static volatile m360BufferDescriptor_t *consoleRxBd, *consoleTxBd; +static volatile char rxBuf[RXBUFSIZE], txBuf; +static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) +/* + * Device-specific routines + */ +#if (defined (M360_SMC1_INTERRUPT)) +static rtems_isr +smc1InterruptHandler (rtems_vector_number v) { - rtems_status_code status; + /* + * 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; + } + } + m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ +} +#endif + +static void +smc1Initialize (void) +{ /* * Allocate buffer descriptors */ - consoleRxBd = M360AllocateBufferDescriptors (1); - consoleTxBd = M360AllocateBufferDescriptors (1); + smcRxBd = M360AllocateBufferDescriptors (1); + smcTxBd = M360AllocateBufferDescriptors (1); /* * Configure port B pins to enable SMTXD1 and SMRXD1 pins @@ -82,16 +97,16 @@ rtems_device_driver console_initialize( /* * Set up SMC1 parameter RAM common to all protocols */ - m360.smc1p.rbase = (char *)consoleRxBd - (char *)&m360; - m360.smc1p.tbase = (char *)consoleTxBd - (char *)&m360; + 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; - m360.smc1p.mrblr = 1; + m360.smc1p.mrblr = RXBUFSIZE; /* * Set up SMC1 parameter RAM UART-specific parameters */ - m360.smc1p.un.uart.max_idl = 0; + 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; @@ -99,16 +114,16 @@ rtems_device_driver console_initialize( /* * Set up the Receive Buffer Descriptor */ - consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; - consoleRxBd->length = 0; - consoleRxBd->buffer = &rxBuf; + smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; + smcRxBd->length = 0; + smcRxBd->buffer = rxBuf; /* * Setup the Transmit Buffer Descriptor */ - consoleTxBd->length = 1; - consoleTxBd->status = M360_BD_WRAP; - consoleTxBd->buffer = &txBuf; + smcTxBd->status = M360_BD_WRAP; + smcTxBd->length = 1; + smcTxBd->buffer = &txBuf; /* * Set up SMC1 general and protocol-specific mode registers @@ -127,181 +142,158 @@ rtems_device_driver console_initialize( */ m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; - 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; +#if (defined (M360_SMC1_INTERRUPT)) + { + rtems_isr_entry old_handler; + rtems_status_code sc; + + sc = rtems_interrupt_catch (smc1InterruptHandler, + (m360.cicr & 0xE0) | 0x04, + &old_handler); + m360.smc1.smcm = 1; /* Enable SMC1 receiver interrupt */ + m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ + } +#endif } -/* is_character_ready - * - * Check to see if a character is available on the console port. If so, - * then return a TRUE (along with the character). Otherwise return FALSE. - * - * Input parameters: pointer to location in which to return character - * - * Output parameters: character (if available) - * - * Return values: TRUE - character available - * FALSE - no character available - */ - -rtems_boolean is_character_ready( - char *ch /* -> character */ -) +static int +smc1Read (int minor) { - if (consoleRxBd->status & M360_BD_EMPTY) - return FALSE; - *ch = rxBuf; - consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; - return TRUE; -} + unsigned char c; + if (smcRxBd->status & M360_BD_EMPTY) + return -1; + c = rxBuf[0]; + smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; + return c; +} -/* inbyte - * - * Receive a character from the console port - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: character read - */ - -char inbyte( void ) +static int +smc1Write (int minor, char *buf, int len) { - char ch; - - while (is_character_ready (&ch) == FALSE) - continue; - return ch; + int nwrite = 0; + + while (nwrite < len) { + while (smcTxBd->status & M360_BD_READY) + continue; + txBuf = *buf++; + smcTxBd->status = M360_BD_READY | M360_BD_WRAP; + nwrite++; + } + return nwrite; } - -/* outbyte - * - * Transmit a character to the console serial port - * - * Input parameters: - * ch - character to be transmitted - * - * Output parameters: NONE +/* + *************** + * BOILERPLATE * + *************** */ -void outbyte( - char ch +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) { - if (ch == '\n') - outbyte('\r'); - while (consoleTxBd->status & M360_BD_READY) - continue; - txBuf = ch; - consoleTxBd->status = M360_BD_READY | M360_BD_WRAP; + rtems_status_code status; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + smc1Initialize (); + + /* + * 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 entry point + * Open the device */ - rtems_device_driver console_open( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ) { - return RTEMS_SUCCESSFUL; + rtems_status_code sc; + +#if (defined (M360_SMC1_INTERRUPT)) + rtems_libio_open_close_args_t *args = arg; + + sc = rtems_termios_open (major, minor, arg, + NULL, + NULL, + NULL, + smc1Write); + smc1ttyp = args->iop->data1; +#else + sc = rtems_termios_open (major, minor, arg, + NULL, + NULL, + smc1Read, + smc1Write); +#endif + return sc; } /* - * Close entry point + * Close the device */ - rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ) { - return RTEMS_SUCCESSFUL; + return rtems_termios_close (arg); } /* - * read bytes from the serial port. We only have stdin. + * Read from the device */ - 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; + return rtems_termios_read (arg); } /* - * write bytes to the serial port. Stdout and stderr are the same. + * Write to the device */ - 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; + return rtems_termios_write (arg); } /* - * IO Control entry point + * Handle ioctl request. + * Should set hardware line speed, bits/char, etc. */ - rtems_device_driver console_control( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ) -{ - return RTEMS_SUCCESSFUL; +{ + return rtems_termios_ioctl (arg); } -- cgit v1.2.3