summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/sh/sh7045/sci/sci.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-18 21:22:58 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-18 21:22:58 +0000
commit4a238002e71ec018723229f8669363a5ffb7302e (patch)
treefc5a57faf9a30225bd1f3fa2d713b85815cb77ef /c/src/lib/libcpu/sh/sh7045/sci/sci.c
parentCorrected to include extra arguments for simulators on sparc (diff)
downloadrtems-4a238002e71ec018723229f8669363a5ffb7302e.tar.bz2
Patch from "John M. Mills" <jmills@tga.com> with subsequent cleanup from
Ralf Corsepius <corsepiu@faw.uni-ulm.de> that adds initial Hitachi SH-2 support to RTEMS. Ralf's comments are: Changes: ------ 1. SH-Port: * Many files renamed. * CONSOLE_DEVNAME and MHZ defines removed from libcpu. * console.c moved to libbsp/sh/shared, build in libbsp/sh/<BSP>/console applying VPATH. * CONSOLE_DEVNAME made BSP-specific, replacement is defined in bsp.h * MHZ define replaced with HZ (extendent resolution) in custom/*.cfg * -DHZ=HZ used in bspstart.c, only * Makefile variable HZ used in bsp-dependent directories only. 2. SH1-Port * clock-driver rewritten to provide better resolution for odd CPU frequencies. This driver is only partially tested on hardware, ie. sightly experimental, but I don't expect severe problems with it. * Polling SCI-driver added. This driver is experimental and completly untested yet. Therefore it is not yet used for the console (/dev/console is still pointing to /dev/null, cf. gensh1/bsp.h). * minor changes to the timer driver * SH1 specific delay()/CPU_delay() now is implemented as a function 3. SH2-Port * Merged * IMO, the code is still in its infancy. Therefore I have interspersed comments (FIXME) it for items which I think John should look after. * sci and console drivers partially rewritten and extended (John, I hope you don't mind). * Copyright notices are not yet adapted
Diffstat (limited to 'c/src/lib/libcpu/sh/sh7045/sci/sci.c')
-rw-r--r--c/src/lib/libcpu/sh/sh7045/sci/sci.c384
1 files changed, 384 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/sh/sh7045/sci/sci.c b/c/src/lib/libcpu/sh/sh7045/sci/sci.c
new file mode 100644
index 0000000000..4a50abc803
--- /dev/null
+++ b/c/src/lib/libcpu/sh/sh7045/sci/sci.c
@@ -0,0 +1,384 @@
+/*
+ * /dev/sci[0|1] for Hitachi SH 704X
+ *
+ * The SH doesn't have a designated console device. Therefore we "alias"
+ * another device as /dev/console and revector all calls to /dev/console
+ * to this device.
+ *
+ * This approach is similar to installing a sym-link from one device to
+ * another device. If rtems once will support sym-links for devices files,
+ * this implementation could be dropped.
+ *
+ * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * COPYRIGHT (c) 1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * 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.
+ *
+ * Modified to reflect sh7045 processor:
+ * John M. Mills (jmills@tga.com)
+ * TGA Technologies, Inc.
+ * 100 Pinnacle Way, Suite 140
+ * Norcross, GA 30071 U.S.A.
+ *
+ * This modified file may be copied and distributed in accordance
+ * the above-referenced license. It is provided for critique and
+ * developmental purposes without any warranty nor representation
+ * by the authors or by TGA Technologies.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#include <stdlib.h>
+
+#include <rtems/libio.h>
+#include <iosupp.h>
+#include <rtems/score/sh_io.h>
+#include <rtems/score/ispsh7045.h>
+#include <rtems/score/iosh7045.h>
+#include <sh/sh7_sci.h>
+#include <sh/io_types.h>
+#include <sh/sci.h>
+
+struct scidev_t {
+ char * name ;
+ rtems_device_minor_number minor ;
+ unsigned short opened ;
+ tcflag_t cflags ;
+} sci_device[2] =
+{
+ { "/dev/sci0", 0, 0, B9600 | CS8 },
+ { "/dev/sci1", 0, 0, B9600 | CS8 }
+} ;
+
+/* local data structures maintain hardware configuration */
+extern int _sci_get_brparms(
+ tcflag_t cflag,
+ unsigned char *smr,
+ unsigned char *brr );
+
+#if UNUSED
+static sci_setup_t sio_param[2];
+#endif
+
+/* local functions operate SCI ports 0 and 1 */
+/* called from polling routines or ISRs */
+rtems_boolean wrtSCI0(unsigned char ch)
+{
+ unsigned8 temp;
+ rtems_boolean result=FALSE;
+
+ if ((read8(SCI_SSR0) & SCI_TDRE) != 0x00) {
+ /* Write the character to the TDR */
+ write8(ch, SCI_TDR0);
+ /* Clear the TDRE bit */
+ temp = read8(SCI_SSR0) & ~SCI_TDRE;
+ write8(temp, SCI_SSR0);
+ result = TRUE;
+ }
+ return result;
+} /* wrtSCI0 */
+
+rtems_boolean wrtSCI1(unsigned char ch)
+{
+ unsigned8 temp;
+ rtems_boolean result=FALSE;
+
+ if ((read8(SCI_SSR1) & SCI_TDRE) != 0x00) {
+ /* Write the character to the TDR */
+ write8(ch, SCI_TDR1);
+ /* Clear the TDRE bit */
+ temp = read8(SCI_SSR1) & ~SCI_TDRE;
+ write8(temp, SCI_SSR1);
+ result = TRUE;
+ }
+ return result;
+} /* wrtSCI1 */
+
+/* polled output steers byte to selected port */
+void sh_sci_outbyte_polled(
+ rtems_device_minor_number minor,
+ char ch )
+{
+ if (minor == 0) /* blocks until port ready */
+ while (wrtSCI0(ch) != TRUE); /* SCI0*/
+ else
+ while (wrtSCI1(ch) != TRUE); /* SCI1*/
+} /* sh_sci_outbyte_polled */
+
+/* Initial version calls polled output driver and blocks */
+void outbyte(
+ rtems_device_minor_number minor,
+ char ch)
+{
+ sh_sci_outbyte_polled(minor, (unsigned char)ch);
+} /* outbyte */
+
+rtems_boolean rdSCI0(unsigned char *ch)
+{
+ unsigned8 temp;
+ rtems_boolean result=FALSE;
+
+ if ((read8(SCI_SSR0) & SCI_RDRF) != 0x00) {
+ /* Write the character to the TDR */
+ write8(*ch, SCI_RDR0);
+ /* Clear the TDRE bit */
+ temp = read8(SCI_SSR0) & ~SCI_RDRF;
+ write8(temp, SCI_SSR0);
+ result = TRUE;
+ }
+ return result;
+} /* rdSCI0 */
+
+rtems_boolean rdSCI1(unsigned char *ch)
+{
+ unsigned8 temp;
+ rtems_boolean result=FALSE;
+
+ if ((read8(SCI_SSR1) & SCI_RDRF) != 0x00) {
+ /* Write the character to the TDR */
+ write8(*ch, SCI_RDR1);
+ /* Clear the TDRE bit */
+ temp= read8(SCI_SSR1) & ~SCI_RDRF;
+ write8(temp, SCI_SSR1);
+ result = TRUE;
+ }
+ return result;
+} /* rdSCI1 */
+
+
+/* initial version pulls byte from selected port */
+char sh_sci_inbyte_polled(
+ rtems_device_minor_number minor )
+{
+ char ch;
+
+ if (minor == 0) /* blocks until char.ready */
+ while (rdSCI0(&ch) != TRUE); /* SCI0 */
+ else
+ while (rdSCI1(&ch) != TRUE); /* SCI1 */
+ return ch;
+} /* sh_sci_inbyte_polled */
+
+/* Initial version calls polled input driver */
+char inbyte(
+ rtems_device_minor_number minor )
+{
+ char ch;
+
+ ch = sh_sci_inbyte_polled(minor);
+ return ch;
+} /* inbyte */
+
+
+/* sh_sci_initialize
+ *
+ * This routine initializes the sh_sci IO driver.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ */
+
+rtems_device_driver sh_sci_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg )
+{
+ int a;
+ unsigned16 temp16;
+ rtems_device_driver status ;
+
+ /* register devices */
+ for ( a = 0 ; a < 2 ; a++ )
+ {
+ status = rtems_io_register_name(
+ sci_device[a].name,
+ major,
+ sci_device[a].minor );
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ }
+
+ /* default hardware setup */
+
+ /* general setup */
+ temp16 = read16(PFC_PECR1) | 0x0800; /* General I/O except pin 13 (reset) */
+ write16(temp16, PFC_PECR1);
+ write16(0x00, PFC_PECR2); /* All I/O lines bits 7-0 */
+ temp16 = read16(PFC_PEIOR) | 0x0020; /* P5 to out, all other pins in */
+ write16(temp16, PFC_PEIOR);
+
+ temp16 = read16(PFC_PACRL2) | 0x0145; /* PFC - pins for Tx0-1, Rx0-1 */
+ write16(temp16, PFC_PACRL2);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * Open entry point
+ */
+
+rtems_device_driver sh_sci_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg )
+{
+ unsigned8 temp8;
+ unsigned char smr ;
+ unsigned char brr ;
+
+ unsigned a ;
+
+ /* device already opened */
+ if ( sci_device[minor].opened > 0 )
+ {
+ sci_device[minor].opened++ ;
+
+ return RTEMS_SUCCESSFUL ;
+ }
+
+ /* retrieve brr and smr values */
+ _sci_get_brparms( sci_device[minor].cflags, &smr, &brr );
+
+ if (minor == 0) {
+ write8(0x00, SCI_SCR0); /* Clear SCR */
+ write8(smr, SCI_SMR0); /* Clear SMR */
+ write8(brr, SCI_BRR0); /* Default 9600 baud rate */
+#if 0
+ write8(0x1F, SCI_BRR0); /* 28800 baud */
+#endif
+/* FIXME: Will get optimized away */
+ for(a=0;a<10000L;a++); /* One bit delay */
+ write8(0x30, SCI_SCR0); /* Enable clock output */
+ temp8 = read8(SCI_RDR0); /* Clear out old input */
+
+ } else {
+ write8(0x00, SCI_SCR1); /* Clear SCR */
+ write8(smr, SCI_SMR1); /* Clear SMR */
+ write8(brr, SCI_BRR1); /* Default 9600 baud rate */
+#if 0
+ write8(0x1F, SCI_BRR1); /* 28800 baud */
+#endif
+/* FIXME: Will get optimized away */
+ for(a=0;a<10000L;a++); /* One bit delay */
+ write8(0x30, SCI_SCR1); /* Enable clock output */
+ temp8 = read8(SCI_RDR1); /* Clear out old input */
+ }
+
+ sci_device[minor].opened++ ;
+
+ return RTEMS_SUCCESSFUL ;
+}
+
+/*
+ * Close entry point
+ */
+
+rtems_device_driver sh_sci_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ /* FIXME: Incomplete */
+ if ( sci_device[minor].opened > 0 )
+ sci_device[minor].opened-- ;
+ else
+ return RTEMS_INVALID_NUMBER ;
+
+ return RTEMS_SUCCESSFUL ;
+}
+
+/*
+ * read bytes from the serial port. We only have stdin.
+ */
+
+rtems_device_driver sh_sci_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(minor);
+ if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
+ buffer[ count++ ] = '\n';
+ break;
+ }
+ }
+
+ rw_args->bytes_moved = count;
+ return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+}
+
+/*
+ * write bytes to the serial port. Stdout and stderr are the same.
+ */
+
+rtems_device_driver sh_sci_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(minor, '\r');
+ }
+ outbyte( minor, buffer[ count ] );
+ }
+
+ rw_args->bytes_moved = maximum;
+ return 0;
+}
+
+/*
+ * IO Control entry point
+ */
+
+rtems_device_driver sh_sci_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ /* Not yet supported */
+ return RTEMS_SUCCESSFUL ;
+}