diff options
Diffstat (limited to 'firmware/drivers/rtc/rtc_as3514.c')
-rw-r--r-- | firmware/drivers/rtc/rtc_as3514.c | 92 |
1 files changed, 41 insertions, 51 deletions
diff --git a/firmware/drivers/rtc/rtc_as3514.c b/firmware/drivers/rtc/rtc_as3514.c index d0c4cd7c17..159a0456a3 100644 --- a/firmware/drivers/rtc/rtc_as3514.c +++ b/firmware/drivers/rtc/rtc_as3514.c @@ -38,9 +38,6 @@ #define YEAR_SECONDS 31536000 #define LEAP_YEAR_SECONDS 31622400 -#define BCD2DEC(X) (((((X)>>4) & 0x0f) * 10) + ((X) & 0xf)) -#define DEC2BCD(X) ((((X)/10)<<4) | ((X)%10)) - /* Days in each month */ static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -56,31 +53,30 @@ void rtc_init(void) { } -int rtc_read_datetime(unsigned char* buf) +int rtc_read_datetime(struct tm *tm) { char tmp[4]; - int year; - int i; + int i, year, mday, hour, min; unsigned int seconds; - + /* RTC_AS3514's slave address is 0x46*/ - for (i=0;i<4;i++){ + for (i = 0; i < 4; i++){ tmp[i] = ascodec_read(AS3514_RTC_0 + i); } seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24); seconds -= SECS_ADJUST; - + /* Convert seconds since Jan-1-1980 to format compatible with * get_time() from firmware/common/timefuncs.c */ - + /* weekday */ - buf[3] = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; - + tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; + /* Year */ year = 1980; - while(seconds>=LEAP_YEAR_SECONDS) + while (seconds >= LEAP_YEAR_SECONDS) { - if(is_leapyear(year)){ + if (is_leapyear(year)){ seconds -= LEAP_YEAR_SECONDS; } else { seconds -= YEAR_SECONDS; @@ -88,8 +84,8 @@ int rtc_read_datetime(unsigned char* buf) year++; } - - if(is_leapyear(year)) { + + if (is_leapyear(year)) { days_in_month[1] = 29; } else { days_in_month[1] = 28; @@ -98,54 +94,48 @@ int rtc_read_datetime(unsigned char* buf) seconds -= YEAR_SECONDS; } } - buf[6] = year%100; - + tm->tm_year = year%100 + 100; + /* Month */ - for(i=0; i<12; i++) + for (i = 0; i < 12; i++) { - if(seconds < days_in_month[i]*DAY_SECONDS){ - buf[5] = i+1; + if (seconds < days_in_month[i]*DAY_SECONDS){ + tm->tm_mon = i; break; } - + seconds -= days_in_month[i]*DAY_SECONDS; } - + /* Month Day */ - buf[4] = seconds/DAY_SECONDS; - seconds -= buf[4]*DAY_SECONDS; - buf[4]++; /* 1 ... 31 */ + mday = seconds/DAY_SECONDS; + seconds -= mday*DAY_SECONDS; + tm->tm_mday = mday + 1; /* 1 ... 31 */ /* Hour */ - buf[2] = seconds/HOUR_SECONDS; - seconds -= buf[2]*HOUR_SECONDS; - + hour = seconds/HOUR_SECONDS; + seconds -= hour*HOUR_SECONDS; + tm->tm_hour = hour; + /* Minute */ - buf[1] = seconds/MINUTE_SECONDS; - seconds -= buf[1]*MINUTE_SECONDS; - + min = seconds/MINUTE_SECONDS; + seconds -= min*MINUTE_SECONDS; + tm->tm_min = min; + /* Second */ - buf[0] = seconds; - - /* Convert to Binary Coded Decimal format */ - for(i=0; i<7; i++) - buf[i] = DEC2BCD(buf[i]); - + tm->tm_sec = seconds; + return 7; } -int rtc_write_datetime(unsigned char* buf) +int rtc_write_datetime(const struct tm *tm) { int i, year; unsigned int year_days = 0; unsigned int month_days = 0; unsigned int seconds = 0; - - /* Convert from Binary Coded Decimal format */ - for(i=0; i<7; i++) - buf[i] = BCD2DEC(buf[i]); - year = 2000 + buf[6]; + year = 2000 + tm->tm_year - 100; if(is_leapyear(year)) { days_in_month[1] = 29; @@ -154,24 +144,24 @@ int rtc_write_datetime(unsigned char* buf) } /* Number of days in months gone by this year*/ - for(i=0; i<(buf[5]-1); i++){ + for(i = 0; i < tm->tm_mon; i++){ month_days += days_in_month[i]; } /* Number of days in years gone by since 1-Jan-1980 */ - year_days = 365*(buf[6]+20) + (buf[6]-1)/4 + 6; + year_days = 365*(tm->tm_year+20) + (tm->tm_year-1)/4 + 6; /* Convert to seconds since 1-Jan-1980 */ - seconds = buf[0] - + buf[1]*MINUTE_SECONDS - + buf[2]*HOUR_SECONDS - + (buf[4]-1)*DAY_SECONDS + seconds = tm->tm_sec + + tm->tm_min*MINUTE_SECONDS + + tm->tm_hour*HOUR_SECONDS + + (tm->tm_mday-1)*DAY_SECONDS + month_days*DAY_SECONDS + year_days*DAY_SECONDS; seconds += SECS_ADJUST; /* Send data to RTC */ - for (i=0;i<4;i++){ + for (i=0; i<4; i++){ ascodec_write(AS3514_RTC_0 + i, ((seconds >> (8 * i)) & 0xff)); } return 1; |