summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/src/tod.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/exec/score/src/tod.c')
-rw-r--r--c/src/exec/score/src/tod.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/c/src/exec/score/src/tod.c b/c/src/exec/score/src/tod.c
new file mode 100644
index 0000000000..4689c637d7
--- /dev/null
+++ b/c/src/exec/score/src/tod.c
@@ -0,0 +1,236 @@
+/*
+ * Time of Day (TOD) Handler
+ *
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/object.h>
+#include <rtems/thread.h>
+#include <rtems/tod.h>
+#include <rtems/watchdog.h>
+
+/*PAGE
+ *
+ * _TOD_Handler_initialization
+ *
+ * This routine initializes the time of day handler.
+ *
+ * Input parameters:
+ * microseconds_per_tick - microseconds between clock ticks
+ *
+ * Output parameters: NONE
+ */
+
+void _TOD_Handler_initialization(
+ unsigned32 microseconds_per_tick
+)
+{
+ _TOD_Microseconds_per_tick = microseconds_per_tick;
+
+ _TOD_Ticks_since_boot = 0;
+ _TOD_Seconds_since_epoch = 0;
+
+ _TOD_Current.year = TOD_BASE_YEAR;
+ _TOD_Current.month = 1;
+ _TOD_Current.day = 1;
+ _TOD_Current.hour = 0;
+ _TOD_Current.minute = 0;
+ _TOD_Current.second = 0;
+ _TOD_Current.ticks = 0;
+
+ if ( microseconds_per_tick == 0 )
+ _TOD_Ticks_per_second = 0;
+ else
+ _TOD_Ticks_per_second =
+ TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick;
+
+ _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL );
+}
+
+/*PAGE
+ *
+ * _TOD_Set
+ *
+ * This rountine sets the current date and time with the specified
+ * new date and time structure.
+ *
+ * Input parameters:
+ * the_tod - pointer to the time and date structure
+ * seconds_since_epoch - seconds since system epoch
+ *
+ * Output parameters: NONE
+ */
+
+void _TOD_Set(
+ rtems_time_of_day *the_tod,
+ rtems_interval seconds_since_epoch
+)
+{
+ rtems_interval ticks_until_next_second;
+
+ _Thread_Disable_dispatch();
+ _TOD_Deactivate();
+
+ if ( seconds_since_epoch < _TOD_Seconds_since_epoch )
+ _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD,
+ _TOD_Seconds_since_epoch - seconds_since_epoch );
+ else
+ _Watchdog_Adjust_seconds( WATCHDOG_FORWARD,
+ seconds_since_epoch - _TOD_Seconds_since_epoch );
+
+ ticks_until_next_second = _TOD_Ticks_per_second;
+ if ( ticks_until_next_second > _TOD_Current.ticks )
+ ticks_until_next_second -= _TOD_Current.ticks;
+
+ _TOD_Current = *the_tod;
+ _TOD_Seconds_since_epoch = seconds_since_epoch;
+ _TOD_Activate( ticks_until_next_second );
+
+ _Thread_Enable_dispatch();
+}
+
+/*PAGE
+ *
+ * _TOD_Validate
+ *
+ * This kernel routine checks the validity of a date and time structure.
+ *
+ * Input parameters:
+ * the_tod - pointer to a time and date structure
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if the date, time, and tick are valid
+ * RTEMS_INVALID_CLOCK - if the the_tod is invalid
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+rtems_status_code _TOD_Validate(
+ rtems_time_of_day *the_tod
+)
+{
+ unsigned32 days_in_month;
+
+ if ((the_tod->ticks >= _TOD_Ticks_per_second) ||
+ (the_tod->second >= TOD_SECONDS_PER_MINUTE) ||
+ (the_tod->minute >= TOD_MINUTES_PER_HOUR) ||
+ (the_tod->hour >= TOD_HOURS_PER_DAY) ||
+ (the_tod->month == 0) ||
+ (the_tod->month > TOD_MONTHS_PER_YEAR) ||
+ (the_tod->year < TOD_BASE_YEAR) ||
+ (the_tod->day == 0) )
+ return RTEMS_INVALID_CLOCK;
+
+ if ( (the_tod->year % 4) == 0 )
+ days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ];
+ else
+ days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ];
+
+ if ( the_tod->day > days_in_month )
+ return RTEMS_INVALID_CLOCK;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _TOD_To_seconds
+ *
+ * This routine returns the seconds from the epoch until the
+ * current date and time.
+ *
+ * Input parameters:
+ * the_tod - pointer to the time and date structure
+ *
+ * Output parameters:
+ * returns - seconds since epoch until the_tod
+ */
+
+unsigned32 _TOD_To_seconds(
+ rtems_time_of_day *the_tod
+)
+{
+ unsigned32 time;
+ unsigned32 year_mod_4;
+
+ time = the_tod->day - 1;
+ year_mod_4 = the_tod->year & 3;
+
+ if ( year_mod_4 == 0 )
+ time += _TOD_Days_to_date[ 1 ][ the_tod->month ];
+ else
+ time += _TOD_Days_to_date[ 0 ][ the_tod->month ];
+
+ time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) *
+ ( (TOD_DAYS_PER_YEAR * 4) + 1);
+
+ time += _TOD_Days_since_last_leap_year[ year_mod_4 ];
+
+ time *= TOD_SECONDS_PER_DAY;
+
+ time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute)
+ * TOD_SECONDS_PER_MINUTE;
+
+ time += the_tod->second;
+
+ return( time );
+}
+
+/*PAGE
+ *
+ * _TOD_Tickle
+ *
+ * This routine updates the calendar time and tickles the
+ * per second watchdog timer chain.
+ *
+ * Input parameters:
+ * ignored - this parameter is ignored
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: This routine only works for leap-years through 2099.
+ */
+
+void _TOD_Tickle(
+ Objects_Id id,
+ void *ignored
+)
+{
+ unsigned32 leap;
+
+ _TOD_Current.ticks = 0;
+ ++_TOD_Seconds_since_epoch;
+ if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) {
+ _TOD_Current.second = 0;
+ if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) {
+ _TOD_Current.minute = 0;
+ if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) {
+ _TOD_Current.hour = 0;
+ if ( _TOD_Current.year & 0x3 ) leap = 0;
+ else leap = 1;
+ if ( ++_TOD_Current.day >
+ _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) {
+ _TOD_Current.day = 1;
+ if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) {
+ _TOD_Current.month = 1;
+ _TOD_Current.year++;
+ }
+ }
+ }
+ }
+ }
+
+ _Watchdog_Tickle_seconds();
+ _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second,
+ WATCHDOG_ACTIVATE_NOW );
+}