Update from Eric Norum.

This commit is contained in:
Joel Sherrill
1997-10-23 18:47:43 +00:00
parent aa239a7ec2
commit 4106f7f74b

View File

@@ -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 * This driver is an example of `POLLING' or `INTERRUPT' input.
* original distribution terms.
* *
* To compile with interrupt-driven input, define M360_SMC1_INTERRUPT
* in the make customization file for this bsp (gen68360.cfg).
*
* Author:
* W. Eric Norum * W. Eric Norum
* Saskatchewan Accelerator Laboratory * Saskatchewan Accelerator Laboratory
* University of Saskatchewan * University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA * Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.ca * eric@skatter.usask.ca
*
* $Id$
*/
/*
* *
* COPYRIGHT (c) 1989-1997. * COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR). * On-Line Applications Research Corporation (OAR).
@@ -21,45 +19,62 @@
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
*
* http://www.OARcorp.com/rtems/license.html. * http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/ */
#define GEN68360_INIT #include <termios.h>
#include <bsp.h> #include <bsp.h>
#include <rtems/libio.h> #include <rtems/libio.h>
#include "m68360.h" #include "m68360.h"
/* console_initialize #if (defined (M360_SMC1_INTERRUPT))
* # define RXBUFSIZE 16
* This routine initializes the console IO driver. static void *smc1ttyp;
* #else
* Input parameters: NONE # define RXBUFSIZE 1
* #endif
* Output parameters: NONE
*
* Return values:
*/
/* /*
* I/O buffers can be in ordindary RAM * I/O buffers and pointers to buffer descriptors
*/ */
static volatile char rxBuf, txBuf; static volatile char rxBuf[RXBUFSIZE], txBuf;
static volatile m360BufferDescriptor_t *consoleRxBd, *consoleTxBd; static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd;
rtems_device_driver console_initialize( /*
rtems_device_major_number major, * Device-specific routines
rtems_device_minor_number minor, */
void *arg #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 * Allocate buffer descriptors
*/ */
consoleRxBd = M360AllocateBufferDescriptors (1); smcRxBd = M360AllocateBufferDescriptors (1);
consoleTxBd = M360AllocateBufferDescriptors (1); smcTxBd = M360AllocateBufferDescriptors (1);
/* /*
* Configure port B pins to enable SMTXD1 and SMRXD1 pins * 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 * Set up SMC1 parameter RAM common to all protocols
*/ */
m360.smc1p.rbase = (char *)consoleRxBd - (char *)&m360; m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360;
m360.smc1p.tbase = (char *)consoleTxBd - (char *)&m360; m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360;
m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_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 * 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.brklen = 0;
m360.smc1p.un.uart.brkec = 0; m360.smc1p.un.uart.brkec = 0;
m360.smc1p.un.uart.brkcr = 0; m360.smc1p.un.uart.brkcr = 0;
@@ -99,16 +114,16 @@ rtems_device_driver console_initialize(
/* /*
* Set up the Receive Buffer Descriptor * Set up the Receive Buffer Descriptor
*/ */
consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
consoleRxBd->length = 0; smcRxBd->length = 0;
consoleRxBd->buffer = &rxBuf; smcRxBd->buffer = rxBuf;
/* /*
* Setup the Transmit Buffer Descriptor * Setup the Transmit Buffer Descriptor
*/ */
consoleTxBd->length = 1; smcTxBd->status = M360_BD_WRAP;
consoleTxBd->status = M360_BD_WRAP; smcTxBd->length = 1;
consoleTxBd->buffer = &txBuf; smcTxBd->buffer = &txBuf;
/* /*
* Set up SMC1 general and protocol-specific mode registers * 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; m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
status = rtems_io_register_name( #if (defined (M360_SMC1_INTERRUPT))
"/dev/console", {
major, rtems_isr_entry old_handler;
(rtems_device_minor_number)0); 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
}
static int
smc1Read (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;
}
static int
smc1Write (int minor, char *buf, int len)
{
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;
}
/*
***************
* BOILERPLATE *
***************
*/
/*
* 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 ();
/*
* Do device-specific initialization
*/
smc1Initialize ();
/*
* Register the device
*/
status = rtems_io_register_name ("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status); rtems_fatal_error_occurred (status);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* 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 */
)
{
if (consoleRxBd->status & M360_BD_EMPTY)
return FALSE;
*ch = rxBuf;
consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
return TRUE;
}
/* inbyte
*
* Receive a character from the console port
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values: character read
*/
char inbyte( void )
{
char ch;
while (is_character_ready (&ch) == FALSE)
continue;
return ch;
}
/* outbyte
*
* Transmit a character to the console serial port
*
* Input parameters:
* ch - character to be transmitted
*
* Output parameters: NONE
*/
void outbyte(
char ch
)
{
if (ch == '\n')
outbyte('\r');
while (consoleTxBd->status & M360_BD_READY)
continue;
txBuf = ch;
consoleTxBd->status = M360_BD_READY | M360_BD_WRAP;
}
/* /*
* Open entry point * Open the device
*/ */
rtems_device_driver console_open( rtems_device_driver console_open(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void * arg 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_driver console_close(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void * arg 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_driver console_read(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void * arg void * arg
) )
{ {
rtems_libio_rw_args_t *rw_args; return rtems_termios_read (arg);
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. * Write to the device
*/ */
rtems_device_driver console_write( rtems_device_driver console_write(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void * arg void * arg
) )
{ {
int count; return rtems_termios_write (arg);
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 * Handle ioctl request.
* Should set hardware line speed, bits/char, etc.
*/ */
rtems_device_driver console_control( rtems_device_driver console_control(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void * arg void * arg
) )
{ {
return RTEMS_SUCCESSFUL; return rtems_termios_ioctl (arg);
} }