forked from Imagelibrary/rtems
Update from Eric Norum.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user