summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/score603e/tod
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/score603e/tod')
-rw-r--r--c/src/lib/libbsp/powerpc/score603e/tod/Makefile.in65
-rw-r--r--c/src/lib/libbsp/powerpc/score603e/tod/tod.c180
-rw-r--r--c/src/lib/libbsp/powerpc/score603e/tod/tod_g1.c138
3 files changed, 383 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/score603e/tod/Makefile.in b/c/src/lib/libbsp/powerpc/score603e/tod/Makefile.in
new file mode 100644
index 0000000000..20b401dc25
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/score603e/tod/Makefile.in
@@ -0,0 +1,65 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+INSTALL = @INSTALL@
+
+PGM=${ARCH}/tod.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=$(TOD_PIECES)
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+# First and second generation use different RTC chips :(
+ifeq ($(SCORE603E_GENERATION),1)
+TOD_PIECES=tod_g1
+else
+ifeq ($(SCORE603E_GENERATION),2)
+TOD_PIECES=tod
+endif # generation 2
+endif # generation 1
+
+#
+# (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 ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/score603e/tod/tod.c b/c/src/lib/libbsp/powerpc/score603e/tod/tod.c
new file mode 100644
index 0000000000..e6333e8b6f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/score603e/tod/tod.c
@@ -0,0 +1,180 @@
+/*
+ * Real Time Clock (Harris ICM7170) for RTEMS
+ *
+ * This part is found on the second generation of this board.
+ *
+ * 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 <rtems.h>
+#include <tod.h>
+#include <bsp.h>
+
+/*
+ * These values are programed into a register and must not be changed.
+ */
+
+#define ICM1770_CRYSTAL_FREQ_32K 0x00
+#define ICM1770_CRYSTAL_FREQ_1M 0x01
+#define ICM1770_CRYSTAL_FREQ_2M 0x02
+#define ICM1770_CRYSTAL_FREQ_4M 0x03
+
+void ICM7170_GetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+);
+void ICM7170_SetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+);
+
+/*
+ * This code is dependent on the Vista 603e's use of the ICM7170 RTC/NVRAM
+ * and should remain in this file.
+ */
+
+void setRealTimeToRTEMS()
+{
+ rtems_time_of_day rtc_tod;
+
+ ICM7170_GetTOD( SCORE603E_RTC_ADDRESS, SCORE_RTC_FREQUENCY, &rtc_tod );
+ rtems_clock_set( &rtc_tod );
+}
+
+void setRealTimeFromRTEMS()
+{
+ rtems_time_of_day rtems_tod;
+
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+ ICM7170_SetTOD( SCORE603E_RTC_ADDRESS, SCORE_RTC_FREQUENCY, &rtems_tod );
+}
+
+int checkRealTime()
+{
+ rtems_time_of_day rtems_tod;
+ rtems_time_of_day rtc_tod;
+
+ ICM7170_GetTOD( SCORE603E_RTC_ADDRESS, SCORE_RTC_FREQUENCY, &rtc_tod );
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+
+ if( rtems_tod.year == rtc_tod.year &&
+ rtems_tod.month == rtc_tod.month &&
+ rtems_tod.day == rtc_tod.day ) {
+ return ((rtems_tod.hour - rtc_tod.hour) * 3600) +
+ ((rtems_tod.minute - rtc_tod.minute) * 60) +
+ (rtems_tod.second - rtc_tod.second);
+ }
+ return 9999;
+}
+
+/*
+ * These routines are ICM7170 should be in
+ * a separate support library.
+ * XXX Make static
+ */
+static int ICM7170_GetField(
+ volatile unsigned char *imc1770_regs,
+ int reg
+)
+{
+ unsigned char x;
+
+ x = imc1770_regs[reg*4];
+
+ return x;
+}
+
+static void ICM7170_SetField(
+ volatile unsigned char *imc1770_regs,
+ int reg,
+ unsigned char d
+)
+{
+ imc1770_regs[reg*4] = d;
+}
+
+void ICM7170_GetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int year;
+ int usec;
+ static rtems_boolean init = TRUE;
+
+ /* Initialize the clock at once prior to reading */
+ if (init ) {
+ ICM7170_SetField( imc1770_regs, 0x11, (0x0c | icm1770_freq) );
+ init = FALSE;
+ }
+
+ /* Latch times */
+ /* rtc_tod->ticks = */
+
+ usec = ICM7170_GetField( imc1770_regs, 0x00 );
+
+ year = ICM7170_GetField( imc1770_regs, 0x06 );
+ if ( year >= 88 )
+ year += 1900;
+ else
+ year += 2000;
+
+ rtc_tod->year = year;
+ rtc_tod->month = ICM7170_GetField( imc1770_regs, 0x04 );
+ rtc_tod->day = ICM7170_GetField( imc1770_regs, 0x05 );
+ rtc_tod->hour = ICM7170_GetField( imc1770_regs, 0x01 );
+ rtc_tod->minute = ICM7170_GetField( imc1770_regs, 0x02 );
+ rtc_tod->second = ICM7170_GetField( imc1770_regs, 0x03 );
+ rtc_tod->ticks = ICM7170_GetField( imc1770_regs, 0x00 );
+}
+
+void ICM7170_SetTOD(
+ volatile unsigned char *imc1770_regs,
+ rtems_unsigned8 icm1770_freq,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int ticks;
+ int year;
+
+ year = rtc_tod->year;
+ if ( year >= 2088 ) /* plan ahead :) */
+ rtems_fatal_error_occurred( 0xBAD0BAD0 );
+
+ if ( year >= 2000 )
+ year -= 2000;
+ else
+ year -= 1900;
+
+ ICM7170_SetField( imc1770_regs, 0x11, (0x04 |icm1770_freq ) );
+
+ ICM7170_SetField( imc1770_regs, 0x06, year );
+ ICM7170_SetField( imc1770_regs, 0x04, rtc_tod->month );
+ ICM7170_SetField( imc1770_regs, 0x05, rtc_tod->day );
+ ICM7170_SetField( imc1770_regs, 0x01, rtc_tod->hour );
+ ICM7170_SetField( imc1770_regs, 0x02, rtc_tod->minute );
+ ICM7170_SetField( imc1770_regs, 0x03, rtc_tod->second );
+
+ /*
+ * I don't know which day of week is
+ *
+ */
+ ICM7170_SetField( imc1770_regs, 0x07, 1 );
+
+ ICM7170_SetField( imc1770_regs, 0x11, (0x0c | icm1770_freq) );
+}
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/powerpc/score603e/tod/tod_g1.c b/c/src/lib/libbsp/powerpc/score603e/tod/tod_g1.c
new file mode 100644
index 0000000000..6366cf662a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/score603e/tod/tod_g1.c
@@ -0,0 +1,138 @@
+/*
+ * Real Time Clock (SGS-Thomson M48T08/M48T18) for RTEMS
+ *
+ * This part is only found on the first generation board.
+ *
+ * Based on MVME162 TOD Driver by:
+ * COPYRIGHT (C) 1997
+ * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN
+ * ALL RIGHTS RESERVED
+ *
+ * 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 <rtems.h>
+#include <tod.h>
+#include <bsp.h>
+
+/*
+ * These routines are M48T08 and M48T18 dependent and should be in
+ * a separate support library.
+ */
+
+static int M48T08_GetField(
+ volatile unsigned char *mk48t08,
+ int n,
+ unsigned char mask
+)
+{
+ unsigned char x;
+
+ x = mk48t08[n] & mask;
+ return ((x >> 4) * 10) + (x & 0x0f);
+}
+
+static void M48T08_SetField(
+ volatile unsigned char *mk48t08,
+ int n,
+ unsigned char d
+)
+{
+ mk48t08[n] = ((d / 10) << 4) + (d % 10);
+}
+
+static void M48T08_GetTOD(
+ volatile unsigned char *mk48t08,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int year;
+
+ mk48t08[0] |= 0x40; /* Stop read register */
+
+ year = M48T08_GetField( mk48t08, 7, 0xff );
+ if ( year >= 88 )
+ year += 1900;
+ else
+ year += 2000;
+
+ rtc_tod->year = year;
+ rtc_tod->month = M48T08_GetField( mk48t08, 6, 0x1f );
+ rtc_tod->day = M48T08_GetField( mk48t08, 5, 0x3f );
+ rtc_tod->hour = M48T08_GetField( mk48t08, 3, 0x3f );
+ rtc_tod->minute = M48T08_GetField( mk48t08, 2, 0x7f );
+ rtc_tod->second = M48T08_GetField( mk48t08, 1, 0x7f );
+ rtc_tod->ticks = 0;
+ mk48t08[0] &= 0x3f; /* Release read register */
+}
+
+static void M48T08_SetTOD(
+ volatile unsigned char *mk48t08,
+ rtems_time_of_day *rtc_tod
+)
+{
+ int year;
+
+ year = rtc_tod->year;
+
+ if ( year >= 2088 ) /* plan ahead :) */
+ rtems_fatal_error_occurred( 0xBAD0BAD0 );
+
+ if ( year >= 2000 )
+ year -= 2000;
+ else
+ year -= 1900;
+
+ mk48t08[0] |= 0x80; /* Stop write register */
+ M48T08_SetField( mk48t08, 7, year );
+ M48T08_SetField( mk48t08, 6, rtc_tod->month );
+ M48T08_SetField( mk48t08, 5, rtc_tod->day );
+ M48T08_SetField( mk48t08, 4, 1 ); /* I don't know which day of week is */
+ M48T08_SetField( mk48t08, 3, rtc_tod->hour );
+ M48T08_SetField( mk48t08, 2, rtc_tod->minute );
+ M48T08_SetField( mk48t08, 1, rtc_tod->second );
+ mk48t08[0] &= 0x3f; /* Write these parameters */
+}
+
+/*
+ * This code is dependent on the Vista 603e's use of the M48T18 RTC/NVRAM
+ * and should remain in this file.
+ */
+
+void setRealTimeToRTEMS()
+{
+ rtems_time_of_day rtc_tod;
+
+ M48T08_GetTOD( SCORE603E_RTC_ADDRESS, &rtc_tod );
+ rtems_clock_set( &rtc_tod );
+}
+
+void setRealTimeFromRTEMS()
+{
+ rtems_time_of_day rtems_tod;
+
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+ M48T08_SetTOD( SCORE603E_RTC_ADDRESS, &rtems_tod );
+}
+
+int checkRealTime()
+{
+ rtems_time_of_day rtems_tod;
+ rtems_time_of_day rtc_tod;
+
+ M48T08_GetTOD( SCORE603E_RTC_ADDRESS, &rtc_tod );
+ rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
+
+ if( rtems_tod.year == rtc_tod.year &&
+ rtems_tod.month == rtc_tod.month &&
+ rtems_tod.day == rtc_tod.day ) {
+ return ((rtems_tod.hour - rtc_tod.hour) * 3600) +
+ ((rtems_tod.minute - rtc_tod.minute) * 60) +
+ (rtems_tod.second - rtc_tod.second);
+ }
+ return 9999;
+}