diff options
Diffstat (limited to 'firmware/drivers/rtc/rtc_pcf50606.c')
-rw-r--r-- | firmware/drivers/rtc/rtc_pcf50606.c | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/firmware/drivers/rtc/rtc_pcf50606.c b/firmware/drivers/rtc/rtc_pcf50606.c index 50df5a1f95..cb6697207b 100644 --- a/firmware/drivers/rtc/rtc_pcf50606.c +++ b/firmware/drivers/rtc/rtc_pcf50606.c | |||
@@ -24,27 +24,70 @@ | |||
24 | #include "kernel.h" | 24 | #include "kernel.h" |
25 | #include "system.h" | 25 | #include "system.h" |
26 | #include "pcf50606.h" | 26 | #include "pcf50606.h" |
27 | #include <stdbool.h> | ||
28 | 27 | ||
29 | void rtc_init(void) | 28 | void rtc_init(void) |
30 | { | 29 | { |
31 | } | 30 | } |
32 | 31 | ||
33 | int rtc_read_datetime(unsigned char* buf) { | 32 | int rtc_read_datetime(struct tm *tm) |
34 | int rc; | 33 | { |
35 | int oldlevel = disable_irq_save(); | 34 | unsigned int i; |
36 | 35 | int rc, oldlevel; | |
37 | rc = pcf50606_read_multiple(0x0a, buf, 7); | 36 | unsigned char buf[7]; |
37 | |||
38 | oldlevel = disable_irq_save(); | ||
39 | |||
40 | rc = pcf50606_read_multiple(0x0a, buf, sizeof(buf)); | ||
38 | 41 | ||
39 | restore_irq(oldlevel); | 42 | restore_irq(oldlevel); |
43 | |||
44 | for (i = 0; i < sizeof(buf); i++) | ||
45 | buf[i] = BCD2DEC(buf[i]); | ||
46 | |||
47 | tm->tm_sec = buf[0]; | ||
48 | tm->tm_min = buf[1]; | ||
49 | tm->tm_hour = buf[2]; | ||
50 | tm->tm_wday = buf[3]; | ||
51 | tm->tm_mday = buf[4]; | ||
52 | tm->tm_mon = buf[5] - 1; | ||
53 | #ifdef IRIVER_H300_SERIES | ||
54 | /* Special kludge to coexist with the iriver firmware. The iriver firmware | ||
55 | stores the date as 1965+nn, and allows a range of 1980..2064. We use | ||
56 | 1964+nn here to make leap years work correctly, so the date will be one | ||
57 | year off in the iriver firmware but at least won't be reset anymore. */ | ||
58 | tm->tm_year = buf[6] + 64; | ||
59 | #else /* Not IRIVER_H300_SERIES */ | ||
60 | tm->tm_year = buf[6] + 100; | ||
61 | #endif /* IRIVER_H300_SERIES */ | ||
62 | |||
40 | return rc; | 63 | return rc; |
41 | } | 64 | } |
42 | 65 | ||
43 | int rtc_write_datetime(unsigned char* buf) { | 66 | int rtc_write_datetime(const struct tm *tm) |
44 | int rc; | 67 | { |
45 | int oldlevel = disable_irq_save(); | 68 | unsigned int i; |
46 | 69 | int rc, oldlevel; | |
47 | rc = pcf50606_write_multiple(0x0a, buf, 7); | 70 | unsigned char buf[7]; |
71 | |||
72 | buf[0] = tm->tm_sec; | ||
73 | buf[1] = tm->tm_min; | ||
74 | buf[2] = tm->tm_hour; | ||
75 | buf[3] = tm->tm_wday; | ||
76 | buf[4] = tm->tm_mday; | ||
77 | buf[5] = tm->tm_mon + 1; | ||
78 | #ifdef IRIVER_H300_SERIES | ||
79 | /* Iriver firmware compatibility kludge, see rtc_read_datetime(). */ | ||
80 | buf[6] = tm->tm_year - 64; | ||
81 | #else /* Not IRIVER_H300_SERIES */ | ||
82 | buf[6] = tm->tm_year - 100; | ||
83 | #endif /* IRIVER_H300_SERIES */ | ||
84 | |||
85 | for (i = 0; i < sizeof(buf); i++) | ||
86 | buf[i] = DEC2BCD(buf[i]); | ||
87 | |||
88 | oldlevel = disable_irq_save(); | ||
89 | |||
90 | rc = pcf50606_write_multiple(0x0a, buf, sizeof(buf)); | ||
48 | 91 | ||
49 | restore_irq(oldlevel); | 92 | restore_irq(oldlevel); |
50 | 93 | ||