forked from Imagelibrary/rtems
bsps/powerpc: Remove unused files
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
Various non BSP dependant support routines.
|
||||
|
||||
clock - Uses the 403 PIT (Programmable interval timer) to
|
||||
generate RTEMS clock ticks.
|
||||
|
||||
console - Uses the 403 Internal serial port to do RTEMS
|
||||
console I/O. Not ALL members of the 403 family
|
||||
have this.
|
||||
|
||||
include - Currently empty
|
||||
|
||||
timer - Uses the 403 timebase register for timing
|
||||
tests. Other PowerPCs have slightly different
|
||||
timebase register definitions.
|
||||
|
||||
vectors - PowerPC 403 specific vector entry points.
|
||||
Includes CPU dependant, application independant
|
||||
handlers: alignment.
|
||||
@@ -1,541 +0,0 @@
|
||||
/*
|
||||
* This file contains the PowerPC 403GA console IO package.
|
||||
*
|
||||
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||
*
|
||||
* COPYRIGHT (c) 1998 by IMD
|
||||
*
|
||||
* Changes from IMD are covered by the original distributions terms.
|
||||
* changes include interrupt support and termios support
|
||||
* for backward compatibility, the original polled driver has been
|
||||
* renamed to console.c.polled
|
||||
*
|
||||
* This file has been initially created (polled version) by
|
||||
*
|
||||
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||
*
|
||||
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of i-cubed limited not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* i-cubed limited makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Modifications for spooling (interrupt driven) console driver
|
||||
* by Thomas Doerfler <td@imd.m.isar.de>
|
||||
* for these modifications:
|
||||
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies. IMD makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*/
|
||||
|
||||
#define NO_BSP_INIT
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include "../irq/ictrl.h"
|
||||
#include <stdlib.h> /* for atexit() */
|
||||
|
||||
struct async {
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Line Status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char SPLS;
|
||||
unsigned char SPLSset;
|
||||
#define LSRDataReady 0x80
|
||||
#define LSRFramingError 0x40
|
||||
#define LSROverrunError 0x20
|
||||
#define LSRParityError 0x10
|
||||
#define LSRBreakInterrupt 0x08
|
||||
#define LSRTxHoldEmpty 0x04
|
||||
#define LSRTxShiftEmpty 0x02
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Handshake Status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char SPHS;
|
||||
unsigned char SPHSset;
|
||||
#define HSRDsr 0x80
|
||||
#define HSRCts 0x40
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Baud rate divisor registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char BRDH;
|
||||
unsigned char BRDL;
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Control Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char SPCTL;
|
||||
#define CRNormal 0x00
|
||||
#define CRLoopback 0x40
|
||||
#define CRAutoEcho 0x80
|
||||
#define CRDtr 0x20
|
||||
#define CRRts 0x10
|
||||
#define CRWordLength7 0x00
|
||||
#define CRWordLength8 0x08
|
||||
#define CRParityDisable 0x00
|
||||
#define CRParityEnable 0x04
|
||||
#define CREvenParity 0x00
|
||||
#define CROddParity 0x02
|
||||
#define CRStopBitsOne 0x00
|
||||
#define CRStopBitsTwo 0x01
|
||||
#define CRDisableDtrRts 0x00
|
||||
|
||||
/*--------------------------------------------------------------------------+
|
||||
| Receiver Command Register.
|
||||
+--------------------------------------------------------------------------*/
|
||||
unsigned char SPRC;
|
||||
#define RCRDisable 0x00
|
||||
#define RCREnable 0x80
|
||||
#define RCRIntDisable 0x00
|
||||
#define RCRIntEnabled 0x20
|
||||
#define RCRDMACh2 0x40
|
||||
#define RCRDMACh3 0x60
|
||||
#define RCRErrorInt 0x10
|
||||
#define RCRPauseEnable 0x08
|
||||
|
||||
/*--------------------------------------------------------------------------+
|
||||
| Transmitter Command Register.
|
||||
+--------------------------------------------------------------------------*/
|
||||
unsigned char SPTC;
|
||||
#define TCRDisable 0x00
|
||||
#define TCREnable 0x80
|
||||
#define TCRIntDisable 0x00
|
||||
#define TCRIntEnabled 0x20
|
||||
#define TCRDMACh2 0x40
|
||||
#define TCRDMACh3 0x60
|
||||
#define TCRTxEmpty 0x10
|
||||
#define TCRErrorInt 0x08
|
||||
#define TCRStopPause 0x04
|
||||
#define TCRBreakGen 0x02
|
||||
|
||||
/*--------------------------------------------------------------------------+
|
||||
| Miscellanies defines.
|
||||
+--------------------------------------------------------------------------*/
|
||||
unsigned char SPTB;
|
||||
#define SPRB SPTB
|
||||
};
|
||||
|
||||
typedef volatile struct async *pasync;
|
||||
static const pasync port = (pasync)0x40000000;
|
||||
|
||||
static void *spittyp; /* handle for termios */
|
||||
int ppc403_spi_interrupt = 1; /* use interrupts... */
|
||||
|
||||
/*
|
||||
* Rx Interrupt handler
|
||||
*/
|
||||
static rtems_isr
|
||||
spiRxInterruptHandler (rtems_vector_number v)
|
||||
{
|
||||
char ch;
|
||||
|
||||
/* clear any receive errors (errors are ignored now) */
|
||||
port->SPLS = (LSRFramingError | LSROverrunError |
|
||||
LSRParityError | LSRBreakInterrupt);
|
||||
/*
|
||||
* Buffer received?
|
||||
*/
|
||||
if (port->SPLS & LSRDataReady) {
|
||||
ch = port->SPRB; /* read receive buffer */
|
||||
rtems_termios_enqueue_raw_characters (spittyp,&ch,1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tx Interrupt handler
|
||||
*/
|
||||
static rtems_isr
|
||||
spiTxInterruptHandler (rtems_vector_number v)
|
||||
{
|
||||
/*
|
||||
* char transmitted?
|
||||
*/
|
||||
if (0 != (port->SPLS & LSRTxHoldEmpty)) { /* must always be true!! */
|
||||
port->SPTC &= ~TCRIntEnabled; /* stop irqs for now... */
|
||||
/* and call termios... */
|
||||
rtems_termios_dequeue_characters (spittyp,1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* enable/disable RTS line to start/stop remote transmitter
|
||||
*/
|
||||
static int
|
||||
spiStartRemoteTx (int minor)
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable (level);
|
||||
port->SPCTL |= CRRts; /* activate RTS */
|
||||
rtems_interrupt_enable (level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spiStopRemoteTx (int minor)
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable (level);
|
||||
port->SPCTL &= ~CRRts; /* deactivate RTS */
|
||||
rtems_interrupt_enable (level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
spiBaudSet(uint32_t baudrate)
|
||||
{
|
||||
uint32_t tmp;
|
||||
extern uint32_t bsp_serial_per_sec;
|
||||
tmp = bsp_serial_per_sec / baudrate;
|
||||
tmp = ((tmp) >> 4) - 1;
|
||||
port->BRDL = tmp & 0xff;
|
||||
port->BRDH = tmp >> 8;
|
||||
|
||||
}
|
||||
/*
|
||||
* Hardware-dependent portion of tcsetattr().
|
||||
*/
|
||||
static int
|
||||
spiSetAttributes (int minor, const struct termios *t)
|
||||
{
|
||||
int baud;
|
||||
|
||||
/* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
|
||||
/* FIXME: check and IMPLEMENT XON/XOFF */
|
||||
switch (t->c_ospeed) {
|
||||
default: baud = -1; break;
|
||||
case B50: baud = 50; break;
|
||||
case B75: baud = 75; break;
|
||||
case B110: baud = 110; break;
|
||||
case B134: baud = 134; break;
|
||||
case B150: baud = 150; break;
|
||||
case B200: baud = 200; break;
|
||||
case B300: baud = 300; break;
|
||||
case B600: baud = 600; break;
|
||||
case B1200: baud = 1200; break;
|
||||
case B1800: baud = 1800; break;
|
||||
case B2400: baud = 2400; break;
|
||||
case B4800: baud = 4800; break;
|
||||
case B9600: baud = 9600; break;
|
||||
case B19200: baud = 19200; break;
|
||||
case B38400: baud = 38400; break;
|
||||
case B57600: baud = 57600; break;
|
||||
case B115200: baud = 115200; break;
|
||||
case B230400: baud = 230400; break;
|
||||
case B460800: baud = 460800; break;
|
||||
}
|
||||
if (baud > 0) {
|
||||
spiBaudSet(baud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spiPollRead (int minor)
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
while (0 == ((status = port->SPLS) & LSRDataReady)) {
|
||||
/* Clean any dodgy status */
|
||||
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt)) != 0) {
|
||||
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt);
|
||||
}
|
||||
}
|
||||
return port->SPRB;
|
||||
}
|
||||
|
||||
static int
|
||||
spiInterruptWrite (int minor, const char *buf, int len)
|
||||
{
|
||||
if (len > 0) {
|
||||
port->SPTB = *buf; /* write char to send */
|
||||
port->SPTC |= TCRIntEnabled; /* always enable tx interrupt */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spiPollWrite(int minor,const char *buf,int len)
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
while (len-- > 0) {
|
||||
do {
|
||||
if (port->SPHS) {
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
}
|
||||
status = port->SPLS;
|
||||
} while (0 == (status & LSRTxHoldEmpty));
|
||||
port->SPTB = *buf++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* deinit SPI
|
||||
*
|
||||
*/
|
||||
void
|
||||
spiDeInit(void)
|
||||
{
|
||||
extern uint32_t bsp_serial_rate;
|
||||
/*
|
||||
* disable interrupts for serial port
|
||||
* set it to state to work with polling boot monitor, if any...
|
||||
*/
|
||||
|
||||
/* set up baud rate to original state */
|
||||
spiBaudSet(bsp_serial_rate);
|
||||
|
||||
/* clear any receive (error) status */
|
||||
port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
|
||||
LSRParityError | LSRBreakInterrupt);
|
||||
|
||||
/* set up port control: DTR/RTS active,8 bit,1 stop,no parity */
|
||||
port->SPCTL = (CRNormal |
|
||||
CRDtr | CRRts |
|
||||
CRWordLength8 | CRParityDisable | CRStopBitsOne);
|
||||
|
||||
/* clear handshake status bits */
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
|
||||
/* enable receiver/transmitter, no interrupts */
|
||||
port->SPRC = (RCREnable | RCRIntDisable);
|
||||
port->SPTC = (TCREnable | TCRIntDisable);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* init SPI
|
||||
*
|
||||
*/
|
||||
rtems_status_code
|
||||
spiInitialize(void)
|
||||
{
|
||||
register unsigned tmp;
|
||||
rtems_isr_entry previous_isr; /* this is a dummy */
|
||||
extern bool bsp_serial_external_clock;
|
||||
extern uint32_t bsp_serial_rate;
|
||||
|
||||
/*
|
||||
* Initialise the serial port
|
||||
*/
|
||||
|
||||
/*
|
||||
* select RTS/CTS hardware handshake lines,
|
||||
* select clock source
|
||||
*/
|
||||
__asm__ volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
|
||||
|
||||
tmp &= ~3;
|
||||
tmp |= (bsp_serial_external_clock ? 2 : 0) | 1;
|
||||
|
||||
__asm__ volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
|
||||
|
||||
/* clear any receive (error) status */
|
||||
port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
|
||||
LSRParityError | LSRBreakInterrupt);
|
||||
|
||||
/* set up baud rate */
|
||||
spiBaudSet(bsp_serial_rate);
|
||||
|
||||
/* set up port control: DTR/RTS active,8 bit,1 stop,no parity */
|
||||
port->SPCTL = (CRNormal |
|
||||
CRDtr | CRRts |
|
||||
CRWordLength8 | CRParityDisable | CRStopBitsOne);
|
||||
|
||||
/* clear handshake status bits */
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
|
||||
if (ppc403_spi_interrupt) {
|
||||
/* add rx/tx isr to vector table */
|
||||
ictrl_set_vector(spiRxInterruptHandler,
|
||||
PPC_IRQ_EXT_SPIR,
|
||||
&previous_isr);
|
||||
|
||||
ictrl_set_vector(spiTxInterruptHandler,
|
||||
PPC_IRQ_EXT_SPIT,
|
||||
&previous_isr);
|
||||
|
||||
port->SPRC = (RCREnable | RCRIntEnabled | RCRErrorInt);
|
||||
port->SPTC = (TCREnable | TCRIntDisable); /* don't enable TxInt yet */
|
||||
}
|
||||
else {
|
||||
/* enable receiver/transmitter, no interrupts */
|
||||
port->SPRC = (RCREnable | RCRIntDisable);
|
||||
port->SPTC = (TCREnable | TCRIntDisable);
|
||||
}
|
||||
|
||||
atexit(spiDeInit);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
***************
|
||||
* BOILERPLATE *
|
||||
***************
|
||||
*/
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
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
|
||||
*/
|
||||
spiInitialize ();
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
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 = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
NULL, /* pollRead */
|
||||
spiInterruptWrite, /* write */
|
||||
spiSetAttributes, /* setAttributes */
|
||||
spiStopRemoteTx, /* stopRemoteTx */
|
||||
spiStartRemoteTx, /* startRemoteTx */
|
||||
1 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
static const rtems_termios_callbacks pollCallbacks = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
spiPollRead, /* pollRead */
|
||||
spiPollWrite, /* write */
|
||||
spiSetAttributes, /* setAttributes */
|
||||
spiStopRemoteTx, /* stopRemoteTx */
|
||||
spiStartRemoteTx, /* startRemoteTx */
|
||||
0 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
if (ppc403_spi_interrupt) {
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
|
||||
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||
spittyp = args->iop->data1;
|
||||
}
|
||||
else {
|
||||
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_close (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
)
|
||||
{
|
||||
return rtems_termios_write (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Control entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
/*
|
||||
* This file contains the PowerPC 403GA console IO package.
|
||||
*
|
||||
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||
*
|
||||
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of i-cubed limited not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* i-cubed limited makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define NO_BSP_INIT
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
struct async {
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Line Status Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPLS;
|
||||
unsigned char SPLSset;
|
||||
#define LSRDataReady 0x80
|
||||
#define LSRFramingError 0x40
|
||||
#define LSROverrunError 0x20
|
||||
#define LSRParityError 0x10
|
||||
#define LSRBreakInterrupt 0x08
|
||||
#define LSRTxHoldEmpty 0x04
|
||||
#define LSRTxShiftEmpty 0x02
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Handshake Status Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPHS;
|
||||
unsigned char SPHSset;
|
||||
#define HSRDsr 0x80
|
||||
#define HSRCts 0x40
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Baud rate divisor registers
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char BRDH;
|
||||
unsigned char BRDL;
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Control Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPCTL;
|
||||
#define CRNormal 0x00
|
||||
#define CRLoopback 0x40
|
||||
#define CRAutoEcho 0x80
|
||||
#define CRDtr 0x20
|
||||
#define CRRts 0x10
|
||||
#define CRWordLength7 0x00
|
||||
#define CRWordLength8 0x08
|
||||
#define CRParityDisable 0x00
|
||||
#define CRParityEnable 0x04
|
||||
#define CREvenParity 0x00
|
||||
#define CROddParity 0x02
|
||||
#define CRStopBitsOne 0x00
|
||||
#define CRStopBitsTwo 0x01
|
||||
#define CRDisableDtrRts 0x00
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Receiver Command Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPRC;
|
||||
#define RCRDisable 0x00
|
||||
#define RCREnable 0x80
|
||||
#define RCRIntDisable 0x00
|
||||
#define RCRIntEnabled 0x20
|
||||
#define RCRDMACh2 0x40
|
||||
#define RCRDMACh3 0x60
|
||||
#define RCRErrorInt 0x10
|
||||
#define RCRPauseEnable 0x08
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Transmitter Command Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPTC;
|
||||
#define TCRDisable 0x00
|
||||
#define TCREnable 0x80
|
||||
#define TCRIntDisable 0x00
|
||||
#define TCRIntEnabled 0x20
|
||||
#define TCRDMACh2 0x40
|
||||
#define TCRDMACh3 0x60
|
||||
#define TCRTxEmpty 0x10
|
||||
#define TCRErrorInt 0x08
|
||||
#define TCRStopPause 0x04
|
||||
#define TCRBreakGen 0x02
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Miscellanies defines.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
unsigned char SPTB;
|
||||
#define SPRB SPTB
|
||||
};
|
||||
|
||||
#define XOFFchar 0x13
|
||||
#define XONchar 0x11
|
||||
|
||||
typedef volatile struct async *pasync;
|
||||
static const pasync port = (pasync)0x40000000;
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
register unsigned tmp;
|
||||
extern uint32_t bsp_serial_per_sec;
|
||||
extern bool bsp_serial_external_clock;
|
||||
extern bool bsp_serial_cts_rts;
|
||||
extern uint32_t bsp_serial_rate;
|
||||
|
||||
/* Initialise the serial port */
|
||||
__asm__ volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
|
||||
tmp &= ~3;
|
||||
tmp |= (bsp_serial_external_clock ? 2 : 0) |
|
||||
(bsp_serial_cts_rts ? 1 : 0);
|
||||
__asm__ volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
|
||||
port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
|
||||
LSRParityError | LSRBreakInterrupt);
|
||||
tmp = bsp_serial_per_sec / bsp_get_serial_rate;
|
||||
#if 0 /* replaced by IMD... */
|
||||
tmp = ((tmp + 8) >> 4) - 1;
|
||||
port->BRDL = tmp & 0x255;
|
||||
port->BRDH = tmp >> 8;
|
||||
#else
|
||||
tmp = ((tmp) >> 4) - 1;
|
||||
port->BRDL = tmp & 0xff;
|
||||
port->BRDH = tmp >> 8;
|
||||
#endif
|
||||
port->SPCTL = (CRNormal | CRDtr | CRRts | CRWordLength8 | CRParityDisable |
|
||||
CRStopBitsOne);
|
||||
port->SPRC = (RCREnable | RCRIntDisable | RCRPauseEnable);
|
||||
port->SPTC = (TCREnable | TCRIntDisable);
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* is_character_ready
|
||||
*
|
||||
* This routine returns TRUE if a character is available.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
bool is_character_ready(
|
||||
char *ch
|
||||
)
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
if ((status = port->SPLS) & LSRDataReady)
|
||||
{
|
||||
*ch = port->SPRB;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Clean any dodgy status */
|
||||
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt)) != 0)
|
||||
{
|
||||
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* inbyte
|
||||
*
|
||||
* This routine reads a character from the SOURCE.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
* character read from SOURCE
|
||||
*/
|
||||
|
||||
char inbyte( void )
|
||||
{
|
||||
unsigned char status;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((status = port->SPLS) & LSRDataReady)
|
||||
break;
|
||||
|
||||
/* Clean any dodgy status */
|
||||
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt)) != 0)
|
||||
{
|
||||
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
|
||||
LSRBreakInterrupt);
|
||||
}
|
||||
}
|
||||
|
||||
return port->SPRB;
|
||||
}
|
||||
|
||||
/* outbyte
|
||||
*
|
||||
* This routine transmits a character out the SOURCE. It may support
|
||||
* XON/XOFF flow control.
|
||||
*
|
||||
* Input parameters:
|
||||
* ch - character to be transmitted
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void outbyte(
|
||||
char ch
|
||||
)
|
||||
{
|
||||
unsigned char status;
|
||||
extern bool bsp_serial_xon_xoff;
|
||||
|
||||
while (port->SPHS)
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = port->SPLS;
|
||||
|
||||
if (port->SPHS)
|
||||
port->SPHS = (HSRDsr | HSRCts);
|
||||
else if (status & LSRTxHoldEmpty)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bsp_serial_xon_xoff)
|
||||
while (is_character_ready(&status))
|
||||
{
|
||||
if (status == XOFFchar)
|
||||
do {
|
||||
while (!is_character_ready(&status));
|
||||
} while (status != XONchar);
|
||||
}
|
||||
|
||||
port->SPTB = 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';
|
||||
buffer[ count ] = 0;
|
||||
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 ] );
|
||||
}
|
||||
return maximum;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Control entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -1,539 +0,0 @@
|
||||
/*
|
||||
* This file contains the PowerPC 405GP console IO package.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||
*
|
||||
* COPYRIGHT (c) 1998 by IMD
|
||||
*
|
||||
* Changes from IMD are covered by the original distributions terms.
|
||||
* changes include interrupt support and termios support
|
||||
* for backward compatibility, the original polled driver has been
|
||||
* renamed to console.c.polled
|
||||
*
|
||||
* This file has been initially created (polled version) by
|
||||
*
|
||||
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||
*
|
||||
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of i-cubed limited not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* i-cubed limited makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Modifications for spooling (interrupt driven) console driver
|
||||
* by Thomas Doerfler <td@imd.m.isar.de>
|
||||
* for these modifications:
|
||||
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
||||
*
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies. IMD makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modifications for PPC405GP by Dennis Ehlin
|
||||
*/
|
||||
|
||||
#define NO_BSP_INIT
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include "../irq/ictrl.h"
|
||||
#include <stdlib.h> /* for atexit() */
|
||||
#include <rtems/console.h>
|
||||
|
||||
struct async {
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Data Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char RBR; /* 0x00 */
|
||||
#define THR RBR
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Interrupt registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char IER; /* 0x01 */
|
||||
#define IER_RCV 0x01
|
||||
#define IER_XMT 0x02
|
||||
#define IER_LS 0x04
|
||||
#define IER_MS 0x08
|
||||
|
||||
unsigned char ISR; /* 0x02 */
|
||||
#define ISR_MS 0x00
|
||||
#define ISR_nIP 0x01
|
||||
#define ISR_Tx 0x02
|
||||
#define ISR_Rx 0x04
|
||||
#define ISR_LS 0x06
|
||||
#define ISR_RxTO 0x0C
|
||||
#define ISR_64BFIFO 0x20
|
||||
#define ISR_FIFOworks 0x40
|
||||
#define ISR_FIFOen 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| FIFO Control registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define FCR ISR
|
||||
#define FCR_FE 0x01 /* FIFO enable */
|
||||
#define FCR_CRF 0x02 /* Clear receive FIFO */
|
||||
#define FCR_CTF 0x04 /* Clear transmit FIFO */
|
||||
#define FCR_DMA 0x08 /* DMA mode select */
|
||||
#define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */
|
||||
#define FCR_RT14 0xC0 /* Set Rx trigger at 14 */
|
||||
#define FCR_RT8 0x80 /* Set Rx trigger at 8 */
|
||||
#define FCR_RT4 0x40 /* Set Rx trigger at 4 */
|
||||
#define FCR_RT1 0x00 /* Set Rx trigger at 1 */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Baud rate divisor registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define DLL RBR
|
||||
#define DLM IER
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Alternate function registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define AFR ISR
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Line control Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char LCR; /* 0x03 */
|
||||
#define LCR_WL5 0x00 /* Word length 5 */
|
||||
#define LCR_WL6 0x01 /* Word length 6 */
|
||||
#define LCR_WL7 0x02 /* Word length 7 */
|
||||
#define LCR_WL8 0x03 /* Word length 8 */
|
||||
|
||||
#define LCR_SB1 0x00 /* 1 stop bits */
|
||||
#define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/
|
||||
#define LCR_SB1_5 0x04 /* 2 stop bits */
|
||||
|
||||
#define LCR_PN 0x00 /* Parity NONE */
|
||||
#define LCR_PE 0x0C /* Parity EVEN */
|
||||
#define LCR_PO 0x08 /* Parity ODD */
|
||||
#define LCR_PM 0x28 /* Forced "mark" parity */
|
||||
#define LCR_PS 0x38 /* Forced "space" parity */
|
||||
|
||||
#define LCR_DL 0x80 /* Enable baudrate latch */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Modem control Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char MCR; /* 0x04 */
|
||||
#define MCR_DTR 0x01
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_INT 0x08 /* Enable interrupts */
|
||||
#define MCR_LOOP 0x10 /* Loopback mode */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Line status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char LSR; /* 0x05 */
|
||||
#define LSR_RSR 0x01
|
||||
#define LSR_OE 0x02
|
||||
#define LSR_PE 0x04
|
||||
#define LSR_FE 0x08
|
||||
#define LSR_BI 0x10
|
||||
#define LSR_THE 0x20
|
||||
#define LSR_TEMT 0x40
|
||||
#define LSR_FIE 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Modem status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char MSR; /* 0x06 */
|
||||
#define UART_MSR_DCTS 0x01
|
||||
#define UART_MSR_DDSR 0x02
|
||||
#define UART_MSR_TERI 0x04
|
||||
#define UART_MSR_DDCD 0x08
|
||||
#define UART_MSR_CTS 0x10
|
||||
#define UART_MSR_DSR 0x20
|
||||
#define UART_MSR_RI 0x40
|
||||
#define UART_MSR_CD 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Scratch pad Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char SCR; /* 0x07 */
|
||||
};
|
||||
|
||||
|
||||
#define USE_UART 0 /* 0=UART0 1=UART1 */
|
||||
#define UART_INTERNAL_CLOCK_DIVISOR 16
|
||||
|
||||
typedef volatile struct async *pasync;
|
||||
static const pasync port = (pasync)(0xEF600300 + (USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */
|
||||
|
||||
static void *spittyp; /* handle for termios */
|
||||
int ppc403_spi_interrupt = 0; /* do not use interrupts... */
|
||||
|
||||
extern uint32_t bsp_serial_per_sec;
|
||||
extern uint32_t bsp_serial_rate;
|
||||
extern bool bsp_serial_external_clock;
|
||||
|
||||
static int spiBaudRound(double x)
|
||||
{
|
||||
return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x);
|
||||
}
|
||||
|
||||
static void
|
||||
spiBaudSet(uint32_t baudrate)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = spiBaudRound( (double)bsp_serial_per_sec / (baudrate * 16) );
|
||||
|
||||
port->LCR = port->LCR | LCR_DL;
|
||||
|
||||
port->DLL = tmp & 0xff;
|
||||
port->DLM = tmp >> 8;
|
||||
|
||||
port->LCR = port->LCR & ~LCR_DL;
|
||||
}
|
||||
/*
|
||||
* Hardware-dependent portion of tcsetattr().
|
||||
*/
|
||||
static int
|
||||
spiSetAttributes (int minor, const struct termios *t)
|
||||
{
|
||||
int baud;
|
||||
|
||||
/* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
|
||||
/* FIXME: check and IMPLEMENT XON/XOFF */
|
||||
switch (t->c_ospeed) {
|
||||
default: baud = -1; break;
|
||||
case B50: baud = 50; break;
|
||||
case B75: baud = 75; break;
|
||||
case B110: baud = 110; break;
|
||||
case B134: baud = 134; break;
|
||||
case B150: baud = 150; break;
|
||||
case B200: baud = 200; break;
|
||||
case B300: baud = 300; break;
|
||||
case B600: baud = 600; break;
|
||||
case B1200: baud = 1200; break;
|
||||
case B1800: baud = 1800; break;
|
||||
case B2400: baud = 2400; break;
|
||||
case B4800: baud = 4800; break;
|
||||
case B9600: baud = 9600; break;
|
||||
case B19200: baud = 19200; break;
|
||||
case B38400: baud = 38400; break;
|
||||
case B57600: baud = 57600; break;
|
||||
case B115200: baud = 115200; break;
|
||||
case B230400: baud = 230400; break;
|
||||
case B460800: baud = 460800; break;
|
||||
}
|
||||
if (baud > 0) {
|
||||
spiBaudSet(baud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spiPollRead (int minor)
|
||||
{
|
||||
|
||||
/* Wait for character */
|
||||
while ((port->LSR & LSR_RSR)==0);
|
||||
|
||||
return port->RBR;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spiPollWrite(int minor, const char *buf, size_t len)
|
||||
{
|
||||
|
||||
while (len-- > 0) {
|
||||
while (!(port->LSR & LSR_THE));
|
||||
port->THR = *buf++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* enable/disable RTS line to start/stop remote transmitter
|
||||
*/
|
||||
static int
|
||||
spiStartRemoteTx (int minor)
|
||||
{
|
||||
/* Not implemented !
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable (level);
|
||||
port->SPCTL |= CRRts; activate RTS
|
||||
rtems_interrupt_enable (level);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spiStopRemoteTx (int minor)
|
||||
{
|
||||
/* Not implemented !
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable (level);
|
||||
port->SPCTL &= ~CRRts; deactivate RTS
|
||||
rtems_interrupt_enable (level);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t InterruptWrite (int minor, const char *buf, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
port->IER |= IER_XMT; /* always enable tx interrupt */
|
||||
port->THR = *buf; /* write char to send */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static rtems_isr serial_ISR(rtems_vector_number v)
|
||||
{
|
||||
unsigned char _isr;
|
||||
char ch;
|
||||
int res;
|
||||
|
||||
_isr=port->ISR & 0x0E;
|
||||
|
||||
if ((_isr == ISR_Rx) || (_isr==ISR_RxTO)) {
|
||||
ch = port->RBR;
|
||||
rtems_termios_enqueue_raw_characters (spittyp,&ch,1);
|
||||
}
|
||||
|
||||
if (_isr == ISR_Tx) {
|
||||
res = rtems_termios_dequeue_characters (spittyp,1);
|
||||
if (res==0) {
|
||||
port->IER &= ~IER_XMT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* deinit SPI
|
||||
*/
|
||||
static void
|
||||
spiDeInit(void)
|
||||
{
|
||||
/*
|
||||
* disable interrupts for serial port
|
||||
* set it to state to work with polling boot monitor, if any...
|
||||
*/
|
||||
|
||||
/* set up baud rate to original state */
|
||||
spiBaudSet(bsp_serial_rate);
|
||||
|
||||
port->IER = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* init SPI
|
||||
*/
|
||||
static rtems_status_code
|
||||
spiInitialize(void)
|
||||
{
|
||||
register unsigned tmp;
|
||||
rtems_isr_entry previous_isr; /* this is a dummy */
|
||||
unsigned char _ier;
|
||||
|
||||
/*
|
||||
* Initialise the serial port
|
||||
*/
|
||||
|
||||
/*
|
||||
* Select clock source and set uart internal clock divisor
|
||||
*/
|
||||
|
||||
__asm__ volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */
|
||||
|
||||
/* UART0 bit 24 0x80, UART1 bit 25 0x40 */
|
||||
tmp |= (bsp_serial_external_clock ? (USE_UART ? 0x40 : 0x80) : 0);
|
||||
|
||||
tmp |= (bsp_serial_external_clock ? 0: ((UART_INTERNAL_CLOCK_DIVISOR -1) << 1));
|
||||
|
||||
__asm__ volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/
|
||||
|
||||
/* Disable port interrupts while changing hardware */
|
||||
_ier = port->IER;
|
||||
port->IER = 0;
|
||||
|
||||
/* set up port control: 8 bit,1 stop,no parity */
|
||||
port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN;
|
||||
|
||||
/* set up baud rate */
|
||||
spiBaudSet(bsp_serial_rate);
|
||||
|
||||
if (ppc403_spi_interrupt) {
|
||||
|
||||
/* add rx/tx isr to vector table */
|
||||
if (USE_UART==0)
|
||||
ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr);
|
||||
else
|
||||
ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr);
|
||||
|
||||
/* Enable and clear FIFO */
|
||||
port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT8;
|
||||
|
||||
/* Enable recive interrupts, don't enable TxInt yet */
|
||||
port->IER=IER_RCV;
|
||||
}
|
||||
else {
|
||||
port->IER=_ier;
|
||||
}
|
||||
|
||||
atexit(spiDeInit);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
***************
|
||||
* BOILERPLATE *
|
||||
***************
|
||||
*/
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
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
|
||||
*/
|
||||
spiInitialize ();
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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 = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
NULL, /* pollRead */
|
||||
InterruptWrite, /* write */
|
||||
spiSetAttributes, /* setAttributes */
|
||||
spiStopRemoteTx, /* stopRemoteTx */
|
||||
spiStartRemoteTx, /* startRemoteTx */
|
||||
1 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
static const rtems_termios_callbacks pollCallbacks = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
spiPollRead, /* pollRead */
|
||||
spiPollWrite, /* write */
|
||||
spiSetAttributes, /* setAttributes */
|
||||
spiStopRemoteTx, /* stopRemoteTx */
|
||||
spiStartRemoteTx, /* startRemoteTx */
|
||||
0 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
if (ppc403_spi_interrupt) {
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||
spittyp = args->iop->data1;
|
||||
}
|
||||
else {
|
||||
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close entry point
|
||||
*/
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_close (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
)
|
||||
{
|
||||
return rtems_termios_write (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Control entry point
|
||||
*/
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
@@ -1,295 +0,0 @@
|
||||
/* ictrl.c
|
||||
*
|
||||
* This routine installs and handles external interrupt vectors for
|
||||
* PowerPC 403 CPU built-in external interrupt controller
|
||||
*
|
||||
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||
*
|
||||
* COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of IMD not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* IMD makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Modifications for PPC405GP by Dennis Ehlin
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ictrl.h"
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <stdlib.h> /* for atexit() */
|
||||
|
||||
/*
|
||||
* ISR vector table to dispatch external interrupts
|
||||
*/
|
||||
|
||||
rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX];
|
||||
|
||||
/*
|
||||
*
|
||||
* some utilities to access the EXI* registers
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* clear bits in EXISR that have a bit set in mask
|
||||
*/
|
||||
#if defined(ppc405)
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
clr_exisr(uint32_t mask)
|
||||
{
|
||||
__asm__ volatile ("mtdcr 0xC0,%0"::"r" (mask));/*EXISR*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get value of EXISR
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE uint32_t
|
||||
get_exisr(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
__asm__ volatile ("mfdcr %0,0xC0":"=r" (val));/*EXISR*/
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* get value of EXIER
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE uint32_t
|
||||
get_exier(void)
|
||||
{
|
||||
uint32_t val;
|
||||
__asm__ volatile ("mfdcr %0,0xC2":"=r" (val));/*EXIER*/
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* set value of EXIER
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
set_exier(uint32_t val)
|
||||
{
|
||||
__asm__ volatile ("mtdcr 0xC2,%0"::"r" (val));/*EXIER*/
|
||||
}
|
||||
|
||||
#else /* not ppc405 */
|
||||
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
clr_exisr(uint32_t mask)
|
||||
{
|
||||
__asm__ volatile ("mtdcr 0x40,%0"::"r" (mask));/*EXISR*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get value of EXISR
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE uint32_t
|
||||
get_exisr(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
__asm__ volatile ("mfdcr %0,0x40":"=r" (val));/*EXISR*/
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* get value of EXIER
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE uint32_t
|
||||
get_exier(void)
|
||||
{
|
||||
uint32_t val;
|
||||
__asm__ volatile ("mfdcr %0,0x42":"=r" (val));/*EXIER*/
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* set value of EXIER
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
set_exier(uint32_t val)
|
||||
{
|
||||
__asm__ volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
|
||||
}
|
||||
#endif /* ppc405 */
|
||||
/*
|
||||
* enable an external interrupt, make this interrupt consistent
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
enable_ext_irq( uint32_t mask)
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
set_exier(get_exier() | ((mask)&PPC_EXI_MASK));
|
||||
rtems_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/*
|
||||
* disable an external interrupt, make this interrupt consistent
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
disable_ext_irq( uint32_t mask)
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
set_exier(get_exier() & ~(mask) & PPC_EXI_MASK);
|
||||
rtems_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* this function is called, when a external interrupt is present and
|
||||
* enabled but there is no handler installed. It will clear
|
||||
* the corresponding enable bits and call the spurious handler
|
||||
* present in the CPU Configuration Table, if any.
|
||||
*
|
||||
*/
|
||||
void
|
||||
ictrl_spurious_handler(uint32_t spurious_mask,
|
||||
void *cpu_frame)
|
||||
{
|
||||
int v;
|
||||
extern void (*bsp_spurious_handler)(uint32_t vector, void *);
|
||||
|
||||
for (v=0; v < PPC_IRQ_EXT_MAX; v++) {
|
||||
if (VEC_TO_EXMSK(v) & spurious_mask) {
|
||||
clr_exisr(VEC_TO_EXMSK(v));
|
||||
disable_ext_irq(VEC_TO_EXMSK(v));
|
||||
#if 0
|
||||
printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
|
||||
vector, cpu_frame->Interrupt.pcoqfront);
|
||||
#endif
|
||||
if (bsp_spurious_handler()) {
|
||||
bsp_spurious_handler(v + PPC_IRQ_EXT_BASE,cpu_frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ISR Handler: this is called from the primary exception dispatcher
|
||||
*/
|
||||
|
||||
void
|
||||
ictrl_isr(rtems_vector_number vector, void *cpu_frame)
|
||||
{
|
||||
uint32_t istat,
|
||||
mask,
|
||||
global_vec;
|
||||
int exvec;
|
||||
rtems_isr_entry handler;
|
||||
|
||||
istat = get_exisr() & get_exier() & PPC_EXI_MASK;
|
||||
|
||||
/* FIXME: this may be speeded up using cntlzw instruction */
|
||||
for (exvec = 0;exvec < PPC_IRQ_EXT_MAX;exvec++) {
|
||||
mask = VEC_TO_EXMSK(exvec);
|
||||
if (0 != (istat & mask)) {
|
||||
/*clr_exisr(mask); too early to ack*/
|
||||
handler = ictrl_vector_table[exvec];
|
||||
if (handler) {
|
||||
istat &= ~mask;
|
||||
global_vec = exvec + PPC_IRQ_EXT_BASE;
|
||||
(handler)(global_vec);
|
||||
}
|
||||
clr_exisr(mask);/* now we can ack*/
|
||||
}
|
||||
}
|
||||
if (istat != 0) { /* anything left? then we have a spurious interrupt */
|
||||
ictrl_spurious_handler(istat,cpu_frame);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* the following functions form the user interface
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* install a user vector for one of the external interrupt sources
|
||||
*
|
||||
*/
|
||||
rtems_status_code
|
||||
ictrl_set_vector(rtems_isr_entry new_handler,
|
||||
uint32_t vector,
|
||||
rtems_isr_entry *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* We put the actual user ISR address in 'ictrl_vector_table'. This will
|
||||
* be used by the _ictrl_isr so the user gets control.
|
||||
*/
|
||||
|
||||
/* check for valid vector range */
|
||||
if ((vector >= PPC_IRQ_EXT_BASE) &&
|
||||
(vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
|
||||
/* return old handler entry */
|
||||
*old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
|
||||
|
||||
if (new_handler != NULL) {
|
||||
/* store handler function... */
|
||||
ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = new_handler;
|
||||
/* then enable it in EXIER register */
|
||||
enable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
|
||||
}
|
||||
else { /* new_handler == NULL */
|
||||
/* then disable it in EXIER register */
|
||||
disable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
|
||||
ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = NULL;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
else {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called via atexit()
|
||||
* deactivate the interrupt controller
|
||||
*/
|
||||
|
||||
void
|
||||
ictrl_exit(void)
|
||||
{
|
||||
/* mark them all unused */
|
||||
disable_ext_irq(~0);
|
||||
clr_exisr(~0);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* activate the interrupt controller
|
||||
*/
|
||||
|
||||
rtems_status_code
|
||||
ictrl_init(void)
|
||||
{
|
||||
proc_ptr dummy;
|
||||
|
||||
/* mark them all unused */
|
||||
disable_ext_irq(~0);
|
||||
clr_exisr(~0);
|
||||
|
||||
/* install the external interrupt handler */
|
||||
_CPU_ISR_install_vector(PPC_IRQ_EXTERNAL,
|
||||
ictrl_isr,
|
||||
&dummy);
|
||||
atexit(ictrl_exit);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* ictrl.h
|
||||
*
|
||||
* This file contains definitions and declarations for the
|
||||
* PowerPC 403 CPU built-in external interrupt controller
|
||||
*
|
||||
*
|
||||
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||
*
|
||||
* COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
|
||||
*
|
||||
* To anyone who acknowledges that this file is provided "AS IS"
|
||||
* without any express or implied warranty:
|
||||
* permission to use, copy, modify, and distribute this file
|
||||
* for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice and this notice appears in all
|
||||
* copies, and that the name of IMD not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* IMD makes no representations about the suitability
|
||||
* of this software for any purpose.
|
||||
*
|
||||
* Modifications for PPC405GP by Dennis Ehlin
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ICTRL_H
|
||||
#define _ICTRL_H
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* definitions for second level IRQ handler support
|
||||
* External Interrupts via EXTERNAL/EISR
|
||||
*/
|
||||
#define PPC_IRQ_EXT_BASE (PPC_IRQ_LAST+1)
|
||||
|
||||
/* mask for external interrupt status in EXIER/EXISR register */
|
||||
/* note: critical interrupt is in these registers aswell */
|
||||
#ifndef ppc405
|
||||
#define PPC_EXI_MASK 0x0FFFFFFF
|
||||
#else /* ppc405 */
|
||||
#define PPC_EXI_MASK 0xFFFFFFFF
|
||||
#endif /* ppc405 */
|
||||
|
||||
#ifndef ppc405
|
||||
#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
|
||||
#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
|
||||
#else /* ppc405 */
|
||||
#define PPC_IRQ_EXT_UART0 (PPC_IRQ_EXT_BASE+0)
|
||||
#define PPC_IRQ_EXT_UART1 (PPC_IRQ_EXT_BASE+1)
|
||||
#endif /* ppc405 */
|
||||
#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
|
||||
#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
|
||||
#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
|
||||
#define PPC_IRQ_EXT_DMA1 (PPC_IRQ_EXT_BASE+9)
|
||||
#define PPC_IRQ_EXT_DMA2 (PPC_IRQ_EXT_BASE+10)
|
||||
#define PPC_IRQ_EXT_DMA3 (PPC_IRQ_EXT_BASE+11)
|
||||
#define PPC_IRQ_EXT_0 (PPC_IRQ_EXT_BASE+27)
|
||||
#define PPC_IRQ_EXT_1 (PPC_IRQ_EXT_BASE+28)
|
||||
#define PPC_IRQ_EXT_2 (PPC_IRQ_EXT_BASE+29)
|
||||
#define PPC_IRQ_EXT_3 (PPC_IRQ_EXT_BASE+30)
|
||||
#define PPC_IRQ_EXT_4 (PPC_IRQ_EXT_BASE+31)
|
||||
|
||||
#define PPC_IRQ_EXT_MAX (32)
|
||||
|
||||
#define VEC_TO_EXMSK(v) (0x80000000 >> (v))
|
||||
|
||||
/*
|
||||
*
|
||||
* install a user vector for one of the external interrupt sources
|
||||
*
|
||||
*/
|
||||
rtems_status_code
|
||||
ictrl_set_vector(rtems_isr_entry new_handler,
|
||||
uint32_t vector,
|
||||
rtems_isr_entry *old_handler
|
||||
);
|
||||
/*
|
||||
* activate the interrupt controller
|
||||
*/
|
||||
rtems_status_code
|
||||
ictrl_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ICTRL_H */
|
||||
/* end of include file */
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
* This file contains the PowerPC 405GP tty driver.
|
||||
*
|
||||
* Derived from /c/src/lib/libbsp/i386/shared/comm/tty_drv.c
|
||||
*
|
||||
* Modifications to PPC405GP by Dennis Ehlin
|
||||
*
|
||||
*/
|
||||
|
||||
#define NO_BSP_INIT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <termios.h>
|
||||
#include <assert.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include "../irq/ictrl.h"
|
||||
#include <stdlib.h> /* for atexit() */
|
||||
#include <tty_drv.h>
|
||||
|
||||
extern uint32_t bsp_serial_per_sec;
|
||||
extern bool bsp_serial_external_clock;
|
||||
extern bool bsp_serial_cts_rts;
|
||||
extern bool bsp_serial_xon_xoff;
|
||||
extern uint32_t bsp_serial_rate;
|
||||
|
||||
struct ttyasync {
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Data Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char RBR; /* 0x00 */
|
||||
#define THR RBR
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Interrupt registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char IER; /* Interrupt Enable Register 0x01 */
|
||||
#define IER_RCV 0x01
|
||||
#define IER_XMT 0x02
|
||||
#define IER_LS 0x04
|
||||
#define IER_MS 0x08
|
||||
|
||||
unsigned char ISR; /* Interrupt Status Register 0x02 */
|
||||
#define ISR_MS 0x00
|
||||
#define ISR_nIP 0x01
|
||||
#define ISR_Tx 0x02
|
||||
#define ISR_Rx 0x04
|
||||
#define ISR_LS 0x06
|
||||
#define ISR_RxTO 0x0C
|
||||
#define ISR_64BFIFO 0x20
|
||||
#define ISR_FIFOworks 0x40
|
||||
#define ISR_FIFOen 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| FIFO Control registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define FCR ISR
|
||||
#define FCR_FE 0x01 /* FIFO enable */
|
||||
#define FCR_CRF 0x02 /* Clear receive FIFO */
|
||||
#define FCR_CTF 0x04 /* Clear transmit FIFO */
|
||||
#define FCR_DMA 0x08 /* DMA mode select */
|
||||
#define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */
|
||||
#define FCR_RT14 0xC0 /* Set Rx trigger at 14 */
|
||||
#define FCR_RT8 0x80 /* Set Rx trigger at 8 */
|
||||
#define FCR_RT4 0x40 /* Set Rx trigger at 4 */
|
||||
#define FCR_RT1 0x00 /* Set Rx trigger at 1 */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Baud rate divisor registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define DLL RBR
|
||||
#define DLM IER
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Alternate function registers
|
||||
+---------------------------------------------------------------------------*/
|
||||
#define AFR ISR
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Line control Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char LCR; /* 0x03 */
|
||||
#define LCR_WL5 0x00 /* Word length 5 */
|
||||
#define LCR_WL6 0x01 /* Word length 6 */
|
||||
#define LCR_WL7 0x02 /* Word length 7 */
|
||||
#define LCR_WL8 0x03 /* Word length 8 */
|
||||
|
||||
#define LCR_SB1 0x00 /* 1 stop bits */
|
||||
#define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/
|
||||
#define LCR_SB1_5 0x04 /* 2 stop bits */
|
||||
|
||||
#define LCR_PN 0x00 /* Parity NONE */
|
||||
#define LCR_PE 0x0C /* Parity EVEN */
|
||||
#define LCR_PO 0x08 /* Parity ODD */
|
||||
#define LCR_PM 0x28 /* Forced "mark" parity */
|
||||
#define LCR_PS 0x38 /* Forced "space" parity */
|
||||
|
||||
#define LCR_DL 0x80 /* Enable baudrate latch */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Modem control Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char MCR; /* 0x04 */
|
||||
#define MCR_DTR 0x01
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_INT 0x08 /* Enable interrupts */
|
||||
#define MCR_LOOP 0x10 /* Loopback mode */
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Line status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char LSR; /* 0x05 */
|
||||
#define LSR_RSR 0x01
|
||||
#define LSR_OE 0x02
|
||||
#define LSR_PE 0x04
|
||||
#define LSR_FE 0x08
|
||||
#define LSR_BI 0x10
|
||||
#define LSR_THE 0x20
|
||||
#define LSR_TEMT 0x40
|
||||
#define LSR_FIE 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Modem status Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char MSR; /* 0x06 */
|
||||
#define UART_MSR_DCTS 0x01
|
||||
#define UART_MSR_DDSR 0x02
|
||||
#define UART_MSR_TERI 0x04
|
||||
#define UART_MSR_DDCD 0x08
|
||||
#define UART_MSR_CTS 0x10
|
||||
#define UART_MSR_DSR 0x20
|
||||
#define UART_MSR_RI 0x40
|
||||
#define UART_MSR_CD 0x80
|
||||
|
||||
/*---------------------------------------------------------------------------+
|
||||
| Scratch pad Register.
|
||||
+---------------------------------------------------------------------------*/
|
||||
unsigned char SCR; /* 0x07 */
|
||||
};
|
||||
|
||||
|
||||
#define TTY0_USE_UART 1 /* 0=UART0 1=UART1 */
|
||||
#define TTY0_UART_INTERNAL_CLOCK_DIVISOR 16
|
||||
#define TTY0_USE_INTERRUPT
|
||||
|
||||
|
||||
typedef volatile struct ttyasync *tty0pasync;
|
||||
static const tty0pasync tty0port = (tty0pasync)(0xEF600300 + (TTY0_USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */
|
||||
|
||||
static void *tty0ttyp; /* handle for termios */
|
||||
|
||||
|
||||
static int
|
||||
tty0_round(double x)
|
||||
{
|
||||
return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x);
|
||||
}
|
||||
|
||||
static void
|
||||
tty0BaudSet(uint32_t baudrate)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = tty0_round( (double)bsp_serial_per_sec / (baudrate * 16) );
|
||||
|
||||
tty0port->LCR = tty0port->LCR | LCR_DL;
|
||||
|
||||
tty0port->DLL = tmp & 0xff;
|
||||
tty0port->DLM = tmp >> 8;
|
||||
|
||||
tty0port->LCR = tty0port->LCR & ~LCR_DL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware-dependent portion of tcsetattr().
|
||||
*/
|
||||
static int
|
||||
tty0SetAttributes (int minor, const struct termios *t)
|
||||
{
|
||||
int baud;
|
||||
|
||||
/* FIXME: check c_cflag & CRTSCTS for hardware flow control */
|
||||
/* FIXME: check and IMPLEMENT XON/XOFF */
|
||||
switch (t->c_ospeed) {
|
||||
default: baud = -1; break;
|
||||
case B50: baud = 50; break;
|
||||
case B75: baud = 75; break;
|
||||
case B110: baud = 110; break;
|
||||
case B134: baud = 134; break;
|
||||
case B150: baud = 150; break;
|
||||
case B200: baud = 200; break;
|
||||
case B300: baud = 300; break;
|
||||
case B600: baud = 600; break;
|
||||
case B1200: baud = 1200; break;
|
||||
case B1800: baud = 1800; break;
|
||||
case B2400: baud = 2400; break;
|
||||
case B4800: baud = 4800; break;
|
||||
case B9600: baud = 9600; break;
|
||||
case B19200: baud = 19200; break;
|
||||
case B38400: baud = 38400; break;
|
||||
case B57600: baud = 57600; break;
|
||||
case B115200: baud = 115200; break;
|
||||
case B230400: baud = 230400; break;
|
||||
case B460800: baud = 460800; break;
|
||||
}
|
||||
if (baud > 0) {
|
||||
tty0BaudSet(baud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef TTY0_USE_INTERRUPT
|
||||
static int
|
||||
tty0PollRead (int minor)
|
||||
{
|
||||
|
||||
/* Wait for character */
|
||||
while ((tty0port->LSR & LSR_RSR)==0);
|
||||
|
||||
return tty0port->RBR;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
tty0PollWrite(int minor, const char *buf, size_t len)
|
||||
{
|
||||
|
||||
while (len-- > 0) {
|
||||
while (!(tty0port->LSR & LSR_THE));
|
||||
tty0port->THR = *buf++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ================ Termios support =================*/
|
||||
|
||||
static ssize_t tty0InterruptWrite (int minor, const char *buf, size_t len)
|
||||
{
|
||||
|
||||
if(len <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write character */
|
||||
|
||||
tty0port->THR = (*buf &0xff);
|
||||
tty0port->IER |= IER_XMT; /* always enable tx interrupt */
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static rtems_isr tty0serial_ISR(rtems_vector_number v)
|
||||
{
|
||||
char buf[128];
|
||||
int off, ret, vect;
|
||||
|
||||
off = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
vect = tty0port->ISR & 0x0f;
|
||||
if(vect & 1)
|
||||
{
|
||||
/* no more interrupts */
|
||||
if(off > 0) {
|
||||
/* Update rx buffer */
|
||||
rtems_termios_enqueue_raw_characters(tty0ttyp, buf, off );
|
||||
|
||||
tty0port->IER |= IER_RCV; /* always enable rx interrupt */
|
||||
/*rtems_termios_rxirq_occured(tty0ttyp);*/
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vect = vect & 0xe; /*mask out all except interrupt pending*/
|
||||
|
||||
switch(vect)
|
||||
{
|
||||
|
||||
case ISR_Tx :
|
||||
/*
|
||||
* TX holding empty: we have to disable these interrupts
|
||||
* if there is nothing more to send.
|
||||
*/
|
||||
|
||||
/* If nothing else to send disable interrupts */
|
||||
ret = rtems_termios_dequeue_characters(tty0ttyp, 1);
|
||||
|
||||
if ( ret == 0 ) {
|
||||
tty0port->IER &= ~IER_XMT;
|
||||
}
|
||||
|
||||
break;
|
||||
case ISR_RxTO:
|
||||
case ISR_Rx :
|
||||
|
||||
/* disable interrupts and notify termios */
|
||||
tty0port->IER &= ~IER_RCV;
|
||||
|
||||
/* read all bytes in fifo*/
|
||||
while (( off < sizeof(buf) ) && ( tty0port->LSR & LSR_RSR ))
|
||||
{
|
||||
buf[off++] = tty0port->RBR;
|
||||
}
|
||||
|
||||
break;
|
||||
case ISR_LS:
|
||||
/* RX error: eat character */
|
||||
/* printk("********* Error **********\n"); */
|
||||
break;
|
||||
default:
|
||||
/* Should not happen */
|
||||
/* printk("error vect=%x",vect); */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* deinit TTY0
|
||||
*
|
||||
*/
|
||||
static void tty0DeInit(void)
|
||||
{
|
||||
/*
|
||||
* disable interrupts for serial tty0port
|
||||
* set it to state to work with polling boot monitor, if any...
|
||||
*/
|
||||
|
||||
/* set up baud rate to original state */
|
||||
tty0BaudSet(bsp_serial_rate);
|
||||
|
||||
tty0port->IER = 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* init SPI
|
||||
*
|
||||
*/
|
||||
static rtems_status_code
|
||||
tty0Initialize(void)
|
||||
{
|
||||
register unsigned tmp;
|
||||
rtems_isr_entry previous_isr; /* this is a dummy */
|
||||
unsigned char _ier;
|
||||
unsigned char _tmp;
|
||||
|
||||
/*
|
||||
* Initialise the serial tty0port
|
||||
*/
|
||||
|
||||
/*
|
||||
* Select clock source and set uart internal clock divisor
|
||||
*/
|
||||
|
||||
__asm__ volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */
|
||||
|
||||
/* UART0 bit 24 0x80, UART1 bit 25 0x40 */
|
||||
tmp |= (bsp_serial_external_clock ? (TTY0_USE_UART ? 0x40 : 0x80) : 0);
|
||||
|
||||
tmp |= (bsp_serial_external_clock ? 0: ((TTY0_UART_INTERNAL_CLOCK_DIVISOR -1) << 1));
|
||||
|
||||
__asm__ volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/
|
||||
|
||||
/* Disable tty0port interrupts while changing hardware */
|
||||
_ier = tty0port->IER;
|
||||
(void) _ier; /* avoid set but not used warning */
|
||||
tty0port->IER = 0;
|
||||
|
||||
/* set up tty0port control: 8 bit,1 stop,no parity */
|
||||
tty0port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN;
|
||||
|
||||
/* set up baud rate */
|
||||
tty0BaudSet(bsp_serial_rate);
|
||||
|
||||
|
||||
#ifdef TTY0_USE_INTERRUPT
|
||||
|
||||
/* add rx/tx isr to vector table */
|
||||
|
||||
if (TTY0_USE_UART==0)
|
||||
ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr);
|
||||
else
|
||||
ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr);
|
||||
|
||||
/* Enable and clear FIFO */
|
||||
tty0port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT14;
|
||||
|
||||
/* Read status to clear them */
|
||||
_tmp = tty0port->LSR;
|
||||
_tmp = tty0port->RBR;
|
||||
_tmp = tty0port->MSR;
|
||||
(void) _tmp; /* avoid set but not used warning */
|
||||
|
||||
/* Enable recive interrupts, don't enable TxInt yet */
|
||||
tty0port->IER=IER_RCV;
|
||||
|
||||
#else
|
||||
|
||||
tty0port->IER=_ier;
|
||||
|
||||
#endif
|
||||
|
||||
atexit(tty0DeInit);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
***************
|
||||
* BOILERPLATE *
|
||||
***************
|
||||
*/
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values:
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_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
|
||||
*/
|
||||
|
||||
/*tty0Initialize (); Moved this to open instead */
|
||||
|
||||
/*
|
||||
* Register the device
|
||||
*/
|
||||
status = rtems_io_register_name ("/dev/ttyS0", major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred (status);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
#ifdef TTY0_USE_INTERRUPT
|
||||
|
||||
static const rtems_termios_callbacks intrCallbacks = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
NULL, /* pollRead */
|
||||
tty0InterruptWrite, /* write */
|
||||
tty0SetAttributes, /* setAttributes */
|
||||
NULL, /* stopRemoteTx */
|
||||
NULL, /* startRemoteTx */
|
||||
TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */
|
||||
};
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
|
||||
tty0Initialize (); /* Initalize hardware */
|
||||
|
||||
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
|
||||
tty0ttyp = args->iop->data1;
|
||||
|
||||
#else
|
||||
|
||||
static const rtems_termios_callbacks pollCallbacks = {
|
||||
NULL, /* firstOpen */
|
||||
NULL, /* lastClose */
|
||||
tty0PollRead, /* pollRead */
|
||||
tty0PollWrite, /* write */
|
||||
tty0SetAttributes, /* setAttributes */
|
||||
NULL, /* stopRemoteTx */
|
||||
NULL, /* startRemoteTx */
|
||||
0 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
tty0Initialize (); /* Initalize hardware */
|
||||
|
||||
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
|
||||
|
||||
#endif
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_close (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* read bytes from the serial port. We only have stdin.
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* write bytes to the serial port. Stdout and stderr are the same.
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_write (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Control entry point
|
||||
*/
|
||||
|
||||
rtems_device_driver tty0_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The location of the vectors file object is critical.
|
||||
|
||||
From the comments at the head of vectors.s:
|
||||
|
||||
The issue with this file is getting it loaded at the right place.
|
||||
The first vector MUST be at address 0x????0100.
|
||||
How this is achieved is dependant on the tool chain.
|
||||
|
||||
However the basic mechanism for ELF assemblers is to create a
|
||||
section called ".vectors", which will be loaded to an address
|
||||
between 0x????0000 and 0x????0100 (inclusive) via a link script.
|
||||
|
||||
The basic mechanism for XCOFF assemblers is to place it in the
|
||||
normal text section, and arrange for this file to be located
|
||||
at an appropriate position on the linker command line.
|
||||
|
||||
The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
|
||||
offset from 0x????0000 to the first location in the file. This
|
||||
will usually be 0x0000 or 0x0100.
|
||||
|
||||
Andrew Bray 18/8/1995
|
||||
Reference in New Issue
Block a user