summaryrefslogtreecommitdiff
path: root/firmware/drivers/rtc/rtc_as3514.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/rtc/rtc_as3514.c')
-rw-r--r--firmware/drivers/rtc/rtc_as3514.c127
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 */
44static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
45
46static 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 */
55static struct { 38static 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)
197int rtc_read_datetime(struct tm *tm) 180int 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
272int rtc_write_datetime(const struct tm *tm) 199int 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++){