diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 4 | ||||
-rw-r--r-- | firmware/common/timefuncs.c | 13 | ||||
-rw-r--r-- | firmware/drivers/eeprom_24cxx.c | 265 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 20 | ||||
-rw-r--r-- | firmware/drivers/rtc/rtc_ds1339_ds3231.c | 144 | ||||
-rw-r--r-- | firmware/export/config-h120.h | 8 | ||||
-rw-r--r-- | firmware/export/config.h | 1 | ||||
-rw-r--r-- | firmware/export/rtc.h | 9 | ||||
-rw-r--r-- | firmware/export/sw_i2c.h | 30 | ||||
-rw-r--r-- | firmware/target/coldfire/iriver/h100/sw_i2c-h100.c | 259 | ||||
-rw-r--r-- | firmware/target/coldfire/iriver/h300/sw_i2c-h300.c | 105 |
11 files changed, 593 insertions, 265 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 03d2b16d1d..f07145ca06 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -137,6 +137,8 @@ drivers/rtc/rtc_pcf50606.c | |||
137 | drivers/rtc/rtc_pcf50605.c | 137 | drivers/rtc/rtc_pcf50605.c |
138 | #elif (CONFIG_RTC == RTC_E8564) | 138 | #elif (CONFIG_RTC == RTC_E8564) |
139 | drivers/rtc/rtc_e8564.c | 139 | drivers/rtc/rtc_e8564.c |
140 | #elif (CONFIG_RTC == RTC_DS1339_DS3231) | ||
141 | drivers/rtc/rtc_ds1339_ds3231.c | ||
140 | #elif (CONFIG_RTC == RTC_S3C2440) | 142 | #elif (CONFIG_RTC == RTC_S3C2440) |
141 | drivers/rtc/rtc_s3c2440.c | 143 | drivers/rtc/rtc_s3c2440.c |
142 | #elif (CONFIG_RTC == RTC_AS3514) | 144 | #elif (CONFIG_RTC == RTC_AS3514) |
@@ -380,6 +382,7 @@ target/coldfire/pcf50606-coldfire.c | |||
380 | target/coldfire/iriver/ata-iriver.c | 382 | target/coldfire/iriver/ata-iriver.c |
381 | target/coldfire/iriver/lcd-remote-iriver.c | 383 | target/coldfire/iriver/lcd-remote-iriver.c |
382 | target/coldfire/iriver/system-iriver.c | 384 | target/coldfire/iriver/system-iriver.c |
385 | target/coldfire/iriver/h300/sw_i2c-h300.c | ||
383 | target/coldfire/iriver/h300/adc-h300.c | 386 | target/coldfire/iriver/h300/adc-h300.c |
384 | target/coldfire/iriver/h300/backlight-h300.c | 387 | target/coldfire/iriver/h300/backlight-h300.c |
385 | target/coldfire/iriver/h300/button-h300.c | 388 | target/coldfire/iriver/h300/button-h300.c |
@@ -400,6 +403,7 @@ target/coldfire/ata-as-coldfire.S | |||
400 | target/coldfire/iriver/ata-iriver.c | 403 | target/coldfire/iriver/ata-iriver.c |
401 | target/coldfire/iriver/lcd-remote-iriver.c | 404 | target/coldfire/iriver/lcd-remote-iriver.c |
402 | target/coldfire/iriver/system-iriver.c | 405 | target/coldfire/iriver/system-iriver.c |
406 | target/coldfire/iriver/h100/sw_i2c-h100.c | ||
403 | target/coldfire/iriver/h100/adc-h100.c | 407 | target/coldfire/iriver/h100/adc-h100.c |
404 | target/coldfire/iriver/h100/backlight-h100.c | 408 | target/coldfire/iriver/h100/backlight-h100.c |
405 | target/coldfire/iriver/h100/button-h100.c | 409 | target/coldfire/iriver/h100/button-h100.c |
diff --git a/firmware/common/timefuncs.c b/firmware/common/timefuncs.c index e48aadd0a2..881bc23e53 100644 --- a/firmware/common/timefuncs.c +++ b/firmware/common/timefuncs.c | |||
@@ -49,6 +49,19 @@ struct tm *get_time(void) | |||
49 | #ifdef CONFIG_RTC | 49 | #ifdef CONFIG_RTC |
50 | static long timeout = 0; | 50 | static long timeout = 0; |
51 | 51 | ||
52 | #if CONFIG_RTC == RTC_DS1339_DS3231 | ||
53 | if(!rtc_detected) { | ||
54 | tm.tm_sec = 0; | ||
55 | tm.tm_min = 0; | ||
56 | tm.tm_hour = 0; | ||
57 | tm.tm_mday = 1; | ||
58 | tm.tm_mon = 0; | ||
59 | tm.tm_year = 70; | ||
60 | tm.tm_wday = 1; | ||
61 | tm.tm_yday = 0; /* Not implemented for now */ | ||
62 | tm.tm_isdst = -1; /* Not implemented for now */ | ||
63 | } else | ||
64 | #endif | ||
52 | /* Don't read the RTC more than once per second */ | 65 | /* Don't read the RTC more than once per second */ |
53 | if (current_tick > timeout) { | 66 | if (current_tick > timeout) { |
54 | char rtcbuf[7]; | 67 | char rtcbuf[7]; |
diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c index 6016c0f841..a0d8f83eb7 100644 --- a/firmware/drivers/eeprom_24cxx.c +++ b/firmware/drivers/eeprom_24cxx.c | |||
@@ -16,274 +16,21 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "lcd.h" | 19 | |
20 | #include "cpu.h" | ||
21 | #include "system.h" | ||
22 | #include "kernel.h" | ||
23 | #include "thread.h" | ||
24 | #include "debug.h" | ||
25 | #include "logf.h" | 20 | #include "logf.h" |
26 | #include "sprintf.h" | ||
27 | #include "string.h" | 21 | #include "string.h" |
28 | #include "inttypes.h" | 22 | #include "inttypes.h" |
29 | 23 | ||
30 | #include "eeprom_24cxx.h" | 24 | #include "sw_i2c.h" |
31 | |||
32 | /** | ||
33 | * I2C-functions are copied and ported from fmradio.c. | ||
34 | */ | ||
35 | 25 | ||
36 | #define SW_I2C_WRITE 0 | 26 | #include "eeprom_24cxx.h" |
37 | #define SW_I2C_READ 1 | ||
38 | 27 | ||
39 | /* Use cache to speedup writing to the chip. */ | 28 | /* Use cache to speedup writing to the chip. */ |
40 | static char data_cache[EEPROM_SIZE]; | 29 | static char data_cache[EEPROM_SIZE]; |
41 | static uint8_t cached_bitfield[EEPROM_SIZE/8]; | 30 | static uint8_t cached_bitfield[EEPROM_SIZE/8]; |
42 | 31 | ||
43 | #define IS_CACHED(addr) (cached_bitfield[addr/8] & (1 << (addr % 8))) | 32 | #define IS_CACHED(addr) (cached_bitfield[addr/8] & (1 << (addr % 8))) |
44 | #define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8)) | 33 | #define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8)) |
45 | |||
46 | /* h1x0 needs its own i2c driver, | ||
47 | h3x0 uses the pcf i2c driver */ | ||
48 | |||
49 | #ifdef IRIVER_H100_SERIES | ||
50 | |||
51 | /* cute little functions, atomic read-modify-write */ | ||
52 | |||
53 | /* SCL is GPIO, 12 */ | ||
54 | #define SCL ( 0x00001000 & GPIO_READ) | ||
55 | #define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT) | ||
56 | #define SCL_LO or_l( 0x00001000, &GPIO_ENABLE) | ||
57 | #define SCL_HI and_l(~0x00001000, &GPIO_ENABLE) | ||
58 | |||
59 | /* SDA is GPIO1, 13 */ | ||
60 | #define SDA ( 0x00002000 & GPIO1_READ) | ||
61 | #define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT) | ||
62 | #define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE) | ||
63 | #define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE) | ||
64 | |||
65 | /* delay loop to achieve 400kHz at 120MHz CPU frequency */ | ||
66 | #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) | ||
67 | |||
68 | static void sw_i2c_init(void) | ||
69 | { | ||
70 | logf("sw_i2c_init"); | ||
71 | or_l(0x00001000, &GPIO_FUNCTION); | ||
72 | or_l(0x00002000, &GPIO1_FUNCTION); | ||
73 | SDA_HI; | ||
74 | SCL_HI; | ||
75 | SDA_OUT_LO; | ||
76 | SCL_OUT_LO; | ||
77 | } | ||
78 | |||
79 | static void sw_i2c_start(void) | ||
80 | { | ||
81 | SCL_LO; | ||
82 | DELAY; | ||
83 | SDA_HI; | ||
84 | DELAY; | ||
85 | SCL_HI; | ||
86 | DELAY; | ||
87 | SDA_LO; | ||
88 | DELAY; | ||
89 | SCL_LO; | ||
90 | } | ||
91 | |||
92 | static void sw_i2c_stop(void) | ||
93 | { | ||
94 | SCL_HI; | ||
95 | DELAY; | ||
96 | SDA_HI; | ||
97 | DELAY; | ||
98 | } | ||
99 | |||
100 | static void sw_i2c_ack(void) | ||
101 | { | ||
102 | SCL_LO; | ||
103 | DELAY; | ||
104 | SDA_LO; | ||
105 | DELAY; | ||
106 | |||
107 | SCL_HI; | ||
108 | DELAY; | ||
109 | } | ||
110 | |||
111 | static bool sw_i2c_getack(void) | ||
112 | { | ||
113 | bool ret = true; | ||
114 | int count = 10; | ||
115 | |||
116 | SCL_LO; | ||
117 | DELAY; | ||
118 | SDA_HI; /* sets to input */ | ||
119 | DELAY; | ||
120 | SCL_HI; | ||
121 | DELAY; | ||
122 | |||
123 | while (SDA && count--) | ||
124 | DELAY; | ||
125 | |||
126 | if (SDA) | ||
127 | /* ack failed */ | ||
128 | ret = false; | ||
129 | |||
130 | SCL_LO; | ||
131 | DELAY; | ||
132 | SDA_LO; | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static void sw_i2c_outb(unsigned char byte) | ||
138 | { | ||
139 | int i; | ||
140 | |||
141 | /* clock out each bit, MSB first */ | ||
142 | for ( i=0x80; i; i>>=1 ) | ||
143 | { | ||
144 | SCL_LO; | ||
145 | DELAY; | ||
146 | if ( i & byte ) | ||
147 | SDA_HI; | ||
148 | else | ||
149 | SDA_LO; | ||
150 | DELAY; | ||
151 | SCL_HI; | ||
152 | DELAY; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static unsigned char sw_i2c_inb(void) | ||
157 | { | ||
158 | int i; | ||
159 | unsigned char byte = 0; | ||
160 | |||
161 | SDA_HI; /* sets to input */ | ||
162 | |||
163 | /* clock in each bit, MSB first */ | ||
164 | for ( i=0x80; i; i>>=1 ) | ||
165 | { | ||
166 | SCL_HI; | ||
167 | DELAY; | ||
168 | if ( SDA ) | ||
169 | byte |= i; | ||
170 | SCL_LO; | ||
171 | DELAY; | ||
172 | } | ||
173 | |||
174 | sw_i2c_ack(); | ||
175 | |||
176 | return byte; | ||
177 | } | ||
178 | |||
179 | #else | ||
180 | |||
181 | #include "pcf50606.h" | ||
182 | |||
183 | #define sw_i2c_init() /* no extra init required */ | ||
184 | #define sw_i2c_start() pcf50606_i2c_start() | ||
185 | #define sw_i2c_stop() pcf50606_i2c_stop() | ||
186 | #define sw_i2c_ack() pcf50606_i2c_ack(true) | ||
187 | #define sw_i2c_getack() pcf50606_i2c_getack() | ||
188 | #define sw_i2c_outb(x) pcf50606_i2c_outb(x) | ||
189 | #define sw_i2c_inb() pcf50606_i2c_inb(false) | ||
190 | |||
191 | #endif /* IRIVER_H100_SERIES */ | ||
192 | |||
193 | |||
194 | int sw_i2c_write(int location, const unsigned char* buf, int count) | ||
195 | { | ||
196 | int i; | ||
197 | |||
198 | sw_i2c_start(); | ||
199 | sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE); | ||
200 | if (!sw_i2c_getack()) | ||
201 | { | ||
202 | sw_i2c_stop(); | ||
203 | return -1; | ||
204 | } | ||
205 | |||
206 | sw_i2c_outb(location); | ||
207 | if (!sw_i2c_getack()) | ||
208 | { | ||
209 | sw_i2c_stop(); | ||
210 | return -2; | ||
211 | } | ||
212 | |||
213 | for (i=0; i<count; i++) | ||
214 | { | ||
215 | sw_i2c_outb(buf[i]); | ||
216 | if (!sw_i2c_getack()) | ||
217 | { | ||
218 | sw_i2c_stop(); | ||
219 | return -3; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | sw_i2c_stop(); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | int sw_i2c_write_byte(int location, unsigned char byte) | ||
229 | { | ||
230 | sw_i2c_start(); | ||
231 | sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE); | ||
232 | if (!sw_i2c_getack()) | ||
233 | { | ||
234 | sw_i2c_stop(); | ||
235 | return -1; | ||
236 | } | ||
237 | |||
238 | sw_i2c_outb(location); | ||
239 | if (!sw_i2c_getack()) | ||
240 | { | ||
241 | sw_i2c_stop(); | ||
242 | return -2; | ||
243 | } | ||
244 | |||
245 | sw_i2c_outb(byte); | ||
246 | if (!sw_i2c_getack()) | ||
247 | { | ||
248 | sw_i2c_stop(); | ||
249 | return -3; | ||
250 | } | ||
251 | |||
252 | sw_i2c_stop(); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | int sw_i2c_read(unsigned char location, unsigned char* byte) | ||
258 | { | ||
259 | sw_i2c_start(); | ||
260 | sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE); | ||
261 | if (!sw_i2c_getack()) | ||
262 | { | ||
263 | sw_i2c_stop(); | ||
264 | return -1; | ||
265 | } | ||
266 | |||
267 | sw_i2c_outb(location); | ||
268 | if (!sw_i2c_getack()) | ||
269 | { | ||
270 | sw_i2c_stop(); | ||
271 | return -2; | ||
272 | } | ||
273 | |||
274 | sw_i2c_start(); | ||
275 | sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_READ); | ||
276 | if (!sw_i2c_getack()) | ||
277 | { | ||
278 | sw_i2c_stop(); | ||
279 | return -3; | ||
280 | } | ||
281 | |||
282 | *byte = sw_i2c_inb(); | ||
283 | sw_i2c_stop(); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | 34 | ||
288 | void eeprom_24cxx_init(void) | 35 | void eeprom_24cxx_init(void) |
289 | { | 36 | { |
@@ -314,7 +61,7 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c) | |||
314 | *c = 0; | 61 | *c = 0; |
315 | do | 62 | do |
316 | { | 63 | { |
317 | ret = sw_i2c_read(address, &byte); | 64 | ret = sw_i2c_read(EEPROM_ADDR, address, &byte, 1); |
318 | } while (ret < 0 && count++ < 200); | 65 | } while (ret < 0 && count++ < 200); |
319 | 66 | ||
320 | if (ret < 0) | 67 | if (ret < 0) |
@@ -357,7 +104,7 @@ int eeprom_24cxx_write_byte(unsigned int address, char c) | |||
357 | 104 | ||
358 | do | 105 | do |
359 | { | 106 | { |
360 | ret = sw_i2c_write_byte(address, c); | 107 | ret = sw_i2c_write(EEPROM_ADDR, address, &c, 1); |
361 | } while (ret < 0 && count++ < 200) ; | 108 | } while (ret < 0 && count++ < 200) ; |
362 | 109 | ||
363 | if (ret < 0) | 110 | if (ret < 0) |
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index e3e1a755cb..e4e77627d0 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -31,6 +31,9 @@ | |||
31 | #include "rbunicode.h" | 31 | #include "rbunicode.h" |
32 | #include "logf.h" | 32 | #include "logf.h" |
33 | #include "atoi.h" | 33 | #include "atoi.h" |
34 | #ifdef CONFIG_RTC | ||
35 | #include "rtc.h" | ||
36 | #endif | ||
34 | 37 | ||
35 | #define BYTES2INT16(array,pos) \ | 38 | #define BYTES2INT16(array,pos) \ |
36 | (array[pos] | (array[pos+1] << 8 )) | 39 | (array[pos] | (array[pos+1] << 8 )) |
@@ -945,6 +948,10 @@ static void fat_time(unsigned short* date, | |||
945 | { | 948 | { |
946 | #ifdef CONFIG_RTC | 949 | #ifdef CONFIG_RTC |
947 | struct tm* tm = get_time(); | 950 | struct tm* tm = get_time(); |
951 | #if CONFIG_RTC == RTC_DS1339_DS3231 | ||
952 | if(rtc_detected) | ||
953 | { | ||
954 | #endif /* CONFIG_RTC == RTC_DS1339_DS3231 */ | ||
948 | 955 | ||
949 | if (date) | 956 | if (date) |
950 | *date = ((tm->tm_year - 80) << 9) | | 957 | *date = ((tm->tm_year - 80) << 9) | |
@@ -958,7 +965,14 @@ static void fat_time(unsigned short* date, | |||
958 | 965 | ||
959 | if (tenth) | 966 | if (tenth) |
960 | *tenth = (tm->tm_sec & 1) * 100; | 967 | *tenth = (tm->tm_sec & 1) * 100; |
961 | #else | 968 | |
969 | #if CONFIG_RTC == RTC_DS1339_DS3231 | ||
970 | } | ||
971 | else | ||
972 | #endif /* CONFIG_RTC == RTC_DS1339_DS3231 */ | ||
973 | #endif /* CONFIG_RTC */ | ||
974 | #if !defined(CONFIG_RTC) || CONFIG_RTC == RTC_DS1339_DS3231 | ||
975 | { | ||
962 | /* non-RTC version returns an increment from the supplied time, or a | 976 | /* non-RTC version returns an increment from the supplied time, or a |
963 | * fixed standard time/date if no time given as input */ | 977 | * fixed standard time/date if no time given as input */ |
964 | bool next_day = false; | 978 | bool next_day = false; |
@@ -1025,9 +1039,9 @@ static void fat_time(unsigned short* date, | |||
1025 | } | 1039 | } |
1026 | if (tenth) | 1040 | if (tenth) |
1027 | *tenth = 0; | 1041 | *tenth = 0; |
1028 | #endif /* CONFIG_RTC */ | 1042 | } |
1043 | #endif /* !defined(CONFIG_RTC) || CONFIG_RTC == RTC_DS1339_DS3231 */ | ||
1029 | } | 1044 | } |
1030 | |||
1031 | static int write_long_name(struct fat_file* file, | 1045 | static int write_long_name(struct fat_file* file, |
1032 | unsigned int firstentry, | 1046 | unsigned int firstentry, |
1033 | unsigned int numentries, | 1047 | unsigned int numentries, |
diff --git a/firmware/drivers/rtc/rtc_ds1339_ds3231.c b/firmware/drivers/rtc/rtc_ds1339_ds3231.c new file mode 100644 index 0000000000..df67fed735 --- /dev/null +++ b/firmware/drivers/rtc/rtc_ds1339_ds3231.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Robert Kukla | ||
11 | * based on Archos code by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum | ||
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 "rtc.h" | ||
20 | #include "logf.h" | ||
21 | #include "sw_i2c.h" | ||
22 | |||
23 | #define RTC_ADDR 0xD0 | ||
24 | |||
25 | bool rtc_detected = false; | ||
26 | |||
27 | void rtc_init(void) | ||
28 | { | ||
29 | char byte; | ||
30 | |||
31 | sw_i2c_init(); | ||
32 | |||
33 | /* read one byte from RTC; 0 on success */ | ||
34 | rtc_detected = !sw_i2c_read(RTC_ADDR, 0, &byte, 1); | ||
35 | |||
36 | #ifdef HAVE_ALARM_MOD | ||
37 | /* Check + save alarm bit first, before the power thread starts watching */ | ||
38 | rtc_check_alarm_started(false); | ||
39 | #endif | ||
40 | |||
41 | } | ||
42 | |||
43 | #ifdef HAVE_ALARM_MOD | ||
44 | |||
45 | /* check whether the unit has been started by the RTC alarm function */ | ||
46 | /* (check for A2F, which => started using wakeup alarm) */ | ||
47 | bool rtc_check_alarm_started(bool release_alarm) | ||
48 | { | ||
49 | static bool alarm_state, run_before; | ||
50 | bool rc; | ||
51 | |||
52 | if (run_before) { | ||
53 | rc = alarm_state; | ||
54 | alarm_state &= ~release_alarm; | ||
55 | } else { | ||
56 | /* This call resets AF, so we store the state for later recall */ | ||
57 | rc = alarm_state = rtc_check_alarm_flag(); | ||
58 | run_before = true; | ||
59 | } | ||
60 | |||
61 | return rc; | ||
62 | } | ||
63 | /* | ||
64 | * Checks the A2F flag. This call resets A2F once read. | ||
65 | * | ||
66 | */ | ||
67 | bool rtc_check_alarm_flag(void) | ||
68 | { | ||
69 | unsigned char buf[1]; | ||
70 | bool flag = false; | ||
71 | |||
72 | sw_i2c_read(RTC_ADDR, 0x0f, buf, 1); | ||
73 | if (buf[0] & 0x02) flag = true; | ||
74 | |||
75 | rtc_enable_alarm(false); | ||
76 | |||
77 | return flag; | ||
78 | } | ||
79 | |||
80 | /* set alarm time registers to the given time (repeat once per day) */ | ||
81 | void rtc_set_alarm(int h, int m) | ||
82 | { | ||
83 | unsigned char buf[3]; | ||
84 | |||
85 | buf[0] = (((m / 10) << 4) | (m % 10)) & 0x7f; /* minutes */ | ||
86 | buf[1] = (((h / 10) << 4) | (h % 10)) & 0x3f; /* hour */ | ||
87 | buf[2] = 0x80; /* repeat every day */ | ||
88 | |||
89 | sw_i2c_write(RTC_ADDR, 0x0b, buf, 3); | ||
90 | } | ||
91 | |||
92 | /* read out the current alarm time */ | ||
93 | void rtc_get_alarm(int *h, int *m) | ||
94 | { | ||
95 | unsigned char buf[2]; | ||
96 | |||
97 | sw_i2c_read(RTC_ADDR, 0x0b, buf, 2); | ||
98 | |||
99 | *m = ((buf[0] & 0x70) >> 4) * 10 + (buf[0] & 0x0f); | ||
100 | *h = ((buf[1] & 0x30) >> 4) * 10 + (buf[1] & 0x0f); | ||
101 | } | ||
102 | |||
103 | /* turn alarm on or off by setting the alarm flag enable */ | ||
104 | /* the alarm is automatically disabled when the RTC gets Vcc power at startup */ | ||
105 | /* avoid that an alarm occurs when the device is on because this locks the ON key forever */ | ||
106 | /* returns false if alarm was set and alarm flag (output) is off */ | ||
107 | /* returns true if alarm flag went on, which would lock the device, so the alarm was disabled again */ | ||
108 | bool rtc_enable_alarm(bool enable) | ||
109 | { | ||
110 | unsigned char buf[2]; | ||
111 | |||
112 | buf[0] = enable ? 0x26 : 0x04; /* BBSQI INTCN A2IE vs INTCH only */ | ||
113 | buf[1] = 0x00; /* reset alarm flags (and OSF for good measure) */ | ||
114 | |||
115 | sw_i2c_write(RTC_ADDR, 0x0e, buf, 2); | ||
116 | |||
117 | return false; /* all ok */ | ||
118 | } | ||
119 | |||
120 | #endif /* HAVE_ALARM_MOD */ | ||
121 | |||
122 | int rtc_read_datetime(unsigned char* buf) | ||
123 | { | ||
124 | int i; | ||
125 | |||
126 | i = sw_i2c_read(RTC_ADDR, 0, buf, 7); | ||
127 | |||
128 | buf[3]--; /* timefuncs wants 0..6 for wday */ | ||
129 | |||
130 | return i; | ||
131 | } | ||
132 | |||
133 | int rtc_write_datetime(unsigned char* buf) | ||
134 | { | ||
135 | int i; | ||
136 | |||
137 | buf[3]++; /* chip wants 1..7 for wday */ | ||
138 | buf[5]|=0x80; /* chip wants century (always 20xx) */ | ||
139 | |||
140 | i = sw_i2c_write(RTC_ADDR, 0, buf, 7); | ||
141 | |||
142 | return i; | ||
143 | } | ||
144 | |||
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h index e7fb73ea0f..9dccf22d0e 100644 --- a/firmware/export/config-h120.h +++ b/firmware/export/config-h120.h | |||
@@ -45,7 +45,13 @@ | |||
45 | /* Define this if you do software codec */ | 45 | /* Define this if you do software codec */ |
46 | #define CONFIG_CODEC SWCODEC | 46 | #define CONFIG_CODEC SWCODEC |
47 | 47 | ||
48 | /* Define this if you have an remote lcd */ | 48 | #ifndef SIMULATOR |
49 | /* RTC is autodetected on target only */ | ||
50 | #define CONFIG_RTC RTC_DS1339_DS3231 | ||
51 | #define HAVE_ALARM_MOD | ||
52 | #endif | ||
53 | |||
54 | /* Define this if you have an remote lcd */ | ||
49 | #define HAVE_REMOTE_LCD | 55 | #define HAVE_REMOTE_LCD |
50 | 56 | ||
51 | #define CONFIG_LCD LCD_S1D15E06 | 57 | #define CONFIG_LCD LCD_S1D15E06 |
diff --git a/firmware/export/config.h b/firmware/export/config.h index ac2ee688e4..085f86af53 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -153,6 +153,7 @@ | |||
153 | #define RTC_S3C2440 4 | 153 | #define RTC_S3C2440 4 |
154 | #define RTC_E8564 5 /* iriver H10 */ | 154 | #define RTC_E8564 5 /* iriver H10 */ |
155 | #define RTC_AS3514 6 /* Sandisk Sansa e200 series */ | 155 | #define RTC_AS3514 6 /* Sandisk Sansa e200 series */ |
156 | #define RTC_DS1339_DS3231 7 /* h1x0 RTC mod */ | ||
156 | 157 | ||
157 | /* USB On-the-go */ | 158 | /* USB On-the-go */ |
158 | #define USBOTG_ISP1362 1362 /* iriver H300 */ | 159 | #define USBOTG_ISP1362 1362 /* iriver H300 */ |
diff --git a/firmware/export/rtc.h b/firmware/export/rtc.h index c7e3c4a96b..2f13cbb578 100644 --- a/firmware/export/rtc.h +++ b/firmware/export/rtc.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define _RTC_H_ | 20 | #define _RTC_H_ |
21 | 21 | ||
22 | #include <stdbool.h> | 22 | #include <stdbool.h> |
23 | #include <system.h> | ||
23 | 24 | ||
24 | #ifdef CONFIG_RTC | 25 | #ifdef CONFIG_RTC |
25 | 26 | ||
@@ -27,6 +28,10 @@ extern const int dayname[]; | |||
27 | 28 | ||
28 | extern const int monthname[]; | 29 | extern const int monthname[]; |
29 | 30 | ||
31 | #if CONFIG_RTC == RTC_DS1339_DS3231 | ||
32 | extern bool rtc_detected; | ||
33 | #endif | ||
34 | |||
30 | /* Common functions for all targets */ | 35 | /* Common functions for all targets */ |
31 | void rtc_init(void); | 36 | void rtc_init(void); |
32 | int rtc_read_datetime(unsigned char* buf); | 37 | int rtc_read_datetime(unsigned char* buf); |
@@ -40,6 +45,8 @@ int rtc_read(unsigned char address); | |||
40 | int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes); | 45 | int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes); |
41 | int rtc_write(unsigned char address, unsigned char value); | 46 | int rtc_write(unsigned char address, unsigned char value); |
42 | 47 | ||
48 | #endif /* RTC_M41ST84W */ | ||
49 | |||
43 | #ifdef HAVE_ALARM_MOD | 50 | #ifdef HAVE_ALARM_MOD |
44 | void rtc_set_alarm(int h, int m); | 51 | void rtc_set_alarm(int h, int m); |
45 | void rtc_get_alarm(int *h, int *m); | 52 | void rtc_get_alarm(int *h, int *m); |
@@ -48,8 +55,6 @@ bool rtc_check_alarm_started(bool release_alarm); | |||
48 | bool rtc_check_alarm_flag(void); | 55 | bool rtc_check_alarm_flag(void); |
49 | #endif /* HAVE_ALARM_MOD */ | 56 | #endif /* HAVE_ALARM_MOD */ |
50 | 57 | ||
51 | #endif /* RTC_M41ST84W */ | ||
52 | |||
53 | #endif /* CONFIG_RTC */ | 58 | #endif /* CONFIG_RTC */ |
54 | 59 | ||
55 | #endif | 60 | #endif |
diff --git a/firmware/export/sw_i2c.h b/firmware/export/sw_i2c.h new file mode 100644 index 0000000000..42dccad742 --- /dev/null +++ b/firmware/export/sw_i2c.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Robert Kukla | ||
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 | |||
20 | #ifndef _SW_I2C_H | ||
21 | #define _SW_I2C_H | ||
22 | |||
23 | #define SW_I2C_WRITE 0 | ||
24 | #define SW_I2C_READ 1 | ||
25 | |||
26 | void sw_i2c_init(void); | ||
27 | int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count); | ||
28 | int sw_i2c_read (unsigned char chip, unsigned char location, unsigned char* buf, int count); | ||
29 | |||
30 | #endif | ||
diff --git a/firmware/target/coldfire/iriver/h100/sw_i2c-h100.c b/firmware/target/coldfire/iriver/h100/sw_i2c-h100.c new file mode 100644 index 0000000000..cb061875e0 --- /dev/null +++ b/firmware/target/coldfire/iriver/h100/sw_i2c-h100.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Miika Pekkarinen | ||
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 "system.h" | ||
20 | #include "logf.h" | ||
21 | #include "inttypes.h" | ||
22 | |||
23 | #include "sw_i2c.h" | ||
24 | |||
25 | /** | ||
26 | * I2C-functions are copied and ported from fmradio.c. | ||
27 | * later fixed, adapted and moved to a seperate file so they can be re-used by the rtc-ds1339c code by Robert Kukla | ||
28 | */ | ||
29 | |||
30 | /* cute little functions, atomic read-modify-write */ | ||
31 | |||
32 | /* SCL is GPIO, 12 */ | ||
33 | #define SCL ( 0x00001000 & GPIO_READ) | ||
34 | #define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT) | ||
35 | #define SCL_LO or_l( 0x00001000, &GPIO_ENABLE) | ||
36 | #define SCL_HI and_l(~0x00001000, &GPIO_ENABLE) | ||
37 | |||
38 | /* SDA is GPIO1, 13 */ | ||
39 | #define SDA ( 0x00002000 & GPIO1_READ) | ||
40 | #define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT) | ||
41 | #define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE) | ||
42 | #define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE) | ||
43 | |||
44 | /* delay loop to achieve 400kHz at 120MHz CPU frequency */ | ||
45 | #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) | ||
46 | |||
47 | void sw_i2c_init(void) | ||
48 | { | ||
49 | or_l(0x00001000, &GPIO_FUNCTION); | ||
50 | or_l(0x00002000, &GPIO1_FUNCTION); | ||
51 | SDA_HI; | ||
52 | SCL_HI; | ||
53 | SDA_OUT_LO; | ||
54 | SCL_OUT_LO; | ||
55 | } | ||
56 | |||
57 | /* in: C=? D=? | ||
58 | * out: C=L D=L | ||
59 | */ | ||
60 | static void sw_i2c_start(void) | ||
61 | { | ||
62 | SCL_LO; | ||
63 | DELAY; | ||
64 | SDA_HI; | ||
65 | DELAY; | ||
66 | SCL_HI; | ||
67 | DELAY; | ||
68 | SDA_LO; | ||
69 | DELAY; | ||
70 | SCL_LO; | ||
71 | } | ||
72 | |||
73 | /* in: C=L D=? | ||
74 | * out: C=H D=H | ||
75 | */ | ||
76 | static void sw_i2c_stop(void) | ||
77 | { | ||
78 | SDA_LO; | ||
79 | DELAY; | ||
80 | SCL_HI; | ||
81 | DELAY; | ||
82 | SDA_HI; | ||
83 | } | ||
84 | |||
85 | /* in: C=L D=H | ||
86 | * out: C=L D=L | ||
87 | */ | ||
88 | static void sw_i2c_ack(void) | ||
89 | { | ||
90 | SDA_LO; | ||
91 | DELAY; | ||
92 | |||
93 | SCL_HI; | ||
94 | DELAY; | ||
95 | SCL_LO; | ||
96 | } | ||
97 | |||
98 | /* in: C=L D=H | ||
99 | * out: C=L D=H | ||
100 | */ | ||
101 | static void sw_i2c_nack(void) | ||
102 | { | ||
103 | SDA_HI; /* redundant */ | ||
104 | DELAY; | ||
105 | |||
106 | SCL_HI; | ||
107 | DELAY; | ||
108 | SCL_LO; | ||
109 | } | ||
110 | |||
111 | /* in: C=L D=? | ||
112 | * out: C=L D=H | ||
113 | */ | ||
114 | static bool sw_i2c_getack(void) | ||
115 | { | ||
116 | bool ret = true; | ||
117 | /* int count = 10; */ | ||
118 | |||
119 | SDA_HI; /* sets to input */ | ||
120 | DELAY; | ||
121 | SCL_HI; | ||
122 | DELAY; | ||
123 | |||
124 | /* while (SDA && count--) */ | ||
125 | /* DELAY; */ | ||
126 | |||
127 | if (SDA) | ||
128 | /* ack failed */ | ||
129 | ret = false; | ||
130 | |||
131 | SCL_LO; | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /* in: C=L D=? | ||
137 | * out: C=L D=? | ||
138 | */ | ||
139 | static void sw_i2c_outb(unsigned char byte) | ||
140 | { | ||
141 | int i; | ||
142 | |||
143 | /* clock out each bit, MSB first */ | ||
144 | for ( i=0x80; i; i>>=1 ) | ||
145 | { | ||
146 | if ( i & byte ) | ||
147 | SDA_HI; | ||
148 | else | ||
149 | SDA_LO; | ||
150 | DELAY; | ||
151 | |||
152 | SCL_HI; | ||
153 | DELAY; | ||
154 | SCL_LO; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /* in: C=L D=? | ||
159 | * out: C=L D=H | ||
160 | */ | ||
161 | static unsigned char sw_i2c_inb(void) | ||
162 | { | ||
163 | int i; | ||
164 | unsigned char byte = 0; | ||
165 | |||
166 | SDA_HI; /* sets to input */ | ||
167 | |||
168 | /* clock in each bit, MSB first */ | ||
169 | for ( i=0x80; i; i>>=1 ) | ||
170 | { | ||
171 | DELAY; | ||
172 | do { | ||
173 | SCL_HI; | ||
174 | DELAY; | ||
175 | } | ||
176 | while(SCL==0); /* wait for any SCL clock stretching */ | ||
177 | if ( SDA ) | ||
178 | byte |= i; | ||
179 | SCL_LO; | ||
180 | } | ||
181 | |||
182 | return byte; | ||
183 | } | ||
184 | |||
185 | int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | sw_i2c_start(); | ||
190 | sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE); | ||
191 | if (!sw_i2c_getack()) | ||
192 | { | ||
193 | sw_i2c_stop(); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | sw_i2c_outb(location); | ||
198 | if (!sw_i2c_getack()) | ||
199 | { | ||
200 | sw_i2c_stop(); | ||
201 | return -2; | ||
202 | } | ||
203 | |||
204 | for (i=0; i<count; i++) | ||
205 | { | ||
206 | sw_i2c_outb(buf[i]); | ||
207 | if (!sw_i2c_getack()) | ||
208 | { | ||
209 | sw_i2c_stop(); | ||
210 | return -3; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | sw_i2c_stop(); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | int sw_i2c_read(unsigned char chip, unsigned char location, unsigned char* buf, int count) | ||
220 | { | ||
221 | int i; | ||
222 | |||
223 | sw_i2c_start(); | ||
224 | sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE); | ||
225 | if (!sw_i2c_getack()) | ||
226 | { | ||
227 | sw_i2c_stop(); | ||
228 | return -1; | ||
229 | } | ||
230 | |||
231 | sw_i2c_outb(location); | ||
232 | if (!sw_i2c_getack()) | ||
233 | { | ||
234 | sw_i2c_stop(); | ||
235 | return -2; | ||
236 | } | ||
237 | |||
238 | sw_i2c_start(); | ||
239 | sw_i2c_outb((chip & 0xfe) | SW_I2C_READ); | ||
240 | if (!sw_i2c_getack()) | ||
241 | { | ||
242 | sw_i2c_stop(); | ||
243 | return -3; | ||
244 | } | ||
245 | |||
246 | for (i=0; i<count-1; i++) | ||
247 | { | ||
248 | buf[i] = sw_i2c_inb(); | ||
249 | sw_i2c_ack(); | ||
250 | } | ||
251 | |||
252 | /* 1byte min */ | ||
253 | buf[i] = sw_i2c_inb(); | ||
254 | sw_i2c_nack(); | ||
255 | |||
256 | sw_i2c_stop(); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
diff --git a/firmware/target/coldfire/iriver/h300/sw_i2c-h300.c b/firmware/target/coldfire/iriver/h300/sw_i2c-h300.c new file mode 100644 index 0000000000..f0937463e3 --- /dev/null +++ b/firmware/target/coldfire/iriver/h300/sw_i2c-h300.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Miika Pekkarinen | ||
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 "system.h" | ||
20 | #include "logf.h" | ||
21 | #include "inttypes.h" | ||
22 | |||
23 | #include "sw_i2c.h" | ||
24 | |||
25 | #include "pcf50606.h" | ||
26 | |||
27 | void sw_i2c_init(void) | ||
28 | { | ||
29 | /* no extra init required */ | ||
30 | } | ||
31 | |||
32 | int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count) | ||
33 | { | ||
34 | int i; | ||
35 | |||
36 | pcf50606_i2c_start(); | ||
37 | pcf50606_i2c_outb((chip & 0xfe) | SW_I2C_WRITE); | ||
38 | if (!pcf50606_i2c_getack()) | ||
39 | { | ||
40 | pcf50606_i2c_stop(); | ||
41 | return -1; | ||
42 | } | ||
43 | |||
44 | pcf50606_i2c_outb(location); | ||
45 | if (!pcf50606_i2c_getack()) | ||
46 | { | ||
47 | pcf50606_i2c_stop(); | ||
48 | return -2; | ||
49 | } | ||
50 | |||
51 | for (i=0; i<count; i++) | ||
52 | { | ||
53 | pcf50606_i2c_outb(buf[i]); | ||
54 | if (!pcf50606_i2c_getack()) | ||
55 | { | ||
56 | pcf50606_i2c_stop(); | ||
57 | return -3; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | pcf50606_i2c_stop(); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | int sw_i2c_read(unsigned char chip, unsigned char location, unsigned char* buf, int count) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | pcf50606_i2c_start(); | ||
71 | pcf50606_i2c_outb((chip & 0xfe) | SW_I2C_WRITE); | ||
72 | if (!pcf50606_i2c_getack()) | ||
73 | { | ||
74 | pcf50606_i2c_stop(); | ||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | pcf50606_i2c_outb(location); | ||
79 | if (!pcf50606_i2c_getack()) | ||
80 | { | ||
81 | pcf50606_i2c_stop(); | ||
82 | return -2; | ||
83 | } | ||
84 | |||
85 | pcf50606_i2c_start(); | ||
86 | pcf50606_i2c_outb((chip & 0xfe) | SW_I2C_READ); | ||
87 | if (!pcf50606_i2c_getack()) | ||
88 | { | ||
89 | pcf50606_i2c_stop(); | ||
90 | return -3; | ||
91 | } | ||
92 | |||
93 | for (i=0; i<count-1; i++) | ||
94 | { | ||
95 | buf[i] = pcf50606_i2c_inb(true); | ||
96 | } | ||
97 | |||
98 | /* 1byte min */ | ||
99 | buf[i] = pcf50606_i2c_inb(false); | ||
100 | |||
101 | |||
102 | pcf50606_i2c_stop(); | ||
103 | |||
104 | return 0; | ||
105 | } | ||