diff options
Diffstat (limited to 'firmware/drivers/rtc/rtc_mc13783.c')
-rw-r--r-- | firmware/drivers/rtc/rtc_mc13783.c | 77 |
1 files changed, 21 insertions, 56 deletions
diff --git a/firmware/drivers/rtc/rtc_mc13783.c b/firmware/drivers/rtc/rtc_mc13783.c index 15ed5b148b..e36faa6089 100644 --- a/firmware/drivers/rtc/rtc_mc13783.c +++ b/firmware/drivers/rtc/rtc_mc13783.c | |||
@@ -46,18 +46,6 @@ | |||
46 | #define RTC_BASE_YEAR 1970 | 46 | #define RTC_BASE_YEAR 1970 |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | enum rtc_buffer_field_indexes | ||
50 | { | ||
51 | RTC_I_SECONDS = 0, | ||
52 | RTC_I_MINUTES, | ||
53 | RTC_I_HOURS, | ||
54 | RTC_I_WEEKDAY, | ||
55 | RTC_I_DAY, | ||
56 | RTC_I_MONTH, | ||
57 | RTC_I_YEAR, | ||
58 | RTC_NUM_FIELDS, | ||
59 | }; | ||
60 | |||
61 | enum rtc_registers_indexes | 49 | enum rtc_registers_indexes |
62 | { | 50 | { |
63 | RTC_REG_TIME = 0, | 51 | RTC_REG_TIME = 0, |
@@ -82,26 +70,6 @@ static const unsigned char month_table[2][12] = | |||
82 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, | 70 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, |
83 | }; | 71 | }; |
84 | 72 | ||
85 | static inline void to_bcd(unsigned char *bcd, const unsigned char *buf, | ||
86 | int len) | ||
87 | { | ||
88 | while (len-- > 0) | ||
89 | { | ||
90 | unsigned char d = *buf++; | ||
91 | *bcd++ = ((d / 10) << 4) | (d % 10); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static inline void from_bcd(unsigned char *buf, const unsigned char *bcd, | ||
96 | int len) | ||
97 | { | ||
98 | while (len-- > 0) | ||
99 | { | ||
100 | unsigned char d = *bcd++; | ||
101 | *buf++ = ((d >> 4) & 0x0f) * 10 + (d & 0xf); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /* Get number of leaps since the reference date of 1601/01/01 */ | 73 | /* Get number of leaps since the reference date of 1601/01/01 */ |
106 | static int get_leap_count(int d) | 74 | static int get_leap_count(int d) |
107 | { | 75 | { |
@@ -127,10 +95,10 @@ void rtc_init(void) | |||
127 | } | 95 | } |
128 | } | 96 | } |
129 | 97 | ||
130 | int rtc_read_datetime(unsigned char* buf) | 98 | int rtc_read_datetime(struct tm *tm) |
131 | { | 99 | { |
132 | uint32_t regs[RTC_NUM_REGS]; | 100 | uint32_t regs[RTC_NUM_REGS]; |
133 | int year, leap, month, day; | 101 | int year, leap, month, day, hour, min; |
134 | 102 | ||
135 | /* Read time, day, time - 2nd read of time should be the same or | 103 | /* Read time, day, time - 2nd read of time should be the same or |
136 | * greater */ | 104 | * greater */ |
@@ -147,19 +115,21 @@ int rtc_read_datetime(unsigned char* buf) | |||
147 | while (regs[RTC_REG_TIME2] < regs[RTC_REG_TIME]); | 115 | while (regs[RTC_REG_TIME2] < regs[RTC_REG_TIME]); |
148 | 116 | ||
149 | /* TOD: = 0 to 86399 */ | 117 | /* TOD: = 0 to 86399 */ |
150 | buf[RTC_I_HOURS] = regs[RTC_REG_TIME] / 3600; | 118 | hour = regs[RTC_REG_TIME] / 3600; |
151 | regs[RTC_REG_TIME] -= buf[RTC_I_HOURS]*3600; | 119 | regs[RTC_REG_TIME] -= hour*3600; |
120 | tm->tm_hour = hour; | ||
152 | 121 | ||
153 | buf[RTC_I_MINUTES] = regs[RTC_REG_TIME] / 60; | 122 | min = regs[RTC_REG_TIME] / 60; |
154 | regs[RTC_REG_TIME] -= buf[RTC_I_MINUTES]*60; | 123 | regs[RTC_REG_TIME] -= min*60; |
124 | tm->tm_min = min; | ||
155 | 125 | ||
156 | buf[RTC_I_SECONDS] = regs[RTC_REG_TIME]; | 126 | tm->tm_sec = regs[RTC_REG_TIME]; |
157 | 127 | ||
158 | /* DAY: 0 to 32767 */ | 128 | /* DAY: 0 to 32767 */ |
159 | day = regs[RTC_REG_DAY] + RTC_BASE_DAY_COUNT; | 129 | day = regs[RTC_REG_DAY] + RTC_BASE_DAY_COUNT; |
160 | 130 | ||
161 | /* Weekday */ | 131 | /* Weekday */ |
162 | buf[RTC_I_WEEKDAY] = (day + 1) % 7; /* 1601/01/01 = Monday */ | 132 | tm->tm_wday = (day + 1) % 7; /* 1601/01/01 = Monday */ |
163 | 133 | ||
164 | /* Get number of leaps for today */ | 134 | /* Get number of leaps for today */ |
165 | leap = get_leap_count(day); | 135 | leap = get_leap_count(day); |
@@ -186,28 +156,23 @@ int rtc_read_datetime(unsigned char* buf) | |||
186 | day -= days; | 156 | day -= days; |
187 | } | 157 | } |
188 | 158 | ||
189 | buf[RTC_I_DAY] = day + 1; /* 1 to 31 */ | 159 | tm->tm_mday = day + 1; /* 1 to 31 */ |
190 | buf[RTC_I_MONTH] = month + 1; /* 1 to 12 */ | 160 | tm->tm_mon = month; /* 0 to 11 */ |
191 | buf[RTC_I_YEAR] = year % 100; | 161 | tm->tm_year = year % 100 + 100; |
192 | |||
193 | to_bcd(buf, buf, RTC_NUM_FIELDS); | ||
194 | 162 | ||
195 | return 7; | 163 | return 7; |
196 | } | 164 | } |
197 | 165 | ||
198 | int rtc_write_datetime(unsigned char* buf) | 166 | int rtc_write_datetime(const struct tm *tm) |
199 | { | 167 | { |
200 | uint32_t regs[2]; | 168 | uint32_t regs[2]; |
201 | unsigned char fld[RTC_NUM_FIELDS]; | ||
202 | int year, leap, month, day, i, base_yearday; | 169 | int year, leap, month, day, i, base_yearday; |
203 | 170 | ||
204 | from_bcd(fld, buf, RTC_NUM_FIELDS); | 171 | regs[RTC_REG_TIME] = tm->tm_sec + |
205 | 172 | tm->tm_min*60 + | |
206 | regs[RTC_REG_TIME] = fld[RTC_I_SECONDS] + | 173 | tm->tm_hour*3600; |
207 | fld[RTC_I_MINUTES]*60 + | ||
208 | fld[RTC_I_HOURS]*3600; | ||
209 | 174 | ||
210 | year = fld[RTC_I_YEAR]; | 175 | year = tm->tm_year - 100; |
211 | 176 | ||
212 | if (year < RTC_BASE_YEAR - 1900) | 177 | if (year < RTC_BASE_YEAR - 1900) |
213 | year += 2000; | 178 | year += 2000; |
@@ -230,18 +195,18 @@ int rtc_write_datetime(unsigned char* buf) | |||
230 | /* Find the number of days passed this year up to the 1st of the | 195 | /* Find the number of days passed this year up to the 1st of the |
231 | * month. */ | 196 | * month. */ |
232 | leap = is_leap_year(year); | 197 | leap = is_leap_year(year); |
233 | month = fld[RTC_I_MONTH] - 1; | 198 | month = tm->tm_mon; |
234 | 199 | ||
235 | for (i = 0; i < month; i++) | 200 | for (i = 0; i < month; i++) |
236 | { | 201 | { |
237 | day += month_table[leap][i]; | 202 | day += month_table[leap][i]; |
238 | } | 203 | } |
239 | 204 | ||
240 | regs[RTC_REG_DAY] = day + fld[RTC_I_DAY] - 1 - base_yearday; | 205 | regs[RTC_REG_DAY] = day + tm->tm_mday - 1 - base_yearday; |
241 | 206 | ||
242 | if (mc13783_write_regset(rtc_registers, regs, 2) == 2) | 207 | if (mc13783_write_regset(rtc_registers, regs, 2) == 2) |
243 | { | 208 | { |
244 | return RTC_NUM_FIELDS; | 209 | return 7; |
245 | } | 210 | } |
246 | 211 | ||
247 | return 0; | 212 | return 0; |