Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

time.c

Go to the documentation of this file.
00001 /*!     \file drivers/time/time.c
00002  *      \brief Real time clock driver.
00003  *      \author Andrea Righi <drizzt@inwind.it>
00004  *      \date Last update: 2003-11-01
00005  *      \note Copyright (&copy;) 2003 Andrea Righi
00006  */
00007 
00008 #include <const.h>
00009 
00010 #include <kernel/console.h>
00011 #include <kernel/semaphore.h>
00012 
00013 #include <kernel/time.h>
00014 
00015 //! The real-time clock semaphore.
00016 semaphore_t rtc_lock;
00017 
00018 //! \brief Initialize the Real-Time Clock.
00019 void time_init()
00020 {
00021         INIT_MUTEX(&rtc_lock);
00022 }
00023 
00024 //! \brief
00025 //!     Get the seconds passed since midnight 1970-01-01
00026 //!     (Unix timestamp).
00027 //! \return
00028 //!     The UNIX timestamp.
00029 time_t time_read()
00030 {
00031         unsigned int year, mon, day, hour, min, sec;
00032         int i;
00033 
00034         DOWN(&rtc_lock);
00035 
00036         // When the Update-In-Progress (UIP) flag goes from 1 to 0,     //
00037         // the RTC registers show the second which has precisely just   //
00038         // started.                                                     //
00039         // Read RTC exactly on falling edge of update flag.             //
00040 
00041         for (i=0; i<1000000 ; i++)      // may take up to 1 second...   //
00042                 if ( CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP )
00043                         break;
00044 
00045         for (i=0 ; i<1000000 ; i++)     // must try at least 2.228 ms   //
00046                 if ( !(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
00047                         break;
00048 
00049         do { /* Isn't this overkill ? UIP above should guarantee consistency */
00050                 sec =   CMOS_READ(RTC_SECONDS);
00051                 min =   CMOS_READ(RTC_MINUTES);
00052                 hour =  CMOS_READ(RTC_HOURS);
00053                 day =   CMOS_READ(RTC_DAY_OF_MONTH);
00054                 mon =   CMOS_READ(RTC_MONTH);
00055                 year =  CMOS_READ(RTC_YEAR);
00056         } while (sec != CMOS_READ(RTC_SECONDS));
00057 
00058         if ( !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) )
00059         {
00060                 sec =   BCD2BIN( sec );
00061                 min =   BCD2BIN( min );
00062                 hour =  BCD2BIN( hour );
00063                 day =   BCD2BIN( day );
00064                 mon =   BCD2BIN( mon );
00065                 year =  BCD2BIN( year );
00066         }
00067 
00068         UP(&rtc_lock);
00069 
00070         if ( (year += 1900) < 1970 )
00071                 year += 100;
00072 
00073         return( mktime(year, mon, day, hour, min, sec) );
00074 }

Generated on Fri Feb 20 15:32:16 2004 for Minirighi by doxygen1.2.18