diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/score603e/tod')
-rw-r--r-- | c/src/lib/libbsp/powerpc/score603e/tod/Makefile.in | 65 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/score603e/tod/tod.c | 180 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/score603e/tod/tod_g1.c | 138 |
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; +} |