From ba7107616869bff7dc80627eab666fceb5ff4fb5 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 12 Oct 2001 13:19:08 +0000 Subject: 2001-10-11 Alexandra Kossovsky * clock/Makefile.am, clock/ckinit.c, clock/.cvsignore, Makefile.am, include/Makefile.am, include/iosh7750.h, include/ipl.h, include/ispsh7750.h, include/sh4_regs.h, include/sh4uart.h, include/sh7750_regs.h, include/.cvsignore, sci/Makefile.am, sci/console.c, sci/sh4uart.c, sci/.cvsignore, score/Makefile.am, score/cpu_asm.c, score/ispsh7750.c, score/.cvsignore, timer/Makefile.am, timer/timer.c, timer/.cvsignore, configure.ac, .cvsignore, ChangeLog: New files. Reviewed and updated to latest automake and autoconf standards by Ralf Corsepius . --- c/src/lib/libcpu/sh/sh7750/clock/.cvsignore | 2 + c/src/lib/libcpu/sh/sh7750/clock/Makefile.am | 31 +++ c/src/lib/libcpu/sh/sh7750/clock/ckinit.c | 324 +++++++++++++++++++++++++++ 3 files changed, 357 insertions(+) create mode 100644 c/src/lib/libcpu/sh/sh7750/clock/.cvsignore create mode 100644 c/src/lib/libcpu/sh/sh7750/clock/Makefile.am create mode 100644 c/src/lib/libcpu/sh/sh7750/clock/ckinit.c (limited to 'c/src/lib/libcpu/sh/sh7750/clock') diff --git a/c/src/lib/libcpu/sh/sh7750/clock/.cvsignore b/c/src/lib/libcpu/sh/sh7750/clock/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/sh/sh7750/clock/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/sh/sh7750/clock/Makefile.am b/c/src/lib/libcpu/sh/sh7750/clock/Makefile.am new file mode 100644 index 0000000000..f0044ba331 --- /dev/null +++ b/c/src/lib/libcpu/sh/sh7750/clock/Makefile.am @@ -0,0 +1,31 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +PGM = $(ARCH)/clock.rel + +C_FILES = ckinit.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(top_srcdir)/../../../../../../make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +all-local: $(ARCH) $(OBJS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = ckinit.c + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libcpu/sh/sh7750/clock/ckinit.c b/c/src/lib/libcpu/sh/sh7750/clock/ckinit.c new file mode 100644 index 0000000000..6575670fa7 --- /dev/null +++ b/c/src/lib/libcpu/sh/sh7750/clock/ckinit.c @@ -0,0 +1,324 @@ +/* + * This file contains the generic RTEMS clock driver the Hitachi SH 7750 + * + * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * COPYRIGHT (c) 2001 + * 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. + * + * $Id$ + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef CLOCKPRIO +#define CLOCKPRIO 10 +#endif + +/* Clock timer prescaler division ratio */ +#define CLOCK_PRESCALER 4 +#define TCR0_TPSC SH7750_TCR_TPSC_DIV4 + +/* + * The interrupt vector number associated with the clock tick device + * driver. + */ + +#define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0) + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ + +volatile rtems_unsigned32 Clock_driver_ticks; + +static void Clock_exit( void ); +static rtems_isr Clock_isr( rtems_vector_number vector ); + +/* + * These are set by clock driver during its init + */ +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +/* + * The previous ISR on this clock tick interrupt vector. + */ + +rtems_isr_entry Old_ticker; + +/* + * Isr Handler + */ + +/* Clock_isr -- + * Clock interrupt handling routine. + * + * PARAMETERS: + * vector - interrupt vector number + * + * RETURNS: + * none + */ +rtems_isr +Clock_isr(rtems_vector_number vector) +{ + unsigned16 tcr; + + /* reset the timer underflow flag */ + tcr = read16(SH7750_TCR0); + write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0); + + /* Increment the clock interrupt counter */ + Clock_driver_ticks++ ; + + /* Invoke rtems clock service routine */ + rtems_clock_tick(); +} + +/* Install_clock -- + * Install a clock tick handler and reprograms the chip. This + * is used to initially establish the clock tick. + * + * PARAMETERS: + * clock_isr - Clock interrupt stay routine + * + * RETURNS: + * none + * + * SIDE EFFECTS: + * Establish clock interrupt handler, configure Timer 0 hardware + */ +void +Install_clock(rtems_isr_entry clock_isr) +{ + int cpudiv = 1; /* CPU frequency divider */ + int tidiv = 1; /* Timer input frequency divider */ + unsigned32 timer_divider; /* Calculated Timer Divider value */ + unsigned8 temp8; + unsigned16 temp16; + + /* + * Initialize the clock tick device driver variables + */ + + Clock_driver_ticks = 0; + + /* Get CPU frequency divider from clock unit */ + switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) + { + case SH7750_FRQCR_IFCDIV1: + cpudiv = 1; + break; + + case SH7750_FRQCR_IFCDIV2: + cpudiv = 2; + break; + + case SH7750_FRQCR_IFCDIV3: + cpudiv = 3; + break; + + case SH7750_FRQCR_IFCDIV4: + cpudiv = 4; + break; + + case SH7750_FRQCR_IFCDIV6: + cpudiv = 6; + break; + + case SH7750_FRQCR_IFCDIV8: + cpudiv = 8; + break; + + default: + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); + } + + /* Get peripheral module frequency divider from clock unit */ + switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) + { + case SH7750_FRQCR_PFCDIV2: + tidiv = 2 * CLOCK_PRESCALER; + break; + + case SH7750_FRQCR_PFCDIV3: + tidiv = 3 * CLOCK_PRESCALER; + break; + + case SH7750_FRQCR_PFCDIV4: + tidiv = 4 * CLOCK_PRESCALER; + break; + + case SH7750_FRQCR_PFCDIV6: + tidiv = 6 * CLOCK_PRESCALER; + break; + + case SH7750_FRQCR_PFCDIV8: + tidiv = 8 * CLOCK_PRESCALER; + break; + + default: + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); + } + timer_divider = + (rtems_cpu_configuration_get_clicks_per_second() * + cpudiv / (tidiv*1000000)) * + rtems_configuration_get_microseconds_per_tick(); + + /* + * Hardware specific initialization + */ + + /* Stop the Timer 0 */ + temp8 = read8(SH7750_TSTR); + temp8 &= ~SH7750_TSTR_STR0; + write8(temp8, SH7750_TSTR); + + /* Establish interrupt handler */ + rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker ); + + /* Reset counter */ + write32(timer_divider, SH7750_TCNT0); + + /* Load divider */ + write32(timer_divider, SH7750_TCOR0); + + write16( + SH7750_TCR_UNIE | /* Enable Underflow Interrupt */ + SH7750_TCR_CKEG_RAISE | /* Count on rising edge */ + TCR0_TPSC, /* Timer prescaler ratio */ + SH7750_TCR0); + + /* Set clock interrupt priority */ + temp16 = read16(SH7750_IPRA); + temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S); + write16(temp16, SH7750_IPRA); + + /* Start the Timer 0 */ + temp8 = read8(SH7750_TSTR); + temp8 |= SH7750_TSTR_STR0; + write8(temp8, SH7750_TSTR); + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + + atexit( Clock_exit ); +} + +/* Clock_exit -- + * Clean up before the application exits + * + * PARAMETERS: + * none + * + * RETURNS: + * none + * + * SIDE EFFECTS: + * Stop Timer 0 counting, set timer 0 interrupt priority level to 0. + */ +void +Clock_exit(void) +{ + unsigned8 temp8 = 0; + unsigned16 temp16 = 0; + + /* turn off the timer interrupts */ + /* Stop the Timer 0 */ + temp8 = read8(SH7750_TSTR); + temp8 &= ~SH7750_TSTR_STR0; + write8(temp8, SH7750_TSTR); + + /* Lower timer interrupt priority to 0 */ + temp16 = read16(SH7750_IPRA); + temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S); + write16(temp16, SH7750_IPRA); + + /* old vector shall not be installed */ +} + +/* Clock_initialize -- + * Device driver entry point for clock tick driver initialization. + * + * PARAMETERS: + * major - clock major device number + * minor - clock minor device number + * pargp - driver initialize primitive argument, not used + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_device_driver +Clock_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) +{ + Install_clock( Clock_isr ); + + /* + * make major/minor avail to others such as shared memory driver + */ + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +/* Clock_control -- + * Device driver entry point for clock driver IOCTL functions. + * + * PARAMETERS: + * major - clock major device number + * minor - clock minor device number + * pargp - driver ioctl primitive argument, not used + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_device_driver +Clock_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) +{ + rtems_unsigned32 isrlevel; + rtems_libio_ioctl_args_t *args = pargp; + + if (args != 0) + { + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr(CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + rtems_isr_entry ignored ; + rtems_interrupt_disable( isrlevel ); + rtems_interrupt_catch( args->buffer, CLOCK_VECTOR, &ignored ); + + rtems_interrupt_enable( isrlevel ); + } + } + return RTEMS_SUCCESSFUL; +} -- cgit v1.2.3