summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-10-23 18:47:43 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-10-23 18:47:43 +0000
commit4106f7f74bb16af78ac461d75cde1a669db8c991 (patch)
tree0e125b5a894406b75671c27bc57965466fc237b5 /c/src/lib/libbsp
parentUpdated console driver to use new read routine conventions. (diff)
downloadrtems-4106f7f74bb16af78ac461d75cde1a669db8c991.tar.bz2
Update from Eric Norum.
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/console/console.c314
1 files changed, 153 insertions, 161 deletions
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 <termios.h>
#include <bsp.h>
#include <rtems/libio.h>
#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);
}