OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [powerpc/] [ppc403/] [console/] [console.c.polled] - Rev 690

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *  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-1999.
 *  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.OARcorp.com/rtems/license.html.
 *
 *  $Id: console.c.polled,v 1.2 2001-09-27 12:01:30 chris Exp $
 */

#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;

  /* Initialise the serial port */
  asm volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
  tmp &= ~3;
  tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 2 : 0) |
      (rtems_cpu_configuration_get_serial_cts_rts() ? 1 : 0);
  asm volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
  port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
         LSRParityError | LSRBreakInterrupt);
  tmp = rtems_cpu_configuration_get_serial_per_sec() /
          rtems_cpu_configuration_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:
 */

rtems_boolean 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;

  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 (rtems_cpu_configuration_get_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;
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.