Add the missing brickmania screenshots to the c200 and 5/6GB H10 manual. Fill out...
[Rockbox.git] / firmware / common / timefuncs.c
blob9865b0fe171cb8570b6675c3947358dd24964b31
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdio.h> /* get NULL */
21 #include "config.h"
23 #include "kernel.h"
24 #include "rtc.h"
25 #include "timefuncs.h"
26 #include "debug.h"
28 #ifndef SIMULATOR
29 static struct tm tm;
30 #endif
32 bool valid_time(const struct tm *tm)
34 if (tm->tm_hour < 0 || tm->tm_hour > 23 ||
35 tm->tm_sec < 0 || tm->tm_sec > 59 ||
36 tm->tm_min < 0 || tm->tm_min > 59 ||
37 tm->tm_year < 100 || tm->tm_year > 199 ||
38 tm->tm_mon < 0 || tm->tm_mon > 11 ||
39 tm->tm_wday < 0 || tm->tm_wday > 6 ||
40 tm->tm_mday < 1 || tm->tm_mday > 31)
41 return false;
42 else
43 return true;
46 struct tm *get_time(void)
48 #ifndef SIMULATOR
49 #if CONFIG_RTC
50 static long timeout = 0;
52 /* Don't read the RTC more than once per second */
53 if (current_tick > timeout) {
54 char rtcbuf[7];
55 /* Once per second, 1/10th of a second off */
56 timeout = HZ * (current_tick / HZ + 1) + HZ / 5;
57 rtc_read_datetime(rtcbuf);
59 tm.tm_sec = ((rtcbuf[0] & 0x70) >> 4) * 10 + (rtcbuf[0] & 0x0f);
60 tm.tm_min = ((rtcbuf[1] & 0x70) >> 4) * 10 + (rtcbuf[1] & 0x0f);
61 tm.tm_hour = ((rtcbuf[2] & 0x30) >> 4) * 10 + (rtcbuf[2] & 0x0f);
62 tm.tm_wday = rtcbuf[3] & 0x07;
63 tm.tm_mday = ((rtcbuf[4] & 0x30) >> 4) * 10 + (rtcbuf[4] & 0x0f);
64 tm.tm_mon = ((rtcbuf[5] & 0x10) >> 4) * 10 + (rtcbuf[5] & 0x0f) - 1;
65 #ifdef IRIVER_H300_SERIES
66 /* Special kludge to coexist with the iriver firmware. The iriver firmware
67 stores the date as 1965+nn, and allows a range of 1980..2064. We use
68 1964+nn here to make leap years work correctly, so the date will be one
69 year off in the iriver firmware but at least won't be reset anymore. */
70 tm.tm_year = ((rtcbuf[6] & 0xf0) >> 4) * 10 + (rtcbuf[6] & 0x0f) + 64;
71 #else
72 tm.tm_year = ((rtcbuf[6] & 0xf0) >> 4) * 10 + (rtcbuf[6] & 0x0f) + 100;
73 #endif
75 tm.tm_yday = 0; /* Not implemented for now */
76 tm.tm_isdst = -1; /* Not implemented for now */
78 #else
79 tm.tm_sec = 0;
80 tm.tm_min = 0;
81 tm.tm_hour = 0;
82 tm.tm_mday = 1;
83 tm.tm_mon = 0;
84 tm.tm_year = 70;
85 tm.tm_wday = 1;
86 tm.tm_yday = 0; /* Not implemented for now */
87 tm.tm_isdst = -1; /* Not implemented for now */
88 #endif
89 return &tm;
90 #else
91 time_t now = time(NULL);
92 return localtime(&now);
93 #endif
96 int set_time(const struct tm *tm)
98 #if CONFIG_RTC
99 int rc;
100 char rtcbuf[7];
102 if (valid_time(tm))
104 rtcbuf[0]=((tm->tm_sec/10) << 4) | (tm->tm_sec%10);
105 rtcbuf[1]=((tm->tm_min/10) << 4) | (tm->tm_min%10);
106 rtcbuf[2]=((tm->tm_hour/10) << 4) | (tm->tm_hour%10);
107 rtcbuf[3]=tm->tm_wday;
108 rtcbuf[4]=((tm->tm_mday/10) << 4) | (tm->tm_mday%10);
109 rtcbuf[5]=(((tm->tm_mon+1)/10) << 4) | ((tm->tm_mon+1)%10);
110 #ifdef IRIVER_H300_SERIES
111 /* Iriver firmware compatibility kludge, see get_time(). */
112 rtcbuf[6]=(((tm->tm_year-64)/10) << 4) | ((tm->tm_year-64)%10);
113 #else
114 rtcbuf[6]=(((tm->tm_year-100)/10) << 4) | ((tm->tm_year-100)%10);
115 #endif
117 rc = rtc_write_datetime(rtcbuf);
119 if(rc)
120 return -1;
121 else
122 return 0;
124 else
126 return -2;
128 #else
129 (void)tm;
130 return 0;
131 #endif
134 #if CONFIG_RTC
135 /* mktime() code taken from lynx-2.8.5 source, written
136 by Philippe De Muyter <phdm@macqel.be> */
137 time_t mktime(struct tm *t)
139 short month, year;
140 time_t result;
141 static int m_to_d[12] =
142 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
144 month = t->tm_mon;
145 year = t->tm_year + month / 12 + 1900;
146 month %= 12;
147 if (month < 0)
149 year -= 1;
150 month += 12;
152 result = (year - 1970) * 365 + (year - 1969) / 4 + m_to_d[month];
153 result = (year - 1970) * 365 + m_to_d[month];
154 if (month <= 1)
155 year -= 1;
156 result += (year - 1968) / 4;
157 result -= (year - 1900) / 100;
158 result += (year - 1600) / 400;
159 result += t->tm_mday;
160 result -= 1;
161 result *= 24;
162 result += t->tm_hour;
163 result *= 60;
164 result += t->tm_min;
165 result *= 60;
166 result += t->tm_sec;
167 return(result);
169 #endif