diff options
Diffstat (limited to 'firmware/drivers/rtc/rtc_e8564.c')
-rw-r--r-- | firmware/drivers/rtc/rtc_e8564.c | 118 |
1 files changed, 62 insertions, 56 deletions
diff --git a/firmware/drivers/rtc/rtc_e8564.c b/firmware/drivers/rtc/rtc_e8564.c index b4cd4b91f8..55c67c13c8 100644 --- a/firmware/drivers/rtc/rtc_e8564.c +++ b/firmware/drivers/rtc/rtc_e8564.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "i2c-pp.h" | 27 | #include "i2c-pp.h" |
28 | #include <stdbool.h> | 28 | #include <stdbool.h> |
29 | 29 | ||
30 | /*RTC_E8564's slave address is 0x51*/ | ||
31 | #define RTC_ADDR 0x51 | ||
32 | |||
30 | /* RTC registers */ | 33 | /* RTC registers */ |
31 | #define RTC_CTRL1 0x00 | 34 | #define RTC_CTRL1 0x00 |
32 | #define RTC_CTRL2 0x01 | 35 | #define RTC_CTRL2 0x01 |
@@ -59,94 +62,96 @@ void rtc_init(void) | |||
59 | 62 | ||
60 | /* initialize Control 1 register */ | 63 | /* initialize Control 1 register */ |
61 | tmp = 0; | 64 | tmp = 0; |
62 | pp_i2c_send(0x51, RTC_CTRL1,tmp); | 65 | pp_i2c_send(RTC_ADDR, RTC_CTRL1, tmp); |
63 | 66 | ||
64 | /* read value of the Control 2 register - we'll need it to preserve alarm and timer interrupt assertion flags */ | 67 | /* read value of the Control 2 register - we'll need it to preserve alarm and timer interrupt assertion flags */ |
65 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 68 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
66 | /* preserve alarm and timer interrupt flags */ | 69 | /* preserve alarm and timer interrupt flags */ |
67 | tmp &= (RTC_TF | RTC_AF | RTC_TIE | RTC_AIE); | 70 | tmp &= (RTC_TF | RTC_AF | RTC_TIE | RTC_AIE); |
68 | pp_i2c_send(0x51, RTC_CTRL2,tmp); | 71 | pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); |
69 | } | 72 | } |
70 | 73 | ||
71 | int rtc_read_datetime(unsigned char* buf) | 74 | int rtc_read_datetime(struct tm *tm) |
72 | { | 75 | { |
73 | unsigned char tmp; | ||
74 | int read; | 76 | int read; |
75 | 77 | unsigned char buf[7]; | |
76 | /*RTC_E8564's slave address is 0x51*/ | 78 | |
77 | read = i2c_readbytes(0x51,0x02,7,buf); | 79 | read = i2c_readbytes(RTC_ADDR, 0x02, sizeof(buf), buf); |
78 | 80 | ||
79 | /* swap wday and mday to be compatible with | 81 | /* convert from bcd, avoid getting extra bits */ |
80 | * get_time() from firmware/common/timefuncs.c */ | 82 | tm->tm_sec = BCD2DEC(buf[0] & 0x7f); |
81 | tmp=buf[3]; | 83 | tm->tm_min = BCD2DEC(buf[1] & 0x7f); |
82 | buf[3]=buf[4]; | 84 | tm->tm_hour = BCD2DEC(buf[2] & 0x3f); |
83 | buf[4]=tmp; | 85 | tm->tm_mday = BCD2DEC(buf[3] & 0x3f); |
84 | 86 | tm->tm_wday = BCD2DEC(buf[4] & 0x3); | |
87 | tm->tm_mon = BCD2DEC(buf[5] & 0x1f) - 1; | ||
88 | tm->tm_year = BCD2DEC(buf[6]) + 100; | ||
89 | |||
85 | return read; | 90 | return read; |
86 | } | 91 | } |
87 | 92 | ||
88 | int rtc_write_datetime(unsigned char* buf) | 93 | int rtc_write_datetime(const struct tm *tm) |
89 | { | 94 | { |
90 | int i; | 95 | unsigned int i; |
91 | unsigned char tmp; | 96 | unsigned char buf[7]; |
92 | 97 | ||
93 | /* swap wday and mday to be compatible with | 98 | buf[0] = tm->tm_sec; |
94 | * set_time() in firmware/common/timefuncs.c */ | 99 | buf[1] = tm->tm_min; |
95 | tmp=buf[3]; | 100 | buf[2] = tm->tm_hour; |
96 | buf[3]=buf[4]; | 101 | buf[3] = tm->tm_mday; |
97 | buf[4]=tmp; | 102 | buf[4] = tm->tm_wday; |
98 | 103 | buf[5] = tm->tm_mon + 1; | |
99 | for (i=0;i<7;i++){ | 104 | buf[6] = tm->tm_year - 100; |
100 | pp_i2c_send(0x51, 0x02+i,buf[i]); | 105 | |
101 | } | 106 | for (i = 0; i < sizeof(buf); i++) |
107 | pp_i2c_send(RTC_ADDR, 0x02 + i, DEC2BCD(buf[i])); | ||
108 | |||
102 | return 1; | 109 | return 1; |
103 | } | 110 | } |
104 | 111 | ||
105 | void rtc_set_alarm(int h, int m) | 112 | void rtc_set_alarm(int h, int m) |
106 | { | 113 | { |
107 | unsigned char buf[4]={0}; | 114 | unsigned char buf[4] = {0}; |
108 | int rv=0; | 115 | int i, rv; |
109 | int i=0; | 116 | |
110 | |||
111 | /* clear alarm interrupt */ | 117 | /* clear alarm interrupt */ |
112 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,buf); | 118 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, buf); |
113 | buf[0] &= RTC_AF; | 119 | buf[0] &= RTC_AF; |
114 | pp_i2c_send(0x51, RTC_CTRL2,buf[0]); | 120 | pp_i2c_send(RTC_ADDR, RTC_CTRL2, buf[0]); |
115 | 121 | ||
116 | /* prepare new alarm */ | 122 | /* prepare new alarm */ |
117 | if( m >= 0 ) | 123 | if( m >= 0 ) |
118 | buf[0] = (((m/10) << 4) | m%10); | 124 | buf[0] = DEC2BCD(m); |
119 | else | 125 | else |
120 | /* ignore minutes comparison query */ | 126 | /* ignore minutes comparison query */ |
121 | buf[0] = RTC_AE; | 127 | buf[0] = RTC_AE; |
122 | 128 | ||
123 | if( h >= 0 ) | 129 | if( h >= 0 ) |
124 | buf[1] = (((h/10) << 4) | h%10); | 130 | buf[1] = DEC2BCD(h); |
125 | else | 131 | else |
126 | /* ignore hours comparison query */ | 132 | /* ignore hours comparison query */ |
127 | buf[1] = RTC_AE; | 133 | buf[1] = RTC_AE; |
128 | 134 | ||
129 | /* ignore day and wday */ | 135 | /* ignore day and wday */ |
130 | buf[2] = RTC_AE; | 136 | buf[2] = RTC_AE; |
131 | buf[3] = RTC_AE; | 137 | buf[3] = RTC_AE; |
132 | 138 | ||
133 | /* write new alarm */ | 139 | /* write new alarm */ |
134 | for(;i<4;i++) | 140 | for(i = 0; i < 4; i++) |
135 | pp_i2c_send(0x51, RTC_ALARM_MINUTES+i,buf[i]); | 141 | pp_i2c_send(RTC_ADDR, RTC_ALARM_MINUTES + i, buf[i]); |
136 | 142 | ||
137 | /* note: alarm is not enabled at the point */ | 143 | /* note: alarm is not enabled at the point */ |
138 | } | 144 | } |
139 | 145 | ||
140 | void rtc_get_alarm(int *h, int *m) | 146 | void rtc_get_alarm(int *h, int *m) |
141 | { | 147 | { |
142 | unsigned char buf[4]={0}; | 148 | unsigned char buf[4]={0}; |
143 | |||
144 | /* get alarm preset */ | ||
145 | i2c_readbytes(0x51, RTC_ALARM_MINUTES,4,buf); | ||
146 | 149 | ||
147 | *m = ((buf[0] >> 4) & 0x7)*10 + (buf[0] & 0x0f); | 150 | /* get alarm preset */ |
148 | *h = ((buf[1] >> 4) & 0x3)*10 + (buf[1] & 0x0f); | 151 | i2c_readbytes(RTC_ADDR, RTC_ALARM_MINUTES, 4 ,buf); |
149 | 152 | ||
153 | *m = BCD2DEC(buf[0] & 0x7f); | ||
154 | *h = BCD2DEC(buf[0] & 0x3f); | ||
150 | } | 155 | } |
151 | 156 | ||
152 | bool rtc_enable_alarm(bool enable) | 157 | bool rtc_enable_alarm(bool enable) |
@@ -157,10 +162,10 @@ bool rtc_enable_alarm(bool enable) | |||
157 | if(enable) | 162 | if(enable) |
158 | { | 163 | { |
159 | /* enable alarm interrupt */ | 164 | /* enable alarm interrupt */ |
160 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 165 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
161 | tmp |= RTC_AIE; | 166 | tmp |= RTC_AIE; |
162 | tmp &= ~RTC_AF; | 167 | tmp &= ~RTC_AF; |
163 | pp_i2c_send(0x51, RTC_CTRL2,tmp); | 168 | pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); |
164 | } | 169 | } |
165 | else | 170 | else |
166 | { | 171 | { |
@@ -168,9 +173,9 @@ bool rtc_enable_alarm(bool enable) | |||
168 | if(rtc_lock_alarm_clear) | 173 | if(rtc_lock_alarm_clear) |
169 | /* lock disabling alarm before it was checked whether or not the unit was started by RTC alarm */ | 174 | /* lock disabling alarm before it was checked whether or not the unit was started by RTC alarm */ |
170 | return false; | 175 | return false; |
171 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 176 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
172 | tmp &= ~(RTC_AIE | RTC_AF); | 177 | tmp &= ~(RTC_AIE | RTC_AF); |
173 | pp_i2c_send(0x51, RTC_CTRL2,tmp); | 178 | pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); |
174 | } | 179 | } |
175 | 180 | ||
176 | return false; | 181 | return false; |
@@ -186,21 +191,21 @@ bool rtc_check_alarm_started(bool release_alarm) | |||
186 | if (run_before) | 191 | if (run_before) |
187 | { | 192 | { |
188 | started = alarm_state; | 193 | started = alarm_state; |
189 | alarm_state &= ~release_alarm; | 194 | alarm_state &= ~release_alarm; |
190 | } | 195 | } |
191 | else | 196 | else |
192 | { | 197 | { |
193 | /* read Control 2 register which contains alarm flag */ | 198 | /* read Control 2 register which contains alarm flag */ |
194 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 199 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
195 | 200 | ||
196 | alarm_state = started = ( (tmp & RTC_AF) && (tmp & RTC_AIE) ); | 201 | alarm_state = started = ( (tmp & RTC_AF) && (tmp & RTC_AIE) ); |
197 | 202 | ||
198 | if(release_alarm && started) | 203 | if(release_alarm && started) |
199 | { | 204 | { |
200 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 205 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
201 | /* clear alarm interrupt enable and alarm flag */ | 206 | /* clear alarm interrupt enable and alarm flag */ |
202 | tmp &= ~(RTC_AF | RTC_AIE); | 207 | tmp &= ~(RTC_AF | RTC_AIE); |
203 | pp_i2c_send(0x51, RTC_CTRL2,tmp); | 208 | pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); |
204 | } | 209 | } |
205 | run_before = true; | 210 | run_before = true; |
206 | rtc_lock_alarm_clear = false; | 211 | rtc_lock_alarm_clear = false; |
@@ -215,7 +220,8 @@ bool rtc_check_alarm_flag(void) | |||
215 | int rv=0; | 220 | int rv=0; |
216 | 221 | ||
217 | /* read Control 2 register which contains alarm flag */ | 222 | /* read Control 2 register which contains alarm flag */ |
218 | rv = i2c_readbytes(0x51,RTC_CTRL2,1,&tmp); | 223 | rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); |
219 | 224 | ||
220 | return (tmp & RTC_AF); | 225 | return (tmp & RTC_AF); |
221 | } | 226 | } |
227 | |||