From 4a238002e71ec018723229f8669363a5ffb7302e Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 18 Nov 1999 21:22:58 +0000 Subject: Patch from "John M. Mills" with subsequent cleanup from Ralf Corsepius 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//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 --- c/src/lib/libcpu/sh/sh7045/sci/Makefile.in | 71 ++++++ c/src/lib/libcpu/sh/sh7045/sci/sci.c | 384 +++++++++++++++++++++++++++++ 2 files changed, 455 insertions(+) create mode 100644 c/src/lib/libcpu/sh/sh7045/sci/Makefile.in create mode 100644 c/src/lib/libcpu/sh/sh7045/sci/sci.c (limited to 'c/src/lib/libcpu/sh/sh7045/sci') diff --git a/c/src/lib/libcpu/sh/sh7045/sci/Makefile.in b/c/src/lib/libcpu/sh/sh7045/sci/Makefile.in new file mode 100644 index 0000000000..2548c0b478 --- /dev/null +++ b/c/src/lib/libcpu/sh/sh7045/sci/Makefile.in @@ -0,0 +1,71 @@ +## +## $Id$ +## + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = ../../.. +subdir = sh/sh7045/sci + +RTEMS_ROOT = @RTEMS_ROOT@ +PROJECT_ROOT = @PROJECT_ROOT@ + +VPATH = @srcdir@ + +PGM = ${ARCH}/sci.rel + +# C source names, if any, go here -- minus the .c +C_PIECES = sci +C_FILES = $(C_PIECES:%=%.c) +C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) + +H_FILES = + +# Assembly source names, if any, go here -- minus the .s +S_PIECES = +S_FILES = $(S_PIECES:%=%.s) +S_O_FILES = $(S_FILES:%.s=${ARCH}/%.o) + +SRCS = $(C_FILES) $(H_FILES) $(S_FILES) +OBJS = $(C_O_FILES) $(S_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +INSTALL_CHANGE = @INSTALL_CHANGE@ + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by +# libbsp/sh/BSP/wrapup/Makefile +install: all + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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 ; +} -- cgit v1.2.3