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.c92
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 @@
38#define YEAR_SECONDS 31536000 38#define YEAR_SECONDS 31536000
39#define LEAP_YEAR_SECONDS 31622400 39#define LEAP_YEAR_SECONDS 31622400
40 40
41#define BCD2DEC(X) (((((X)>>4) & 0x0f) * 10) + ((X) & 0xf))
42#define DEC2BCD(X) ((((X)/10)<<4) | ((X)%10))
43
44/* Days in each month */ 41/* Days in each month */
45static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 42static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
46 43
@@ -56,31 +53,30 @@ void rtc_init(void)
56{ 53{
57} 54}
58 55
59int rtc_read_datetime(unsigned char* buf) 56int rtc_read_datetime(struct tm *tm)
60{ 57{
61 char tmp[4]; 58 char tmp[4];
62 int year; 59 int i, year, mday, hour, min;
63 int i;
64 unsigned int seconds; 60 unsigned int seconds;
65 61
66 /* RTC_AS3514's slave address is 0x46*/ 62 /* RTC_AS3514's slave address is 0x46*/
67 for (i=0;i<4;i++){ 63 for (i = 0; i < 4; i++){
68 tmp[i] = ascodec_read(AS3514_RTC_0 + i); 64 tmp[i] = ascodec_read(AS3514_RTC_0 + i);
69 } 65 }
70 seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24); 66 seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24);
71 seconds -= SECS_ADJUST; 67 seconds -= SECS_ADJUST;
72 68
73 /* Convert seconds since Jan-1-1980 to format compatible with 69 /* Convert seconds since Jan-1-1980 to format compatible with
74 * get_time() from firmware/common/timefuncs.c */ 70 * get_time() from firmware/common/timefuncs.c */
75 71
76 /* weekday */ 72 /* weekday */
77 buf[3] = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7; 73 tm->tm_wday = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7;
78 74
79 /* Year */ 75 /* Year */
80 year = 1980; 76 year = 1980;
81 while(seconds>=LEAP_YEAR_SECONDS) 77 while (seconds >= LEAP_YEAR_SECONDS)
82 { 78 {
83 if(is_leapyear(year)){ 79 if (is_leapyear(year)){
84 seconds -= LEAP_YEAR_SECONDS; 80 seconds -= LEAP_YEAR_SECONDS;
85 } else { 81 } else {
86 seconds -= YEAR_SECONDS; 82 seconds -= YEAR_SECONDS;
@@ -88,8 +84,8 @@ int rtc_read_datetime(unsigned char* buf)
88 84
89 year++; 85 year++;
90 } 86 }
91 87
92 if(is_leapyear(year)) { 88 if (is_leapyear(year)) {
93 days_in_month[1] = 29; 89 days_in_month[1] = 29;
94 } else { 90 } else {
95 days_in_month[1] = 28; 91 days_in_month[1] = 28;
@@ -98,54 +94,48 @@ int rtc_read_datetime(unsigned char* buf)
98 seconds -= YEAR_SECONDS; 94 seconds -= YEAR_SECONDS;
99 } 95 }
100 } 96 }
101 buf[6] = year%100; 97 tm->tm_year = year%100 + 100;
102 98
103 /* Month */ 99 /* Month */
104 for(i=0; i<12; i++) 100 for (i = 0; i < 12; i++)
105 { 101 {
106 if(seconds < days_in_month[i]*DAY_SECONDS){ 102 if (seconds < days_in_month[i]*DAY_SECONDS){
107 buf[5] = i+1; 103 tm->tm_mon = i;
108 break; 104 break;
109 } 105 }
110 106
111 seconds -= days_in_month[i]*DAY_SECONDS; 107 seconds -= days_in_month[i]*DAY_SECONDS;
112 } 108 }
113 109
114 /* Month Day */ 110 /* Month Day */
115 buf[4] = seconds/DAY_SECONDS; 111 mday = seconds/DAY_SECONDS;
116 seconds -= buf[4]*DAY_SECONDS; 112 seconds -= mday*DAY_SECONDS;
117 buf[4]++; /* 1 ... 31 */ 113 tm->tm_mday = mday + 1; /* 1 ... 31 */
118 114
119 /* Hour */ 115 /* Hour */
120 buf[2] = seconds/HOUR_SECONDS; 116 hour = seconds/HOUR_SECONDS;
121 seconds -= buf[2]*HOUR_SECONDS; 117 seconds -= hour*HOUR_SECONDS;
122 118 tm->tm_hour = hour;
119
123 /* Minute */ 120 /* Minute */
124 buf[1] = seconds/MINUTE_SECONDS; 121 min = seconds/MINUTE_SECONDS;
125 seconds -= buf[1]*MINUTE_SECONDS; 122 seconds -= min*MINUTE_SECONDS;
126 123 tm->tm_min = min;
124
127 /* Second */ 125 /* Second */
128 buf[0] = seconds; 126 tm->tm_sec = seconds;
129 127
130 /* Convert to Binary Coded Decimal format */
131 for(i=0; i<7; i++)
132 buf[i] = DEC2BCD(buf[i]);
133
134 return 7; 128 return 7;
135} 129}
136 130
137int rtc_write_datetime(unsigned char* buf) 131int rtc_write_datetime(const struct tm *tm)
138{ 132{
139 int i, year; 133 int i, year;
140 unsigned int year_days = 0; 134 unsigned int year_days = 0;
141 unsigned int month_days = 0; 135 unsigned int month_days = 0;
142 unsigned int seconds = 0; 136 unsigned int seconds = 0;
143
144 /* Convert from Binary Coded Decimal format */
145 for(i=0; i<7; i++)
146 buf[i] = BCD2DEC(buf[i]);
147 137
148 year = 2000 + buf[6]; 138 year = 2000 + tm->tm_year - 100;
149 139
150 if(is_leapyear(year)) { 140 if(is_leapyear(year)) {
151 days_in_month[1] = 29; 141 days_in_month[1] = 29;
@@ -154,24 +144,24 @@ int rtc_write_datetime(unsigned char* buf)
154 } 144 }
155 145
156 /* Number of days in months gone by this year*/ 146 /* Number of days in months gone by this year*/
157 for(i=0; i<(buf[5]-1); i++){ 147 for(i = 0; i < tm->tm_mon; i++){
158 month_days += days_in_month[i]; 148 month_days += days_in_month[i];
159 } 149 }
160 150
161 /* Number of days in years gone by since 1-Jan-1980 */ 151 /* Number of days in years gone by since 1-Jan-1980 */
162 year_days = 365*(buf[6]+20) + (buf[6]-1)/4 + 6; 152 year_days = 365*(tm->tm_year+20) + (tm->tm_year-1)/4 + 6;
163 153
164 /* Convert to seconds since 1-Jan-1980 */ 154 /* Convert to seconds since 1-Jan-1980 */
165 seconds = buf[0] 155 seconds = tm->tm_sec
166 + buf[1]*MINUTE_SECONDS 156 + tm->tm_min*MINUTE_SECONDS
167 + buf[2]*HOUR_SECONDS 157 + tm->tm_hour*HOUR_SECONDS
168 + (buf[4]-1)*DAY_SECONDS 158 + (tm->tm_mday-1)*DAY_SECONDS
169 + month_days*DAY_SECONDS 159 + month_days*DAY_SECONDS
170 + year_days*DAY_SECONDS; 160 + year_days*DAY_SECONDS;
171 seconds += SECS_ADJUST; 161 seconds += SECS_ADJUST;
172 162
173 /* Send data to RTC */ 163 /* Send data to RTC */
174 for (i=0;i<4;i++){ 164 for (i=0; i<4; i++){
175 ascodec_write(AS3514_RTC_0 + i, ((seconds >> (8 * i)) & 0xff)); 165 ascodec_write(AS3514_RTC_0 + i, ((seconds >> (8 * i)) & 0xff));
176 } 166 }
177 return 1; 167 return 1;