00001 /*! \file include/kernel/time.h 00002 * \brief Real time clock driver header. 00003 * \author Andrea Righi <drizzt@inwind.it> 00004 * \date Last update: 2003-08-27 00005 * \note Copyright (©) 2003 Andrea Righi 00006 */ 00007 00008 #ifndef TIME_H 00009 #define TIME_H 00010 00011 //! Time variable type. 00012 typedef unsigned long time_t; 00013 00014 //! The base epoch year. 00015 #define RTC_EPOCH_YEAR 1970 00016 //! The base epoch day (Jan 1). 00017 #define EPOCH_DAY 0 00018 00019 //! RTC port for seconds. 00020 #define RTC_SECONDS 0 00021 //! RTC port for minutes. 00022 #define RTC_MINUTES 2 00023 //! RTC port for hours. 00024 #define RTC_HOURS 4 00025 00026 //! RTC port for the day of the week. 00027 #define RTC_DAY_OF_WEEK 6 00028 //! RTC port for the month. 00029 #define RTC_DAY_OF_MONTH 7 00030 //! RTC port for month. 00031 #define RTC_MONTH 8 00032 //! RTC port for year. 00033 #define RTC_YEAR 9 00034 00035 //! RTC control register A. 00036 #define RTC_REG_A 10 00037 //! RTC control register B. 00038 #define RTC_REG_B 11 00039 //! RTC control register C. 00040 #define RTC_REG_C 12 00041 //! RTC control register D. 00042 #define RTC_REG_D 13 00043 00044 //! Macro to convert from BCD to binary format. 00045 #define BCD2BIN(n) ( ((n) >> 4) * 10 + ((n) & 0x0F) ) 00046 //! Macro to convert from binary to BCD format. 00047 #define BIN2BCD(n) ( (((n) / 10) << 4) + ((n) % 10) ) 00048 00049 //! CMOS control register. 00050 #define CMOS_CTRL 0x70 00051 //! CMOS data register. 00052 #define CMOS_DATA 0x71 00053 00054 //! \brief Read a value from the CMOS. 00055 //! \param port The port to read from. 00056 //! \return The value read from the CMOS \a port. 00057 #define CMOS_READ(port) ( \ 00058 { \ 00059 out( CMOS_CTRL, (port) ); \ 00060 in( CMOS_DATA ); \ 00061 }) 00062 00063 //! \brief Write a value to the CMOS. 00064 //! \param port The port to write to. 00065 //! \param val The value to write. 00066 #define CMOS_WRITE(port, val) ( \ 00067 { \ 00068 out( CMOS_CTRL, (port) ); \ 00069 out( CMOS_DATA, (val) ); \ 00070 }) 00071 00072 // --- Register Details ----------------------------------------------- // 00073 // ******************************************************************** // 00074 //! RTC update frequency register. 00075 #define RTC_FREQ_SELECT RTC_REG_A 00076 00077 //! Update-in-progress - set to "1" 244 microsecs before RTC goes off 00078 //! the bus, reset after update (may take 1.984ms @ 32768Hz RefClock) 00079 //! is complete, totalling to a max high interval of 2.228 ms. 00080 #define RTC_UIP 0x80 00081 /* 2 values for divider stage reset, others for "testing purposes only" */ 00082 #define RTC_DIV_RESET1 0x60 00083 #define RTC_DIV_RESET2 0x70 00084 00085 // ******************************************************************** // 00086 //! RTC status register. 00087 #define RTC_CONTROL RTC_REG_B 00088 00089 //! Disable updates for clock setting. 00090 #define RTC_SET 0x80 00091 //! RTC binary date; all time/date values are BCD if clear. 00092 #define RTC_DM_BINARY 0x04 00093 // 24 hour mode - else hours bit 7 means pm. 00094 #define RTC_24H 0x02 00095 00096 // ******************************************************************** // 00097 00098 /** \ingroup Drivers 00099 * \defgroup RTCDriver Real-Time Clock 00100 * The real-time clock driver. 00101 * @{ 00102 */ 00103 00104 // --- Time procedures ------------------------------------------------ // 00105 00106 //! \brief Converts Gregorian date to seconds since 1970-01-01 00:00:00. 00107 //! \param year The year value. 00108 //! \param mon The month value. 00109 //! \param day The day of the month value. 00110 //! \param hour The hours value. 00111 //! \param min The minutes value. 00112 //! \param sec The seconds value. 00113 //! \return 00114 //! Seconds since 1970-01-01 00:00:00 (UNIX timestamp). 00115 /** 00116 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 00117 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. 00118 * 00119 * [For the Julian calendar (which was used in Russia before 1917, 00120 * Britain & colonies before 1752, anywhere else before 1582, 00121 * and is still in use by some communities) leave out the 00122 * -year/100+year/400 terms, and add 10.] 00123 * 00124 * This algorithm was first published by Gauss (I think). 00125 * 00126 * WARNING: this function will overflow on 2106-02-07 06:28:16 on 00127 * machines were long is 32-bit! (However, as time_t is signed, we 00128 * will already get problems at other places on 2038-01-19 03:14:08) 00129 * \n\n Thanks to Linux... (Andrea Righi). 00130 */ 00131 static __inline__ unsigned long 00132 mktime (unsigned int year, unsigned int mon, 00133 unsigned int day, unsigned int hour, 00134 unsigned int min, unsigned int sec) 00135 { 00136 if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ 00137 mon += 12; /* Puts Feb last since it has leap day */ 00138 year -= 1; 00139 } 00140 00141 return ((( 00142 (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + 00143 year*365 - 719499 00144 )*24 + hour /* now have hours */ 00145 )*60 + min /* now have minutes */ 00146 )*60 + sec; /* finally seconds */ 00147 } 00148 00149 // --- Prototypes ----------------------------------------------------- // 00150 00151 void time_init(); 00152 time_t time_read(); 00153 00154 /** @} */ // end of RTCDriver 00155 00156 #endif