diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/rtc/rtc_as3514.c | 127 |
1 files changed, 16 insertions, 111 deletions
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index 868fa9753b..a4d2eb13f7 100644 --- a/firmware/drivers/rtc/rtc_as3514.c +++ b/firmware/drivers/rtc/rtc_as3514.c | |||
@@ -23,34 +23,17 @@ | |||
23 | #include "rtc.h" | 23 | #include "rtc.h" |
24 | #include "as3514.h" | 24 | #include "as3514.h" |
25 | #include "ascodec.h" | 25 | #include "ascodec.h" |
26 | #include "time.h" | ||
26 | 27 | ||
27 | /* AMS Sansas start counting from Jan 1st 1970 instead of 1980 (not as3525v2) */ | 28 | /* AMS Sansas start counting from Jan 1st 1970 instead of 1980 (not as3525v2) */ |
28 | #if (CONFIG_CPU==AS3525) | 29 | #if (CONFIG_CPU==AS3525) |
29 | #define SECS_ADJUST 315532800 /* seconds between 1970-1-1 and 1980-1-1 */ | 30 | #define SECS_ADJUST 0 |
30 | #elif (CONFIG_CPU==AS3525v2) | 31 | #elif (CONFIG_CPU==AS3525v2) |
31 | #define SECS_ADJUST 315532800 - (2*365*24*3600) - 26*(24*3600) + 7*3600 + 25*60 | 32 | #define SECS_ADJUST ((2*365*24*3600) + 26*(24*3600) - 7*3600 - 25*60) |
32 | #else | 33 | #else |
33 | #define SECS_ADJUST 0 | 34 | #define SECS_ADJUST 315532800 /* 1980/1/1 */ |
34 | #endif | 35 | #endif |
35 | 36 | ||
36 | #define MINUTE_SECONDS 60 | ||
37 | #define HOUR_SECONDS 3600 | ||
38 | #define DAY_SECONDS 86400 | ||
39 | #define WEEK_SECONDS 604800 | ||
40 | #define YEAR_SECONDS 31536000 | ||
41 | #define LEAP_YEAR_SECONDS 31622400 | ||
42 | |||
43 | /* Days in each month */ | ||
44 | static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||
45 | |||
46 | static inline bool is_leapyear(int year) | ||
47 | { | ||
48 | if( ((year%4)==0) && (((year%100)!=0) || ((year%400)==0)) ) | ||
49 | return true; | ||
50 | else | ||
51 | return false; | ||
52 | } | ||
53 | |||
54 | #ifdef HAVE_RTC_ALARM /* as3543 */ | 37 | #ifdef HAVE_RTC_ALARM /* as3543 */ |
55 | static struct { | 38 | static struct { |
56 | unsigned int seconds; /* total seconds to wakeup */ | 39 | unsigned int seconds; /* total seconds to wakeup */ |
@@ -197,109 +180,31 @@ void rtc_init(void) | |||
197 | int rtc_read_datetime(struct tm *tm) | 180 | int rtc_read_datetime(struct tm *tm) |
198 | { | 181 | { |
199 | char tmp[4]; | 182 | char tmp[4]; |
200 | int i, year, mday, hour, min; | ||
201 | unsigned int seconds; | 183 | unsigned int seconds; |
184 | int i; | ||
202 | 185 | ||
203 | /* RTC_AS3514's slave address is 0x46*/ | 186 | /* Get seconds time stamp from RTC */ |
204 | for (i = 0; i < 4; i++){ | 187 | for (i = 0; i < 4; i++){ |
205 | tmp[i] = ascodec_read(AS3514_RTC_0 + i); | 188 | tmp[i] = ascodec_read(AS3514_RTC_0 + i); |
206 | } | 189 | } |
207 | seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24); | 190 | seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24); |
208 | seconds -= SECS_ADJUST; | ||
209 | 191 | ||
210 | /* Convert seconds since Jan-1-1980 to format compatible with | 192 | /* convert to struct tm */ |
211 | * get_time() from firmware/common/timefuncs.c */ | 193 | time_t time = seconds + SECS_ADJUST; |
194 | gmtime_r(&time, tm); | ||
212 | 195 | ||
213 | /* weekday */ | 196 | return 1; |
214 | tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; | ||
215 | |||
216 | /* Year */ | ||
217 | year = 1980; | ||
218 | while (seconds >= LEAP_YEAR_SECONDS) | ||
219 | { | ||
220 | if (is_leapyear(year)){ | ||
221 | seconds -= LEAP_YEAR_SECONDS; | ||
222 | } else { | ||
223 | seconds -= YEAR_SECONDS; | ||
224 | } | ||
225 | |||
226 | year++; | ||
227 | } | ||
228 | |||
229 | if (is_leapyear(year)) { | ||
230 | days_in_month[1] = 29; | ||
231 | } else { | ||
232 | days_in_month[1] = 28; | ||
233 | if(seconds>YEAR_SECONDS){ | ||
234 | year++; | ||
235 | seconds -= YEAR_SECONDS; | ||
236 | } | ||
237 | } | ||
238 | tm->tm_year = year%100 + 100; | ||
239 | |||
240 | /* Month */ | ||
241 | for (i = 0; i < 12; i++) | ||
242 | { | ||
243 | if (seconds < days_in_month[i]*DAY_SECONDS){ | ||
244 | tm->tm_mon = i; | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | seconds -= days_in_month[i]*DAY_SECONDS; | ||
249 | } | ||
250 | |||
251 | /* Month Day */ | ||
252 | mday = seconds/DAY_SECONDS; | ||
253 | seconds -= mday*DAY_SECONDS; | ||
254 | tm->tm_mday = mday + 1; /* 1 ... 31 */ | ||
255 | |||
256 | /* Hour */ | ||
257 | hour = seconds/HOUR_SECONDS; | ||
258 | seconds -= hour*HOUR_SECONDS; | ||
259 | tm->tm_hour = hour; | ||
260 | |||
261 | /* Minute */ | ||
262 | min = seconds/MINUTE_SECONDS; | ||
263 | seconds -= min*MINUTE_SECONDS; | ||
264 | tm->tm_min = min; | ||
265 | |||
266 | /* Second */ | ||
267 | tm->tm_sec = seconds; | ||
268 | |||
269 | return 7; | ||
270 | } | 197 | } |
271 | 198 | ||
272 | int rtc_write_datetime(const struct tm *tm) | 199 | int rtc_write_datetime(const struct tm *tm) |
273 | { | 200 | { |
274 | int i, year; | 201 | time_t time; |
275 | unsigned int year_days = 0; | 202 | unsigned int seconds; |
276 | unsigned int month_days = 0; | 203 | int i; |
277 | unsigned int seconds = 0; | ||
278 | |||
279 | year = 2000 + tm->tm_year - 100; | ||
280 | |||
281 | if(is_leapyear(year)) { | ||
282 | days_in_month[1] = 29; | ||
283 | } else { | ||
284 | days_in_month[1] = 28; | ||
285 | } | ||
286 | |||
287 | /* Number of days in months gone by this year*/ | ||
288 | for(i = 0; i < tm->tm_mon; i++){ | ||
289 | month_days += days_in_month[i]; | ||
290 | } | ||
291 | 204 | ||
292 | /* Number of days in years gone by since 1-Jan-1980 */ | 205 | /* convert struct tm to time stamp */ |
293 | year_days = 365*(tm->tm_year-100+20) + (tm->tm_year-100-1)/4 + 6; | 206 | time = mktime((struct tm *)tm); |
294 | 207 | seconds = time - SECS_ADJUST; | |
295 | /* Convert to seconds since 1-Jan-1980 */ | ||
296 | seconds = tm->tm_sec | ||
297 | + tm->tm_min*MINUTE_SECONDS | ||
298 | + tm->tm_hour*HOUR_SECONDS | ||
299 | + (tm->tm_mday-1)*DAY_SECONDS | ||
300 | + month_days*DAY_SECONDS | ||
301 | + year_days*DAY_SECONDS; | ||
302 | seconds += SECS_ADJUST; | ||
303 | 208 | ||
304 | /* Send data to RTC */ | 209 | /* Send data to RTC */ |
305 | for (i=0; i<4; i++){ | 210 | for (i=0; i<4; i++){ |