/* * Real Time Clock Driver Wrapper for Libchip */ /* * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #include #include #include #include #include /* * Configuration Information */ static rtems_device_minor_number RTC_Minor = UINT32_MAX; static bool RTC_Is_present(void) { return RTC_Minor != UINT32_MAX; } /* * rtc_initialize * * Initialize the RTC driver */ rtems_device_driver rtc_initialize( rtems_device_major_number major, rtems_device_minor_number minor_arg, void *arg ) { rtems_device_minor_number minor; rtems_status_code status; for (minor=0; minor < RTC_Count ; minor++) { /* * First perform the configuration dependent probe, then the * device dependent probe */ if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) { /* * Use this device as the primary RTC */ RTC_Minor = minor; break; } } if ( !RTC_Is_present() ) { /* * Failed to find an RTC -- this is not a fatal error. */ return RTEMS_INVALID_NUMBER; } /* * Register and initialize the primary RTC's */ status = rtems_io_register_name( RTC_DEVICE_NAME, major, RTC_Minor ); if (status != RTEMS_SUCCESSFUL) { rtems_fatal_error_occurred(status); } RTC_Table[minor].pDeviceFns->deviceInitialize( RTC_Minor ); /* * Now initialize any secondary RTC's */ for ( minor++ ; minordeviceInitialize(minor); } } setRealTimeToRTEMS(); return RTEMS_SUCCESSFUL; } rtems_device_driver rtc_read( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { int rv = 0; rtems_libio_rw_args_t *rw = arg; rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer; rw->offset = 0; rw->bytes_moved = 0; if (!RTC_Is_present()) { return RTEMS_NOT_CONFIGURED; } if (rw->count != sizeof( rtems_time_of_day)) { return RTEMS_INVALID_SIZE; } rv = RTC_Table [RTC_Minor].pDeviceFns->deviceGetTime( RTC_Minor, tod ); if (rv != 0) { return RTEMS_IO_ERROR; } rw->bytes_moved = rw->count; return RTEMS_SUCCESSFUL; } rtems_device_driver rtc_write( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { int rv = 0; rtems_libio_rw_args_t *rw = arg; const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer; rw->offset = 0; rw->bytes_moved = 0; if (!RTC_Is_present()) { return RTEMS_NOT_CONFIGURED; } if (rw->count != sizeof( rtems_time_of_day)) { return RTEMS_INVALID_SIZE; } rv = RTC_Table [RTC_Minor].pDeviceFns->deviceSetTime( RTC_Minor, tod ); if (rv != 0) { return RTEMS_IO_ERROR; } rw->bytes_moved = rw->count; return RTEMS_SUCCESSFUL; } rtems_device_driver rtc_open( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return RTEMS_SUCCESSFUL; } rtems_device_driver rtc_close( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return RTEMS_SUCCESSFUL; } rtems_device_driver rtc_control( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return RTEMS_NOT_IMPLEMENTED; } /* * This routine copies the time from the real time clock to RTEMS */ void setRealTimeToRTEMS() { rtems_time_of_day rtc_tod; if (!RTC_Is_present()) return; RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod); rtems_clock_set( &rtc_tod ); } /* * setRealTimeFromRTEMS * * This routine copies the time from RTEMS to the real time clock */ void setRealTimeFromRTEMS(void) { rtems_time_of_day rtems_tod; if (!RTC_Is_present()) return; rtems_clock_get_tod( &rtems_tod ); RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, &rtems_tod); } /* * getRealTime * * This routine reads the current time from the RTC. */ void getRealTime( rtems_time_of_day *tod ) { if (!RTC_Is_present()) return; RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, tod); } /* * setRealTime * * This routine sets the RTC. */ int setRealTime( const rtems_time_of_day *tod ) { if (!RTC_Is_present()) return -1; if ( !_TOD_Validate(tod) ) return -1; RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, tod); return 0; } /* * checkRealTime * * This routine reads the returns the variance betweent the real time and * RTEMS time. */ int checkRealTime(void) { rtems_time_of_day rtems_tod; rtems_time_of_day rtc_tod; uint32_t rtems_time; uint32_t rtc_time; if (!RTC_Is_present()) return -1; rtems_clock_get_tod( &rtems_tod ); RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod); rtems_time = _TOD_To_seconds( &rtems_tod ); rtc_time = _TOD_To_seconds( &rtc_tod ); return rtems_time - rtc_time; }