diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/rtc/rtc_imx233.c | 120 |
1 files changed, 10 insertions, 110 deletions
diff --git a/firmware/drivers/rtc/rtc_imx233.c b/firmware/drivers/rtc/rtc_imx233.c index 9e62476be6..f2484fa72a 100644 --- a/firmware/drivers/rtc/rtc_imx233.c +++ b/firmware/drivers/rtc/rtc_imx233.c | |||
@@ -19,34 +19,14 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | ||
23 | #include "time.h" | ||
22 | #include "system.h" | 24 | #include "system.h" |
23 | #include "rtc.h" | 25 | #include "rtc.h" |
24 | #include "timefuncs.h" | 26 | #include "timefuncs.h" |
25 | #include "rtc-imx233.h" | 27 | #include "rtc-imx233.h" |
26 | 28 | ||
27 | #if defined(SANSA_FUZEPLUS) | 29 | #define YEAR1980 315532800 /* 1980/1/1 00:00:00 in UTC */ |
28 | #define SECS_ADJUST 315532800 /* seconds between 1970-1-1 and 1980-1-1 */ | ||
29 | #else | ||
30 | #define SECS_ADJUST 0 | ||
31 | #endif | ||
32 | |||
33 | #define MINUTE_SECONDS 60 | ||
34 | #define HOUR_SECONDS 3600 | ||
35 | #define DAY_SECONDS 86400 | ||
36 | #define WEEK_SECONDS 604800 | ||
37 | #define YEAR_SECONDS 31536000 | ||
38 | #define LEAP_YEAR_SECONDS 31622400 | ||
39 | |||
40 | /* Days in each month */ | ||
41 | static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||
42 | |||
43 | static inline bool is_leapyear(int year) | ||
44 | { | ||
45 | if( ((year%4)==0) && (((year%100)!=0) || ((year%400)==0)) ) | ||
46 | return true; | ||
47 | else | ||
48 | return false; | ||
49 | } | ||
50 | 30 | ||
51 | void rtc_init(void) | 31 | void rtc_init(void) |
52 | { | 32 | { |
@@ -55,7 +35,7 @@ void rtc_init(void) | |||
55 | 35 | ||
56 | int rtc_read_datetime(struct tm *tm) | 36 | int rtc_read_datetime(struct tm *tm) |
57 | { | 37 | { |
58 | uint32_t seconds = imx233_rtc_read_seconds() - SECS_ADJUST; | 38 | uint32_t seconds = imx233_rtc_read_seconds(); |
59 | #ifdef SANSA_FUZEPLUS | 39 | #ifdef SANSA_FUZEPLUS |
60 | /* The OF uses PERSISTENT2 register to keep the adjustment and only changes | 40 | /* The OF uses PERSISTENT2 register to keep the adjustment and only changes |
61 | * SECONDS if necessary. */ | 41 | * SECONDS if necessary. */ |
@@ -63,100 +43,19 @@ int rtc_read_datetime(struct tm *tm) | |||
63 | #else | 43 | #else |
64 | /* The Freescale recommended way of keeping time is the number of seconds | 44 | /* The Freescale recommended way of keeping time is the number of seconds |
65 | * since 00:00 1/1/1980 */ | 45 | * since 00:00 1/1/1980 */ |
46 | seconds += YEAR1980; | ||
66 | #endif | 47 | #endif |
67 | 48 | ||
68 | /* Convert seconds since 00:00 1/1/xxxx (xxxx=year) */ | 49 | gmtime_r(&seconds, tm); |
69 | |||
70 | /* weekday */ | ||
71 | tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; | ||
72 | |||
73 | /* Year */ | ||
74 | int year = 1980; | ||
75 | while(seconds >= LEAP_YEAR_SECONDS) | ||
76 | { | ||
77 | if(is_leapyear(year)) | ||
78 | seconds -= LEAP_YEAR_SECONDS; | ||
79 | else | ||
80 | seconds -= YEAR_SECONDS; | ||
81 | |||
82 | year++; | ||
83 | } | ||
84 | |||
85 | if(is_leapyear(year)) | ||
86 | days_in_month[1] = 29; | ||
87 | else | ||
88 | { | ||
89 | days_in_month[1] = 28; | ||
90 | if(seconds>YEAR_SECONDS) | ||
91 | { | ||
92 | year++; | ||
93 | seconds -= YEAR_SECONDS; | ||
94 | } | ||
95 | } | ||
96 | tm->tm_year = year % 100 + 100; | ||
97 | |||
98 | /* Month */ | ||
99 | for(int i = 0; i < 12; i++) | ||
100 | { | ||
101 | if(seconds < days_in_month[i] * DAY_SECONDS) | ||
102 | { | ||
103 | tm->tm_mon = i; | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | seconds -= days_in_month[i] * DAY_SECONDS; | ||
108 | } | ||
109 | |||
110 | /* Month Day */ | ||
111 | int mday = seconds / DAY_SECONDS; | ||
112 | seconds -= mday * DAY_SECONDS; | ||
113 | tm->tm_mday = mday + 1; /* 1 ... 31 */ | ||
114 | |||
115 | /* Hour */ | ||
116 | int hour = seconds / HOUR_SECONDS; | ||
117 | seconds -= hour*HOUR_SECONDS; | ||
118 | tm->tm_hour = hour; | ||
119 | |||
120 | /* Minute */ | ||
121 | int min = seconds / MINUTE_SECONDS; | ||
122 | seconds -= min*MINUTE_SECONDS; | ||
123 | tm->tm_min = min; | ||
124 | |||
125 | /* Second */ | ||
126 | tm->tm_sec = seconds; | ||
127 | 50 | ||
128 | return 0; | 51 | return 0; |
129 | } | 52 | } |
130 | 53 | ||
131 | int rtc_write_datetime(const struct tm *tm) | 54 | int rtc_write_datetime(const struct tm *tm) |
132 | { | 55 | { |
133 | int i, year; | 56 | uint32_t seconds; |
134 | unsigned int year_days = 0; | ||
135 | unsigned int month_days = 0; | ||
136 | unsigned int seconds = 0; | ||
137 | 57 | ||
138 | year = 2000 + tm->tm_year - 100; | 58 | seconds = mktime((struct tm *)tm); |
139 | |||
140 | if(is_leapyear(year)) | ||
141 | days_in_month[1] = 29; | ||
142 | else | ||
143 | days_in_month[1] = 28; | ||
144 | |||
145 | /* Number of days in months gone by this year*/ | ||
146 | for(i = 0; i < tm->tm_mon; i++) | ||
147 | month_days += days_in_month[i]; | ||
148 | |||
149 | /* Number of days in years gone by since 1-Jan-1980 */ | ||
150 | year_days = 365*(tm->tm_year-100+20) + (tm->tm_year-100-1)/4 + 6; | ||
151 | |||
152 | /* Convert to seconds since 1-Jan-1980 */ | ||
153 | seconds = tm->tm_sec | ||
154 | + tm->tm_min*MINUTE_SECONDS | ||
155 | + tm->tm_hour*HOUR_SECONDS | ||
156 | + (tm->tm_mday-1)*DAY_SECONDS | ||
157 | + month_days*DAY_SECONDS | ||
158 | + year_days*DAY_SECONDS; | ||
159 | seconds += SECS_ADJUST; | ||
160 | 59 | ||
161 | #ifdef SANSA_FUZEPLUS | 60 | #ifdef SANSA_FUZEPLUS |
162 | /* The OF uses PERSISTENT2 register to keep the adjustment and only changes | 61 | /* The OF uses PERSISTENT2 register to keep the adjustment and only changes |
@@ -168,8 +67,9 @@ int rtc_write_datetime(const struct tm *tm) | |||
168 | #else | 67 | #else |
169 | /* The Freescale recommended way of keeping time is the number of seconds | 68 | /* The Freescale recommended way of keeping time is the number of seconds |
170 | * since 00:00 1/1/1980 */ | 69 | * since 00:00 1/1/1980 */ |
171 | imx233_rtc_write_seconds(seconds); | 70 | imx233_rtc_write_seconds(seconds - YEAR1980); |
172 | #endif | 71 | #endif |
72 | |||
173 | return 0; | 73 | return 0; |
174 | } | 74 | } |
175 | 75 | ||