diff options
author | Marcoen Hirschberg <marcoen@gmail.com> | 2006-11-27 09:44:56 +0000 |
---|---|---|
committer | Marcoen Hirschberg <marcoen@gmail.com> | 2006-11-27 09:44:56 +0000 |
commit | a45e632495a0b662474771737197658ef22d73f0 (patch) | |
tree | faa6588b0e55cba4ea7ff8a58813d75581c563e1 /firmware/drivers/rtc | |
parent | 860e387758bbebef04a6fde206decb7f31e45654 (diff) | |
download | rockbox-a45e632495a0b662474771737197658ef22d73f0.tar.gz rockbox-a45e632495a0b662474771737197658ef22d73f0.zip |
move rtc functions to seperate files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11614 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/rtc')
-rw-r--r-- | firmware/drivers/rtc/rtc_e8564.c | 64 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_m41st84w.c | 280 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_pcf50605.c | 45 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_pcf50606.c | 51 |
4 files changed, 440 insertions, 0 deletions
diff --git a/firmware/drivers/rtc/rtc_e8564.c b/firmware/drivers/rtc/rtc_e8564.c new file mode 100644 index 0000000000..233168c303 --- /dev/null +++ b/firmware/drivers/rtc/rtc_e8564.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "i2c.h" | ||
21 | #include "rtc.h" | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "i2c-pp5020.h" | ||
25 | #include <stdbool.h> | ||
26 | |||
27 | void rtc_init(void) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | int rtc_read_datetime(unsigned char* buf) | ||
32 | { | ||
33 | unsigned char tmp; | ||
34 | int read; | ||
35 | |||
36 | /*RTC_E8564's slave address is 0x51*/ | ||
37 | read = i2c_readbytes(0x51,0x02,7,buf); | ||
38 | |||
39 | /* swap wday and mday to be compatible with | ||
40 | * get_time() from firmware/common/timefuncs.c */ | ||
41 | tmp=buf[3]; | ||
42 | buf[3]=buf[4]; | ||
43 | buf[4]=tmp; | ||
44 | |||
45 | return read; | ||
46 | } | ||
47 | |||
48 | int rtc_write_datetime(unsigned char* buf) | ||
49 | { | ||
50 | int i; | ||
51 | unsigned char tmp; | ||
52 | |||
53 | /* swap wday and mday to be compatible with | ||
54 | * set_time() in firmware/common/timefuncs.c */ | ||
55 | tmp=buf[3]; | ||
56 | buf[3]=buf[4]; | ||
57 | buf[4]=tmp; | ||
58 | |||
59 | for (i=0;i<7;i++){ | ||
60 | pp_i2c_send(0x51, 0x02+i,buf[i]); | ||
61 | } | ||
62 | return 1; | ||
63 | } | ||
64 | |||
diff --git a/firmware/drivers/rtc/rtc_m41st84w.c b/firmware/drivers/rtc/rtc_m41st84w.c new file mode 100644 index 0000000000..1d76867e13 --- /dev/null +++ b/firmware/drivers/rtc/rtc_m41st84w.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "i2c.h" | ||
21 | #include "rtc.h" | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include <stdbool.h> | ||
25 | |||
26 | #define RTC_ADR 0xd0 | ||
27 | #define RTC_DEV_WRITE (RTC_ADR | 0x00) | ||
28 | #define RTC_DEV_READ (RTC_ADR | 0x01) | ||
29 | |||
30 | void rtc_init(void) | ||
31 | { | ||
32 | unsigned char data; | ||
33 | |||
34 | #ifdef HAVE_ALARM_MOD | ||
35 | /* Check + save alarm bit first, before the power thread starts watching */ | ||
36 | rtc_check_alarm_started(false); | ||
37 | #endif | ||
38 | |||
39 | rtc_write(0x13, 0x10); /* 32 kHz square wave */ | ||
40 | |||
41 | /* Clear the Stop bit if it is set */ | ||
42 | data = rtc_read(0x01); | ||
43 | if(data & 0x80) | ||
44 | rtc_write(0x01, 0x00); | ||
45 | |||
46 | /* Clear the HT bit if it is set */ | ||
47 | data = rtc_read(0x0c); | ||
48 | |||
49 | if(data & 0x40) | ||
50 | { | ||
51 | data &= ~0x40; | ||
52 | rtc_write(0x0c,data); | ||
53 | } | ||
54 | |||
55 | #ifdef HAVE_ALARM_MOD | ||
56 | |||
57 | /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */ | ||
58 | /* without this, the alarm won't work! */ | ||
59 | |||
60 | data = rtc_read(0x04); | ||
61 | if (data & 0x80) | ||
62 | { | ||
63 | data &= ~0x80; | ||
64 | rtc_write(0x04, data); | ||
65 | } | ||
66 | |||
67 | /* Also, make sure that the OUT bit in register 8 is 1, | ||
68 | otherwise the player can't be turned off. */ | ||
69 | rtc_write(8, rtc_read(8) | 0x80); | ||
70 | |||
71 | #endif | ||
72 | } | ||
73 | |||
74 | #ifdef HAVE_ALARM_MOD | ||
75 | |||
76 | /* check whether the unit has been started by the RTC alarm function */ | ||
77 | /* (check for AF, which => started using wakeup alarm) */ | ||
78 | bool rtc_check_alarm_started(bool release_alarm) | ||
79 | { | ||
80 | static bool alarm_state, run_before; | ||
81 | bool rc; | ||
82 | |||
83 | if (run_before) { | ||
84 | rc = alarm_state; | ||
85 | alarm_state &= ~release_alarm; | ||
86 | } else { | ||
87 | /* This call resets AF, so we store the state for later recall */ | ||
88 | rc = alarm_state = rtc_check_alarm_flag(); | ||
89 | run_before = true; | ||
90 | } | ||
91 | |||
92 | return rc; | ||
93 | } | ||
94 | /* | ||
95 | * Checks the AL register. This call resets AL once read. | ||
96 | * | ||
97 | * We're only interested if ABE is set. AL is still raised regardless | ||
98 | * even if the unit is off when the alarm occurs. | ||
99 | */ | ||
100 | bool rtc_check_alarm_flag(void) | ||
101 | { | ||
102 | return ( ( (rtc_read(0x0f) & 0x40) != 0) && | ||
103 | (rtc_read(0x0a) & 0x20) ); | ||
104 | } | ||
105 | |||
106 | /* set alarm time registers to the given time (repeat once per day) */ | ||
107 | void rtc_set_alarm(int h, int m) | ||
108 | { | ||
109 | unsigned char data; | ||
110 | |||
111 | /* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */ | ||
112 | |||
113 | rtc_write(0x0e, 0x00); /* seconds 0 and RTP1 */ | ||
114 | rtc_write(0x0d, ((m / 10) << 4) | (m % 10)); /* minutes and RPT2 */ | ||
115 | rtc_write(0x0c, ((h / 10) << 4) | (h % 10)); /* hour and RPT3 */ | ||
116 | rtc_write(0x0b, 0xc1); /* set date 01 and RPT4 and RTP5 */ | ||
117 | |||
118 | /* set month to 1, if it's invalid, the rtc does an alarm every second instead */ | ||
119 | data = rtc_read(0x0a); | ||
120 | data &= 0xe0; | ||
121 | data |= 0x01; | ||
122 | rtc_write(0x0a, data); | ||
123 | } | ||
124 | |||
125 | /* read out the current alarm time */ | ||
126 | void rtc_get_alarm(int *h, int *m) | ||
127 | { | ||
128 | unsigned char data; | ||
129 | |||
130 | data = rtc_read(0x0c); | ||
131 | *h = ((data & 0x30) >> 4) * 10 + (data & 0x0f); | ||
132 | |||
133 | data = rtc_read(0x0d); | ||
134 | *m = ((data & 0x70) >> 4) * 10 + (data & 0x0f); | ||
135 | } | ||
136 | |||
137 | /* turn alarm on or off by setting the alarm flag enable */ | ||
138 | /* the alarm is automatically disabled when the RTC gets Vcc power at startup */ | ||
139 | /* avoid that an alarm occurs when the device is on because this locks the ON key forever */ | ||
140 | /* returns false if alarm was set and alarm flag (output) is off */ | ||
141 | /* returns true if alarm flag went on, which would lock the device, so the alarm was disabled again */ | ||
142 | bool rtc_enable_alarm(bool enable) | ||
143 | { | ||
144 | unsigned char data = rtc_read(0x0a); | ||
145 | if (enable) | ||
146 | { | ||
147 | data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */ | ||
148 | } | ||
149 | else | ||
150 | data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ | ||
151 | rtc_write(0x0a, data); | ||
152 | |||
153 | /* check if alarm flag AF is off (as it should be) */ | ||
154 | /* in some cases enabling the alarm results in an activated AF flag */ | ||
155 | /* this should not happen, but it does */ | ||
156 | /* if you know why, tell me! */ | ||
157 | /* for now, we try again forever in this case */ | ||
158 | while (rtc_check_alarm_flag()) /* on */ | ||
159 | { | ||
160 | data &= 0x5f; /* turn bit d7=AFE and d5=ABE off */ | ||
161 | rtc_write(0x0a, data); | ||
162 | sleep(HZ / 10); | ||
163 | rtc_check_alarm_flag(); | ||
164 | data |= 0xa0; /* turn bit d7=AFE and d5=ABE on */ | ||
165 | rtc_write(0x0a, data); | ||
166 | } | ||
167 | |||
168 | return false; /* all ok */ | ||
169 | } | ||
170 | |||
171 | #endif /* HAVE_ALARM_MOD */ | ||
172 | |||
173 | int rtc_write(unsigned char address, unsigned char value) | ||
174 | { | ||
175 | int ret = 0; | ||
176 | unsigned char buf[2]; | ||
177 | |||
178 | i2c_begin(); | ||
179 | |||
180 | buf[0] = address; | ||
181 | buf[1] = value; | ||
182 | |||
183 | /* send run command */ | ||
184 | if (i2c_write(RTC_DEV_WRITE,buf,2)) | ||
185 | { | ||
186 | ret = -1; | ||
187 | } | ||
188 | |||
189 | i2c_end(); | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | int rtc_read(unsigned char address) | ||
194 | { | ||
195 | int value = -1; | ||
196 | unsigned char buf[1]; | ||
197 | |||
198 | i2c_begin(); | ||
199 | |||
200 | buf[0] = address; | ||
201 | |||
202 | /* send read command */ | ||
203 | if (i2c_write(RTC_DEV_READ,buf,1) >= 0) | ||
204 | { | ||
205 | i2c_start(); | ||
206 | i2c_outb(RTC_DEV_READ); | ||
207 | if (i2c_getack()) | ||
208 | { | ||
209 | value = i2c_inb(1); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | i2c_stop(); | ||
214 | |||
215 | i2c_end(); | ||
216 | return value; | ||
217 | } | ||
218 | |||
219 | int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes) | ||
220 | { | ||
221 | int ret = 0; | ||
222 | unsigned char obuf[1]; | ||
223 | int i; | ||
224 | |||
225 | i2c_begin(); | ||
226 | |||
227 | obuf[0] = address; | ||
228 | |||
229 | /* send read command */ | ||
230 | if (i2c_write(RTC_DEV_READ, obuf, 1) >= 0) | ||
231 | { | ||
232 | i2c_start(); | ||
233 | i2c_outb(RTC_DEV_READ); | ||
234 | if (i2c_getack()) | ||
235 | { | ||
236 | for(i = 0;i < numbytes-1;i++) | ||
237 | buf[i] = i2c_inb(0); | ||
238 | |||
239 | buf[i] = i2c_inb(1); | ||
240 | } | ||
241 | else | ||
242 | { | ||
243 | ret = -1; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | i2c_stop(); | ||
248 | |||
249 | i2c_end(); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | int rtc_read_datetime(unsigned char* buf) { | ||
254 | int rc; | ||
255 | |||
256 | rc = rtc_read_multiple(1, buf, 7); | ||
257 | |||
258 | /* Adjust weekday */ | ||
259 | if(buf[3] == 7) | ||
260 | buf[3]=0; | ||
261 | |||
262 | return rc; | ||
263 | } | ||
264 | |||
265 | int rtc_write_datetime(unsigned char* buf) { | ||
266 | int i; | ||
267 | int rc = 0; | ||
268 | |||
269 | /* Adjust weekday */ | ||
270 | if(buf[3] == 0) | ||
271 | buf[3] = 7; | ||
272 | |||
273 | for (i = 0; i < 7 ; i++) | ||
274 | { | ||
275 | rc |= rtc_write(i+1, buf[i]); | ||
276 | } | ||
277 | rc |= rtc_write(8, 0x80); /* Out=1, calibration = 0 */ | ||
278 | |||
279 | return rc; | ||
280 | } | ||
diff --git a/firmware/drivers/rtc/rtc_pcf50605.c b/firmware/drivers/rtc/rtc_pcf50605.c new file mode 100644 index 0000000000..1bc40146ff --- /dev/null +++ b/firmware/drivers/rtc/rtc_pcf50605.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "i2c.h" | ||
21 | #include "rtc.h" | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "pcf50605.h" | ||
25 | #include <stdbool.h> | ||
26 | |||
27 | void rtc_init(void) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | int rtc_read_datetime(unsigned char* buf) | ||
32 | { | ||
33 | return pcf50605_read_multiple(0x0a, buf, 7); | ||
34 | } | ||
35 | |||
36 | int rtc_write_datetime(unsigned char* buf) | ||
37 | { | ||
38 | int i; | ||
39 | |||
40 | for (i=0;i<7;i++) { | ||
41 | pcf50605_write(0x0a+i, buf[i]); | ||
42 | } | ||
43 | |||
44 | return 1; | ||
45 | } | ||
diff --git a/firmware/drivers/rtc/rtc_pcf50606.c b/firmware/drivers/rtc/rtc_pcf50606.c new file mode 100644 index 0000000000..25b0c704c0 --- /dev/null +++ b/firmware/drivers/rtc/rtc_pcf50606.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "i2c.h" | ||
21 | #include "rtc.h" | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "pcf50606.h" | ||
25 | #include <stdbool.h> | ||
26 | |||
27 | void rtc_init(void) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | int rtc_read_datetime(unsigned char* buf) { | ||
32 | int rc; | ||
33 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
34 | |||
35 | rc = pcf50606_read_multiple(0x0a, buf, 7); | ||
36 | |||
37 | set_irq_level(oldlevel); | ||
38 | return rc; | ||
39 | } | ||
40 | |||
41 | int rtc_write_datetime(unsigned char* buf) { | ||
42 | int rc; | ||
43 | int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
44 | |||
45 | rc = pcf50606_write_multiple(0x0a, buf, 7); | ||
46 | |||
47 | set_irq_level(oldlevel); | ||
48 | |||
49 | return rc; | ||
50 | } | ||
51 | |||