1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdio.h> /* get NULL */
27 #include "timefuncs.h"
30 #if !(defined SIMULATOR && CONFIG_RTC)
34 static void fill_default_tm(struct tm
*tm
)
43 tm
->tm_yday
= 0; /* Not implemented for now */
44 tm
->tm_isdst
= -1; /* Not implemented for now */
46 #endif /* !(defined SIMULATOR && CONFIG_RTC)*/
48 bool valid_time(const struct tm
*tm
)
50 if (tm
->tm_hour
< 0 || tm
->tm_hour
> 23 ||
51 tm
->tm_sec
< 0 || tm
->tm_sec
> 59 ||
52 tm
->tm_min
< 0 || tm
->tm_min
> 59 ||
53 tm
->tm_year
< 100 || tm
->tm_year
> 199 ||
54 tm
->tm_mon
< 0 || tm
->tm_mon
> 11 ||
55 tm
->tm_wday
< 0 || tm
->tm_wday
> 6 ||
56 tm
->tm_mday
< 1 || tm
->tm_mday
> 31)
62 struct tm
*get_time(void)
66 static long timeout
= 0;
68 /* Don't read the RTC more than once per second */
69 if (current_tick
> timeout
)
71 /* Once per second, 1/10th of a second off */
72 timeout
= HZ
* (current_tick
/ HZ
+ 1) + HZ
/ 5;
73 #if CONFIG_RTC != RTC_JZ47XX
75 rtc_read_datetime(rtcbuf
);
77 tm
.tm_sec
= ((rtcbuf
[0] & 0x70) >> 4) * 10 + (rtcbuf
[0] & 0x0f);
78 tm
.tm_min
= ((rtcbuf
[1] & 0x70) >> 4) * 10 + (rtcbuf
[1] & 0x0f);
79 tm
.tm_hour
= ((rtcbuf
[2] & 0x30) >> 4) * 10 + (rtcbuf
[2] & 0x0f);
80 tm
.tm_wday
= rtcbuf
[3] & 0x07;
81 tm
.tm_mday
= ((rtcbuf
[4] & 0x30) >> 4) * 10 + (rtcbuf
[4] & 0x0f);
82 tm
.tm_mon
= ((rtcbuf
[5] & 0x10) >> 4) * 10 + (rtcbuf
[5] & 0x0f) - 1;
83 #ifdef IRIVER_H300_SERIES
84 /* Special kludge to coexist with the iriver firmware. The iriver firmware
85 stores the date as 1965+nn, and allows a range of 1980..2064. We use
86 1964+nn here to make leap years work correctly, so the date will be one
87 year off in the iriver firmware but at least won't be reset anymore. */
88 tm
.tm_year
= ((rtcbuf
[6] & 0xf0) >> 4) * 10 + (rtcbuf
[6] & 0x0f) + 64;
89 #else /* Not IRIVER_H300_SERIES */
90 tm
.tm_year
= ((rtcbuf
[6] & 0xf0) >> 4) * 10 + (rtcbuf
[6] & 0x0f) + 100;
91 #endif /* IRIVER_H300_SERIES */
93 tm
.tm_yday
= 0; /* Not implemented for now */
94 tm
.tm_isdst
= -1; /* Not implemented for now */
95 #else /* CONFIG_RTC == RTC_JZ47XX */
96 rtc_read_datetime((unsigned char*)&tm
);
97 #endif /* CONFIG_RTC */
100 fill_default_tm(&tm
);
104 #else /* SIMULATOR */
106 time_t now
= time(NULL
);
107 return localtime(&now
);
108 #else /* Simulator, no RTC */
109 fill_default_tm(&tm
);
112 #endif /* SIMULATOR */
115 int set_time(const struct tm
*tm
)
119 #if CONFIG_RTC != RTC_JZ47XX
125 #if CONFIG_RTC != RTC_JZ47XX
126 rtcbuf
[0]=((tm
->tm_sec
/10) << 4) | (tm
->tm_sec
%10);
127 rtcbuf
[1]=((tm
->tm_min
/10) << 4) | (tm
->tm_min
%10);
128 rtcbuf
[2]=((tm
->tm_hour
/10) << 4) | (tm
->tm_hour
%10);
129 rtcbuf
[3]=tm
->tm_wday
;
130 rtcbuf
[4]=((tm
->tm_mday
/10) << 4) | (tm
->tm_mday
%10);
131 rtcbuf
[5]=(((tm
->tm_mon
+1)/10) << 4) | ((tm
->tm_mon
+1)%10);
132 #ifdef IRIVER_H300_SERIES
133 /* Iriver firmware compatibility kludge, see get_time(). */
134 rtcbuf
[6]=(((tm
->tm_year
-64)/10) << 4) | ((tm
->tm_year
-64)%10);
136 rtcbuf
[6]=(((tm
->tm_year
-100)/10) << 4) | ((tm
->tm_year
-100)%10);
139 rc
= rtc_write_datetime(rtcbuf
);
141 rc
= rtc_write_datetime((unsigned char*)tm
);
160 /* mktime() code taken from lynx-2.8.5 source, written
161 by Philippe De Muyter <phdm@macqel.be> */
162 time_t mktime(struct tm
*t
)
166 static int m_to_d
[12] =
167 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
170 year
= t
->tm_year
+ month
/ 12 + 1900;
177 result
= (year
- 1970) * 365 + (year
- 1969) / 4 + m_to_d
[month
];
178 result
= (year
- 1970) * 365 + m_to_d
[month
];
181 result
+= (year
- 1968) / 4;
182 result
-= (year
- 1900) / 100;
183 result
+= (year
- 1600) / 400;
184 result
+= t
->tm_mday
;
187 result
+= t
->tm_hour
;