summaryrefslogtreecommitdiff
path: root/firmware/drivers/rtc/rtc_e8564.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/rtc/rtc_e8564.c')
-rw-r--r--firmware/drivers/rtc/rtc_e8564.c118
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
71int rtc_read_datetime(unsigned char* buf) 74int 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
88int rtc_write_datetime(unsigned char* buf) 93int 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
105void rtc_set_alarm(int h, int m) 112void 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
140void rtc_get_alarm(int *h, int *m) 146void 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
152bool rtc_enable_alarm(bool enable) 157bool 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