34
34
#define RTC_MONTH 0x08
35
35
#define RTC_YEAR 0x09
36
36
37
+ /* Y2K Bugfix */
38
+ #define RTC_CENTURY 0x32
39
+
37
40
/* Alarm time indices in RTC RAM */
38
41
#define RTC_ALARM_SEC 0x01
39
42
#define RTC_ALARM_MIN 0x03
106
109
#define MIN_WDAY 1
107
110
#define MAX_MDAY 31
108
111
#define MIN_MDAY 1
109
- #define MAX_MON 11
110
- #define MIN_MON 0
112
+ #define MAX_MON 12
113
+ #define MIN_MON 1
111
114
#define MIN_YEAR_DIFF 0 /* YEAR - 1900 */
112
- #define MAX_YEAR_DIFF 199 /* YEAR - 1900 */
115
+ #define MAX_YEAR_DIFF 99 /* YEAR - 1999 */
113
116
114
117
struct rtc_mc146818_data {
115
118
struct k_spinlock lock ;
@@ -149,16 +152,16 @@ static bool rtc_mc146818_validate_time(const struct rtc_time *timeptr)
149
152
if (timeptr -> tm_hour < MIN_HOUR || timeptr -> tm_hour > MAX_HOUR ) {
150
153
return false;
151
154
}
152
- if (timeptr -> tm_wday < MIN_WDAY || timeptr -> tm_wday > MAX_WDAY ) {
155
+ if (timeptr -> tm_wday + 1 < MIN_WDAY || timeptr -> tm_wday + 1 > MAX_WDAY ) {
153
156
return false;
154
157
}
155
158
if (timeptr -> tm_mday < MIN_MDAY || timeptr -> tm_mday > MAX_MDAY ) {
156
159
return false;
157
160
}
158
- if (timeptr -> tm_mon < MIN_MON || timeptr -> tm_mon > MAX_MON ) {
161
+ if (timeptr -> tm_mon + 1 < MIN_MON || timeptr -> tm_mon + 1 > MAX_MON ) {
159
162
return false;
160
163
}
161
- if (timeptr -> tm_year < MIN_YEAR_DIFF || timeptr -> tm_year > MAX_YEAR_DIFF ) {
164
+ if (timeptr -> tm_year - 70 < MIN_YEAR_DIFF || timeptr -> tm_year - 70 > MAX_YEAR_DIFF ) {
162
165
return false;
163
166
}
164
167
return true;
@@ -168,6 +171,8 @@ static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time
168
171
{
169
172
struct rtc_mc146818_data * const dev_data = dev -> data ;
170
173
uint8_t value ;
174
+ int year ;
175
+ int cent ;
171
176
int ret ;
172
177
173
178
k_spinlock_key_t key = k_spin_lock (& dev_data -> lock );
@@ -186,22 +191,27 @@ static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time
186
191
value = rtc_read (RTC_DATA );
187
192
rtc_write (RTC_DATA , value | RTC_UCI_BIT );
188
193
194
+ year = (1970 + timeptr -> tm_year ) % 100 ;
195
+ cent = (1970 + timeptr -> tm_year ) / 100 ;
196
+
189
197
if (!(rtc_read (RTC_DATA ) & RTC_DMODE_BIT )) {
190
198
rtc_write (RTC_SEC , (uint8_t )bin2bcd (timeptr -> tm_sec ));
191
199
rtc_write (RTC_MIN , (uint8_t )bin2bcd (timeptr -> tm_min ));
192
200
rtc_write (RTC_HOUR , (uint8_t )bin2bcd (timeptr -> tm_hour ));
193
201
rtc_write (RTC_WDAY , (uint8_t )bin2bcd (timeptr -> tm_wday ));
194
202
rtc_write (RTC_MDAY , (uint8_t )bin2bcd (timeptr -> tm_mday ));
195
203
rtc_write (RTC_MONTH , (uint8_t )bin2bcd (timeptr -> tm_mon + 1 ));
196
- rtc_write (RTC_YEAR , (uint8_t )bin2bcd (timeptr -> tm_year ));
204
+ rtc_write (RTC_YEAR , (uint8_t )bin2bcd (year ));
205
+ rtc_write (RTC_CENTURY , (uint8_t )bin2bcd (cent ));
197
206
} else {
198
207
rtc_write (RTC_SEC , (uint8_t )timeptr -> tm_sec );
199
208
rtc_write (RTC_MIN , (uint8_t )timeptr -> tm_min );
200
209
rtc_write (RTC_HOUR , (uint8_t )timeptr -> tm_hour );
201
210
rtc_write (RTC_WDAY , (uint8_t )timeptr -> tm_wday );
202
211
rtc_write (RTC_MDAY , (uint8_t )timeptr -> tm_mday );
203
212
rtc_write (RTC_MONTH , (uint8_t )timeptr -> tm_mon + 1 );
204
- rtc_write (RTC_YEAR , (uint8_t )timeptr -> tm_year );
213
+ rtc_write (RTC_YEAR , year );
214
+ rtc_write (RTC_CENTURY , cent );
205
215
}
206
216
207
217
if (timeptr -> tm_isdst == 1 ) {
@@ -221,6 +231,8 @@ static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *tim
221
231
{
222
232
struct rtc_mc146818_data * const dev_data = dev -> data ;
223
233
int ret ;
234
+ uint8_t cent ;
235
+ uint8_t year ;
224
236
uint8_t value ;
225
237
226
238
k_spinlock_key_t key = k_spin_lock (& dev_data -> lock );
@@ -239,16 +251,18 @@ static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *tim
239
251
while (rtc_read (RTC_UIP ) & RTC_UIP_BIT ) {
240
252
continue ;
241
253
}
242
- timeptr -> tm_year = rtc_read (RTC_YEAR );
254
+ cent = rtc_read (RTC_CENTURY );
255
+ year = rtc_read (RTC_YEAR );
243
256
timeptr -> tm_mon = rtc_read (RTC_MONTH ) - 1 ;
244
257
timeptr -> tm_mday = rtc_read (RTC_MDAY );
245
- timeptr -> tm_wday = rtc_read (RTC_WDAY );
258
+ timeptr -> tm_wday = rtc_read (RTC_WDAY ) - 1 ;
246
259
timeptr -> tm_hour = rtc_read (RTC_HOUR );
247
260
timeptr -> tm_min = rtc_read (RTC_MIN );
248
261
timeptr -> tm_sec = rtc_read (RTC_SEC );
249
262
250
263
if (!(rtc_read (RTC_DATA ) & RTC_DMODE_BIT )) {
251
- timeptr -> tm_year = bcd2bin (timeptr -> tm_year );
264
+ year = bcd2bin (year );
265
+ cent = bcd2bin (cent );
252
266
timeptr -> tm_mon = bcd2bin (timeptr -> tm_mon );
253
267
timeptr -> tm_mday = bcd2bin (timeptr -> tm_mday );
254
268
timeptr -> tm_wday = bcd2bin (timeptr -> tm_wday );
@@ -257,6 +271,8 @@ static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *tim
257
271
timeptr -> tm_sec = bcd2bin (timeptr -> tm_sec );
258
272
}
259
273
274
+ timeptr -> tm_year = 100 * (int )cent + year - 1970 ;
275
+
260
276
timeptr -> tm_nsec = 0 ;
261
277
timeptr -> tm_yday = 0 ;
262
278
value = rtc_read (RTC_DATA );
@@ -296,7 +312,7 @@ static bool rtc_mc146818_validate_alarm(const struct rtc_time *timeptr, uint32_t
296
312
}
297
313
298
314
if ((mask & RTC_ALARM_TIME_MASK_MONTH ) &&
299
- (timeptr -> tm_mon < MIN_WDAY || timeptr -> tm_mon > MAX_WDAY )) {
315
+ (timeptr -> tm_mon + 1 < MIN_WDAY || timeptr -> tm_mon + 1 > MAX_WDAY )) {
300
316
return false;
301
317
}
302
318
@@ -306,7 +322,7 @@ static bool rtc_mc146818_validate_alarm(const struct rtc_time *timeptr, uint32_t
306
322
}
307
323
308
324
if ((mask & RTC_ALARM_TIME_MASK_YEAR ) &&
309
- (timeptr -> tm_year < MIN_YEAR_DIFF || timeptr -> tm_year > MAX_YEAR_DIFF )) {
325
+ (timeptr -> tm_year - 70 < MIN_YEAR_DIFF || timeptr -> tm_year - 70 > MAX_YEAR_DIFF )) {
310
326
return false;
311
327
}
312
328
0 commit comments