Console for gen68360
Jake Janovetz
janovetz at tempest.ece.uiuc.edu
Tue Apr 18 15:55:15 UTC 2000
Here's a copy of my SCC4 console stuff. It is largely based on
Eric's console driver and has tracked most of its changes.
Cheers,
Jake
On Tue, Apr 18, 2000 at 05:44:03PM +0200, gerke.kok at ascom.nl wrote:
> Hello,
> we here are trying to port the gen68360 RTEMS 4.0 to our boards. On these
> boards the SMC1 channel is not available to function as console.
> Is there anybody that has a implementation for this console driver for a SCC
> channel? We would be much ablidged.
> wkr,
> Gerke
--
janovetz at uiuc.edu | How can it be that mathematics, being after all a
University of Illinois | product of human thought independent of experience,
| is so admirably adapted to the objects of reality?
PP-ASEL | - Albert Einstein
Disclaimer: The policies of this University certainly do not reflect my
own opinions, objectives, or agenda.
-------------- next part --------------
/**************************************************************************
* console.c *
**************************************************************************
* Description: *
* *
* This file contains the low level driver routines for the console *
* device. This includes initialization and I/O routines. The *
* console for Cantante is a UART on SCC4 at 38400 baud. Most of *
* the routines are null routines because they aren't directly *
* applicable. *
* *
* Pin connections for the 68360 UARTs (CTS and RTS are not used) *
* PA4 (RXD3) <---> UART 1 Receive (remote) *
* PA5 (TXD3) <---> UART 1 Transmit (remote) *
* PA6 (RXD4) <---> UART 2 Receive (console) *
* PA7 (TXD4) <---> UART 2 Transmit (console) *
* *
* *
* The public routines contained in this file are: *
* *
* console_initialize - Initializes the UART and the console device. *
* console_read - Read data from the console. *
* console_write - Write data to the console. *
* console_open - Open the console device. *
* console_close - Close the console device. *
* console_control - Configure the device. *
* *
* *
* The private routines contained in this file are: *
* *
* is_character_ready - TRUE if a character is ready on the input. *
* outbyte - Output a single character. *
* inbyte - Wait for (and read) a single character. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
* 11/03/97 - Added a receiver FIFO and receiver interrupts. (JWJ) *
* 04/01/98 - Updated to work with termios. (JWJ) *
*************************************************************************/
#include <termios.h>
#include <bsp.h>
#include <rtems/libio.h>
#include "m68360.h"
#define RX_BUF_SIZE 16
/*
* Interrupt-driven callback
*/
static int m360_scc4_interrupt = 1;
static void *scc4ttyp;
int m360_clock_rate = 25000000;
static volatile char rx4Buf[RX_BUF_SIZE];
static volatile m360BufferDescriptor_t *scc4RxBd, *scc4TxBd;
/**************************************************************************
* Function: scc4InterruptHandler *
**************************************************************************
* Description: *
* *
* This is the interrupt service routine for the console UART. It *
* handles both receive and transmit interrupts. The bulk of the *
* work is done by termios. *
* *
* *
* Inputs: *
* *
* rtems_vector_number v - Not used. *
* *
* Output: *
* *
* none *
* *
**************************************************************************
* Change History: *
* 11/03/97 - Creation (JWJ) *
*************************************************************************/
static rtems_isr
scc4InterruptHandler(rtems_vector_number v)
{
/***********************************************************************
* Handle a RX interrupt.
**********************************************************************/
if (m360.scc4.scce & 0x1)
{
m360.scc4.scce = 0x1;
while ((scc4RxBd->status & M360_BD_EMPTY) == 0)
{
rtems_termios_enqueue_raw_characters(scc4ttyp,
(char *)scc4RxBd->buffer,
scc4RxBd->length);
scc4RxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
}
}
/***********************************************************************
* Handle a TX interrupt.
**********************************************************************/
if (m360.scc4.scce & 0x2)
{
m360.scc4.scce = 0x2;
if ((scc4TxBd->status & M360_BD_EMPTY) == 0)
{
rtems_termios_dequeue_characters(scc4ttyp, scc4TxBd->length);
}
}
/***********************************************************************
* Clear SCC4 interrupt-in-service bit.
**********************************************************************/
m360.cisr = 1UL << 27;
}
/* I don't support polled I/O yet
static int
scc4PollRead(int minor)
{
unsigned char c;
if (scc4RxBd->status & M360_BD_EMPTY)
{
return(-1);
}
c = rx4Buf[0];
scc4RxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
return(c);
}
*/
/**************************************************************************
* Function: scc4InterruptWrite *
**************************************************************************
* Description: *
* *
* This is the routine called by termios to perform a write. It *
* copies the character into the transmit buffer, then causes an *
* interrupt to take care of the transfer. *
* *
* *
* Inputs: *
* *
* int minor - Device minor number (not used). *
* const char *buf - Pointer to buffer to be sent. *
* int len - Length of buffer to send. *
* *
* Output: *
* *
* none *
* *
**************************************************************************
* Change History: *
* 11/03/97 - Creation (JWJ) *
*************************************************************************/
static int
scc4InterruptWrite(int minor, const char *buf, int len)
{
scc4TxBd->buffer = (char *)buf;
scc4TxBd->length = len;
scc4TxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT;
return(0);
}
/**************************************************************************
* Function: scc4BRGC *
**************************************************************************
* Description: *
* *
* This function is called to compute the divisor register values for *
* a given baud rate. *
* *
* *
* Inputs: *
* *
* int baud - Baud rate (in bps). *
* *
* Output: *
* *
* int - baud rate generator configuration. *
* *
**************************************************************************
* Change History: *
* 08/20/1999 - Creation (JWJ) *
*************************************************************************/
static int
scc4BRGC(int baud)
{
int divisor;
int div16;
div16 = 0;
divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud;
if (divisor > 4096)
{
div16 = 1;
divisor = (divisor + 8) / 16;
}
return(M360_BRG_EN | M360_BRG_EXTC_BRGCLK |
((divisor - 1) << 1) | div16);
}
/**************************************************************************
* Function: scc4SetAttributes *
**************************************************************************
* Description: *
* *
* This function is called to configure the attributes of the device. *
* *
* *
* Inputs: *
* *
* int minor - Minor number of the device. *
* struct termios *t - termios structure. *
* *
* Output: *
* *
* 0 (successful) *
* *
**************************************************************************
* Change History: *
* 08/20/1999 - Creation (JWJ) *
*************************************************************************/
static int
scc4SetAttributes(int minor, const struct termios *t)
{
int baud;
switch (t->c_cflag & CBAUD)
{
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;
default: baud = -1; break;
}
if (baud > 0)
{
m360.brgc4 = scc4BRGC(baud);
}
return(0);
}
/**************************************************************************
* Function: sccInitialize *
**************************************************************************
* Description: *
* *
* Initialize the SCC as a UART. This is where the low-level *
* initialization is done. *
* *
* *
* Inputs: *
* *
* none *
* *
* Output: *
* *
* none *
* *
**************************************************************************
* Change History: *
* 11/03/97 - Creation (JWJ) *
*************************************************************************/
static void
sccInitialize()
{
rtems_isr_entry old_handler;
rtems_status_code sc;
/***********************************************************************
* Allocate buffer descriptors.
**********************************************************************/
scc4RxBd = M360AllocateBufferDescriptors(1);
scc4TxBd = M360AllocateBufferDescriptors(1);
/***********************************************************************
* Configure Port A pins 6-7 as SCC UARTs.
**********************************************************************/
m360.papar |= 0x00c0;
m360.padir &= ~0x00c0;
m360.paodr &= ~0x00c0;
/***********************************************************************
* Configure BRG4 for SCC4 at 38400 baud.
**********************************************************************/
m360.brgc4 = M360_BRG_RST;
m360.brgc4 = scc4BRGC(38400);
/***********************************************************************
* Connect BRG4 to SCC4
**********************************************************************/
m360.sicr &= 0x00ffffff;
m360.sicr |= (3 << 27) | (3 << 24);
/***********************************************************************
* Configure the SCC parameter RAM common to all protocols.
**********************************************************************/
m360.scc4p.rbase = (char *)scc4RxBd - (char *)&m360;
m360.scc4p.tbase = (char *)scc4TxBd - (char *)&m360;
m360.scc4p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
m360.scc4p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
m360.scc4p.mrblr = RX_BUF_SIZE;
/***********************************************************************
* Configure the SCC parameter RAM specific to UART.
**********************************************************************/
m360.scc4p.un.uart.max_idl = 10;
m360.scc4p.un.uart.brklen = 0;
m360.scc4p.un.uart.brkec = 0;
m360.scc4p.un.uart.brkcr = 0;
/***********************************************************************
* Set up the receive buffer descriptors
**********************************************************************/
scc4RxBd->status = M360_BD_EMPTY | M360_BD_INTERRUPT | M360_BD_WRAP;
scc4RxBd->length = 0;
scc4RxBd->buffer = rx4Buf;
/***********************************************************************
* Set up the transmit buffer descriptors
**********************************************************************/
scc4TxBd->status = M360_BD_WRAP;
/***********************************************************************
* Tell the RISC controller to initialize TX/RX on SCC4 & SCC3.
**********************************************************************/
M360ExecuteRISC(M360_CR_CHAN_SCC4 | M360_CR_OP_INIT_RX_TX);
/***********************************************************************
* Install the interrupt service routine.
**********************************************************************/
sc = rtems_interrupt_catch(scc4InterruptHandler, (m360.cicr & 0xe0) | 0x1b,
&old_handler);
/***********************************************************************
* Setup SCC mode registers
* - Clear any previous interrupt events.
* - Disable interrupts.
* - Enable TX and RX interrupts.
**********************************************************************/
m360.scc4.scce = ~0x0000;
m360.scc4.sccm = 0x0003;
m360.cimr |= 0x08000000;
/***********************************************************************
* Setup the GSMR
**********************************************************************/
m360.scc4.gsmr_h = 0x00000020;
m360.scc4.gsmr_l = 0x00028004;
/***********************************************************************
* Setup the PSMR (asynchronous 8-n-1, no CTS)
**********************************************************************/
m360.scc4.psmr = 0xb000;
/***********************************************************************
* Now, enable the transmitter and receiver
**********************************************************************/
m360.scc4.gsmr_l = 0x00028034;
}
/**************************************************************************
* Function: console_initialize *
**************************************************************************
* Description: *
* *
* Initializes the console device by configuring the SCC as a UART. *
* Also registers the device as /dev/console. *
* *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code sc;
rtems_termios_initialize();
sccInitialize();
sc = rtems_io_register_name("/dev/console", major,
(rtems_device_minor_number)0);
if (sc != RTEMS_SUCCESSFUL)
{
rtems_fatal_error_occurred(sc);
}
return(RTEMS_SUCCESSFUL);
}
/**************************************************************************
* Function: console_open *
**************************************************************************
* Description: *
* *
* Opens the console device. (Here, we just call termios to open *
* things up.) *
* *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code sc;
rtems_libio_open_close_args_t *args = arg;
static const rtems_termios_callbacks intrCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
NULL, /* pollRead */
scc4InterruptWrite, /* write */
scc4SetAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
static const rtems_termios_callbacks pollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
NULL, /* pollRead */
NULL, /* write */
scc4SetAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
if (m360_scc4_interrupt)
{
sc = rtems_termios_open(major, minor, arg, &intrCallbacks);
scc4ttyp = args->iop->data1;
}
else
{
sc = rtems_termios_open(major, minor, arg, &pollCallbacks);
}
return(sc);
}
/**************************************************************************
* Function: console_close *
**************************************************************************
* Description: *
* *
* Close the console device. (wrap the termios_close) *
* *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return(rtems_termios_close(arg));
}
/**************************************************************************
* Function: console_read *
**************************************************************************
* Description: *
* *
* Read from the console device. (wrap the termios_read) *
* *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return(rtems_termios_read(arg));
}
/**************************************************************************
* Function: console_write *
**************************************************************************
* Description: *
* *
* Write to the console device. (wrap the termios_write) *
* *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return(rtems_termios_write(arg));
}
/**************************************************************************
* Function: console_control *
* *
* Copyright (c) 1997 Jake Janovetz *
**************************************************************************
* Description: *
* *
* Nothing is done here yet... *
* *
* Inputs: *
* *
* rtems_device_major_number major - Major number of the device. *
* rtems_device_minor_number minor - Minor number of the device. *
* void *arg - Arguments. *
* *
* Output: *
* *
* rtems_device_driver - Return code of the function. *
* *
**************************************************************************
* Change History: *
* 10/31/97 - Creation (JWJ) *
*************************************************************************/
rtems_device_driver console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return(rtems_termios_ioctl(arg));
}
More information about the users
mailing list