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