diff options
Diffstat (limited to 'firmware/target/sh/archos')
47 files changed, 0 insertions, 6766 deletions
diff --git a/firmware/target/sh/archos/app.lds b/firmware/target/sh/archos/app.lds deleted file mode 100644 index 225f11f705..0000000000 --- a/firmware/target/sh/archos/app.lds +++ /dev/null | |||
@@ -1,145 +0,0 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | ENTRY(start) | ||
4 | |||
5 | OUTPUT_FORMAT(elf32-sh) | ||
6 | STARTUP(target/sh/crt0.o) | ||
7 | |||
8 | #define PLUGINSIZE PLUGIN_BUFFER_SIZE | ||
9 | #define CODECSIZE CODEC_SIZE | ||
10 | |||
11 | #ifdef DEBUG | ||
12 | #define STUBOFFSET 0x10000 | ||
13 | #else | ||
14 | #define STUBOFFSET 0 | ||
15 | #endif | ||
16 | |||
17 | #define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE | ||
18 | |||
19 | #define DRAMORIG 0x09000000 + STUBOFFSET | ||
20 | #define IRAMORIG 0x0f000000 | ||
21 | #define IRAMSIZE 0x1000 | ||
22 | |||
23 | /* End of the audio buffer, where the codec buffer starts */ | ||
24 | #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) | ||
25 | |||
26 | /* Where the codec buffer ends, and the plugin buffer starts */ | ||
27 | #define ENDADDR (ENDAUDIOADDR + CODECSIZE) | ||
28 | |||
29 | MEMORY | ||
30 | { | ||
31 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE | ||
32 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE | ||
33 | } | ||
34 | |||
35 | SECTIONS | ||
36 | { | ||
37 | .vectors : | ||
38 | { | ||
39 | loadaddress = .; | ||
40 | _loadaddress = .; | ||
41 | KEEP(*(.resetvectors)); | ||
42 | *(.resetvectors); | ||
43 | KEEP(*(.vectors)); | ||
44 | *(.vectors); | ||
45 | } > DRAM | ||
46 | |||
47 | .text : | ||
48 | { | ||
49 | . = ALIGN(0x200); | ||
50 | *(.init.text) | ||
51 | *(.text*) | ||
52 | . = ALIGN(0x4); | ||
53 | } > DRAM | ||
54 | |||
55 | .rodata : | ||
56 | { | ||
57 | *(.rodata) /* problems without this, dunno why */ | ||
58 | *(.rodata*) | ||
59 | *(.rodata.str1.1) | ||
60 | *(.rodata.str1.4) | ||
61 | . = ALIGN(0x4); | ||
62 | |||
63 | /* Pseudo-allocate the copies of the data sections */ | ||
64 | _datacopy = .; | ||
65 | } > DRAM | ||
66 | |||
67 | /* TRICK ALERT! For RAM execution, we put the .data section at the | ||
68 | same load address as the copy. Thus, we don't waste extra RAM | ||
69 | when we don't actually need the copy. */ | ||
70 | .data : AT ( _datacopy ) | ||
71 | { | ||
72 | _datastart = .; | ||
73 | *(.data*) | ||
74 | . = ALIGN(0x4); | ||
75 | _dataend = .; | ||
76 | } > DRAM | ||
77 | |||
78 | /DISCARD/ : | ||
79 | { | ||
80 | *(.eh_frame) | ||
81 | } | ||
82 | |||
83 | .iram IRAMORIG : | ||
84 | { | ||
85 | _iramstart = .; | ||
86 | *(.icode) | ||
87 | *(.irodata) | ||
88 | *(.idata) | ||
89 | _iramend = .; | ||
90 | } > IRAM AT> DRAM | ||
91 | |||
92 | _iramcopy = LOADADDR(.iram); | ||
93 | _noloaddram = LOADADDR(.iram); | ||
94 | |||
95 | .ibss (NOLOAD) : | ||
96 | { | ||
97 | _iedata = .; | ||
98 | *(.ibss) | ||
99 | . = ALIGN(0x4); | ||
100 | _iend = .; | ||
101 | } > IRAM | ||
102 | |||
103 | .stack _noloaddram (NOLOAD) : | ||
104 | { | ||
105 | *(.stack) | ||
106 | _stackbegin = .; | ||
107 | . += 0x2000; | ||
108 | _stackend = .; | ||
109 | } > DRAM | ||
110 | |||
111 | .bss (NOLOAD) : | ||
112 | { | ||
113 | _edata = .; | ||
114 | *(.bss*) | ||
115 | *(COMMON) | ||
116 | . = ALIGN(0x4); | ||
117 | _end = .; | ||
118 | } > DRAM | ||
119 | |||
120 | .audiobuf (NOLOAD) : | ||
121 | { | ||
122 | . = ALIGN(4); | ||
123 | _audiobuffer = .; | ||
124 | audiobuffer = .; | ||
125 | } > DRAM | ||
126 | |||
127 | .audiobufend ENDAUDIOADDR (NOLOAD) : | ||
128 | { | ||
129 | audiobufend = .; | ||
130 | _audiobufend = .; | ||
131 | } > DRAM | ||
132 | |||
133 | .codec ENDAUDIOADDR (NOLOAD) : | ||
134 | { | ||
135 | codecbuf = .; | ||
136 | _codecbuf = .; | ||
137 | } | ||
138 | |||
139 | .plugin ENDADDR (NOLOAD) : | ||
140 | { | ||
141 | _pluginbuf = .; | ||
142 | pluginbuf = .; | ||
143 | } | ||
144 | } | ||
145 | |||
diff --git a/firmware/target/sh/archos/ata-archos.c b/firmware/target/sh/archos/ata-archos.c deleted file mode 100644 index 2046d3b33f..0000000000 --- a/firmware/target/sh/archos/ata-archos.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "cpu.h" | ||
24 | #include <stdbool.h> | ||
25 | #include "kernel.h" | ||
26 | #include "system.h" | ||
27 | #include "ata-driver.h" | ||
28 | #include "hwcompat.h" | ||
29 | |||
30 | #define ATA_CONTROL1 ((volatile unsigned char*)0x06200206) | ||
31 | #define ATA_CONTROL2 ((volatile unsigned char*)0x06200306) | ||
32 | |||
33 | volatile unsigned char* ata_control; | ||
34 | |||
35 | void ata_reset(void) | ||
36 | { | ||
37 | /* state HRR0 */ | ||
38 | and_b(~0x02, &PADRH); /* assert _RESET */ | ||
39 | sleep(1); /* > 25us */ | ||
40 | |||
41 | /* state HRR1 */ | ||
42 | or_b(0x02, &PADRH); /* negate _RESET */ | ||
43 | sleep(1); /* > 2ms */ | ||
44 | } | ||
45 | |||
46 | void ata_enable(bool on) | ||
47 | { | ||
48 | if(on) | ||
49 | and_b(~0x80, &PADRL); /* enable ATA */ | ||
50 | else | ||
51 | or_b(0x80, &PADRL); /* disable ATA */ | ||
52 | |||
53 | or_b(0x80, &PAIORL); | ||
54 | } | ||
55 | |||
56 | void ata_device_init(void) | ||
57 | { | ||
58 | or_b(0x02, &PAIORH); /* output for ATA reset */ | ||
59 | or_b(0x02, &PADRH); /* release ATA reset */ | ||
60 | PACR2 &= 0xBFFF; /* GPIO function for PA7 (IDE enable) */ | ||
61 | |||
62 | if (HW_MASK & ATA_ADDRESS_200) | ||
63 | ata_control = ATA_CONTROL1; | ||
64 | else | ||
65 | ata_control = ATA_CONTROL2; | ||
66 | } | ||
67 | |||
68 | bool ata_is_coldstart(void) | ||
69 | { | ||
70 | return (PACR2 & 0x4000) != 0; | ||
71 | } | ||
diff --git a/firmware/target/sh/archos/ata-as-archos.S b/firmware/target/sh/archos/ata-as-archos.S deleted file mode 100644 index c403c4c921..0000000000 --- a/firmware/target/sh/archos/ata-as-archos.S +++ /dev/null | |||
@@ -1,233 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004-2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | .section .icode,"ax",@progbits | ||
23 | |||
24 | .align 2 | ||
25 | .global _copy_read_sectors | ||
26 | .type _copy_read_sectors,@function | ||
27 | |||
28 | /* Read a number of words from the ATA data port | ||
29 | * | ||
30 | * Assumes wordcount to be a multiple of 4 | ||
31 | * | ||
32 | * Arguments: | ||
33 | * r4 - buffer address | ||
34 | * r5 - word count | ||
35 | * | ||
36 | * Register usage: | ||
37 | * r0 - scratch | ||
38 | * r1/r2 - read buffers | ||
39 | * r3 - mask (if unaligned) | ||
40 | * r4 - current address | ||
41 | * r5 - end address | ||
42 | * r6 - ata port | ||
43 | */ | ||
44 | |||
45 | _copy_read_sectors: | ||
46 | add r5, r5 /* words -> bytes */ | ||
47 | add r4, r5 /* bytes -> end address */ | ||
48 | add #-12, r5 /* adjust for offsets */ | ||
49 | mov.l .ata_data, r6 | ||
50 | |||
51 | mov r4, r0 | ||
52 | tst #1, r0 /* 16-bit aligned ? */ | ||
53 | bt .r_aligned /* yes, do word copy */ | ||
54 | |||
55 | /* not 16-bit aligned */ | ||
56 | mov #-1, r3 /* prepare a bit mask for high byte */ | ||
57 | shll8 r3 /* r3 = 0xFFFFFF00 */ | ||
58 | |||
59 | mov.w @r6, r2 /* read first word (1st round) */ | ||
60 | mov.b r2, @r4 /* store low byte of first word */ | ||
61 | bra .r_start_b /* jump into loop after next instr. */ | ||
62 | add #-5, r4 /* adjust for dest. offsets; now even */ | ||
63 | |||
64 | .align 2 | ||
65 | .r_loop_b: /* main loop: copy 4 words in a row */ | ||
66 | mov.w @r6, r2 /* read first word (2+ round) */ | ||
67 | and r3, r1 /* get high byte of fourth word (2+ round) */ | ||
68 | extu.b r2, r0 /* get low byte of first word (2+ round) */ | ||
69 | or r1, r0 /* combine with high byte of fourth word */ | ||
70 | mov.w r0, @(4, r4) /* store at buf[4] */ | ||
71 | nop /* maintain alignment */ | ||
72 | .r_start_b: | ||
73 | mov.w @r6, r1 /* read second word */ | ||
74 | and r3, r2 /* get high byte of first word */ | ||
75 | extu.b r1, r0 /* get low byte of second word */ | ||
76 | or r2, r0 /* combine with high byte of first word */ | ||
77 | mov.w r0, @(6, r4) /* store at buf[6] */ | ||
78 | add #8, r4 /* buf += 8 */ | ||
79 | mov.w @r6, r2 /* read third word */ | ||
80 | and r3, r1 /* get high byte of second word */ | ||
81 | extu.b r2, r0 /* get low byte of third word */ | ||
82 | or r1, r0 /* combine with high byte of second word */ | ||
83 | mov.w r0, @r4 /* store at buf[0] */ | ||
84 | cmp/hi r4, r5 /* check for end */ | ||
85 | mov.w @r6, r1 /* read fourth word */ | ||
86 | and r3, r2 /* get high byte of third word */ | ||
87 | extu.b r1, r0 /* get low byte of fourth word */ | ||
88 | or r2, r0 /* combine with high byte of third word */ | ||
89 | mov.w r0, @(2, r4) /* store at buf[2] */ | ||
90 | bt .r_loop_b | ||
91 | /* 24 instructions for 4 copies, takes 30 clock cycles (4 wait) */ | ||
92 | /* avg. 7.5 cycles per word */ | ||
93 | |||
94 | swap.b r1, r0 /* get high byte of last word */ | ||
95 | rts | ||
96 | mov.b r0, @(4, r4) /* and store it */ | ||
97 | |||
98 | /* 16-bit aligned, loop(read and store word) */ | ||
99 | .r_aligned: | ||
100 | mov.w @r6, r2 /* read first word (1st round) */ | ||
101 | bra .r_start_w /* jump into loop after next instr. */ | ||
102 | add #-6, r4 /* adjust for destination offsets */ | ||
103 | |||
104 | .align 2 | ||
105 | .r_loop_w: /* main loop: copy 4 words in a row */ | ||
106 | mov.w @r6, r2 /* read first word (2+ round) */ | ||
107 | swap.b r1, r0 /* swap fourth word (2+ round) */ | ||
108 | mov.w r0, @(4, r4) /* store fourth word (2+ round) */ | ||
109 | nop /* maintain alignment */ | ||
110 | .r_start_w: | ||
111 | mov.w @r6, r1 /* read second word */ | ||
112 | swap.b r2, r0 /* swap first word */ | ||
113 | mov.w r0, @(6, r4) /* store first word in buf[6] */ | ||
114 | add #8, r4 /* buf += 8 */ | ||
115 | mov.w @r6, r2 /* read third word */ | ||
116 | swap.b r1, r0 /* swap second word */ | ||
117 | mov.w r0, @r4 /* store second word in buf[0] */ | ||
118 | cmp/hi r4, r5 /* check for end */ | ||
119 | mov.w @r6, r1 /* read fourth word */ | ||
120 | swap.b r2, r0 /* swap third word */ | ||
121 | mov.w r0, @(2, r4) /* store third word */ | ||
122 | bt .r_loop_w | ||
123 | /* 16 instructions for 4 copies, takes 22 clock cycles (4 wait) */ | ||
124 | /* avg. 5.5 cycles per word */ | ||
125 | |||
126 | swap.b r1, r0 /* swap fourth word (last round) */ | ||
127 | rts | ||
128 | mov.w r0, @(4, r4) /* and store it */ | ||
129 | |||
130 | .r_end: | ||
131 | .size _copy_read_sectors,.r_end-_copy_read_sectors | ||
132 | |||
133 | .align 2 | ||
134 | .global _copy_write_sectors | ||
135 | .type _copy_write_sectors,@function | ||
136 | |||
137 | /* Write a number of words to the ATA data port | ||
138 | * | ||
139 | * Assumes wordcount to be a multiple of 2. | ||
140 | * Writing is not unrolled as much as reading, for several reasons: | ||
141 | * | ||
142 | * - a similar instruction sequence is faster for writing than for reading | ||
143 | * because the auto-incrementing load instructions can be used | ||
144 | * - writing profits from warp mode | ||
145 | * | ||
146 | * Both of these add up to have writing faster than the more unrolled reading. | ||
147 | * | ||
148 | * Arguments: | ||
149 | * r4 - buffer address | ||
150 | * r5 - word count | ||
151 | * | ||
152 | * Register usage: | ||
153 | * r0/r1 - scratch | ||
154 | * r2/r3 - write buffers | ||
155 | * r4 - current address | ||
156 | * r5 - end address | ||
157 | * r6 - mask (if unaligned) | ||
158 | * r7 - ata port | ||
159 | */ | ||
160 | |||
161 | _copy_write_sectors: | ||
162 | add r5, r5 /* words -> bytes */ | ||
163 | add r4, r5 /* bytes -> end address */ | ||
164 | add #-4, r5 /* adjust for offsets */ | ||
165 | mov.l .ata_data, r7 | ||
166 | |||
167 | mov r4, r0 | ||
168 | tst #1, r0 /* 16-bit aligned ? */ | ||
169 | bt .w_aligned /* yes, do word copy */ | ||
170 | |||
171 | /* not 16-bit aligned */ | ||
172 | mov #-1, r6 /* prepare a bit mask for high byte */ | ||
173 | shll8 r6 /* r6 = 0xFFFFFF00 */ | ||
174 | |||
175 | mov.b @r4+, r2 /* load (initial old second) first byte */ | ||
176 | mov.w @r4+, r3 /* load (initial) first word */ | ||
177 | bra .w_start_b | ||
178 | extu.b r2, r0 /* extend unsigned */ | ||
179 | |||
180 | .align 2 | ||
181 | .w_loop_b: /* main loop: copy 2 words in a row */ | ||
182 | mov.w @r4+, r3 /* load first word (2+ round) */ | ||
183 | extu.b r2, r0 /* put away low byte of second word (2+ round) */ | ||
184 | and r6, r2 /* get high byte of second word (2+ round) */ | ||
185 | or r1, r2 /* combine with low byte of old first word */ | ||
186 | mov.w r2, @r7 /* write that */ | ||
187 | .w_start_b: | ||
188 | cmp/hi r4, r5 /* check for end */ | ||
189 | mov.w @r4+, r2 /* load second word */ | ||
190 | extu.b r3, r1 /* put away low byte of first word */ | ||
191 | and r6, r3 /* get high byte of first word */ | ||
192 | or r0, r3 /* combine with high byte of old second word */ | ||
193 | mov.w r3, @r7 /* write that */ | ||
194 | bt .w_loop_b | ||
195 | /* 12 instructions for 2 copies, takes 14 clock cycles */ | ||
196 | /* avg. 7 cycles per word */ | ||
197 | |||
198 | /* the loop "overreads" 1 byte past the buffer end, however, the last */ | ||
199 | /* byte is not written to disk */ | ||
200 | and r6, r2 /* get high byte of last word */ | ||
201 | or r1, r2 /* combine with low byte of old first word */ | ||
202 | rts | ||
203 | mov.w r2, @r7 /* write last word */ | ||
204 | |||
205 | /* 16-bit aligned, loop(load and write word) */ | ||
206 | .w_aligned: | ||
207 | bra .w_start_w /* jump into loop after next instr. */ | ||
208 | mov.w @r4+, r2 /* load first word (1st round) */ | ||
209 | |||
210 | .align 2 | ||
211 | .w_loop_w: /* main loop: copy 2 words in a row */ | ||
212 | mov.w @r4+, r2 /* load first word (2+ round) */ | ||
213 | swap.b r1, r0 /* swap second word (2+ round) */ | ||
214 | mov.w r0, @r7 /* write second word (2+ round) */ | ||
215 | .w_start_w: | ||
216 | cmp/hi r4, r5 /* check for end */ | ||
217 | mov.w @r4+, r1 /* load second word */ | ||
218 | swap.b r2, r0 /* swap first word */ | ||
219 | mov.w r0, @r7 /* write first word */ | ||
220 | bt .w_loop_w | ||
221 | /* 8 instructions for 2 copies, takes 10 clock cycles */ | ||
222 | /* avg. 5 cycles per word */ | ||
223 | |||
224 | swap.b r1, r0 /* swap second word (last round) */ | ||
225 | rts | ||
226 | mov.w r0, @r7 /* and write it */ | ||
227 | |||
228 | .w_end: | ||
229 | .size _copy_write_sectors,.w_end-_copy_write_sectors | ||
230 | |||
231 | .align 2 | ||
232 | .ata_data: | ||
233 | .long 0x06104100 /* ATA data port */ | ||
diff --git a/firmware/target/sh/archos/ata-target.h b/firmware/target/sh/archos/ata-target.h deleted file mode 100644 index dc55cdd5d5..0000000000 --- a/firmware/target/sh/archos/ata-target.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef ATA_TARGET_H | ||
22 | #define ATA_TARGET_H | ||
23 | |||
24 | /* asm optimised read & write loops */ | ||
25 | #define ATA_OPTIMIZED_READING | ||
26 | #define ATA_OPTIMIZED_WRITING | ||
27 | |||
28 | #define ATA_SWAP_WORDS | ||
29 | |||
30 | #define ATA_IOBASE 0x06100100 | ||
31 | #define ATA_DATA (*((volatile unsigned short*)0x06104100)) | ||
32 | #define ATA_CONTROL (*ata_control) | ||
33 | |||
34 | #define ATA_ERROR (*((volatile unsigned char*)ATA_IOBASE + 1)) | ||
35 | #define ATA_NSECTOR (*((volatile unsigned char*)ATA_IOBASE + 2)) | ||
36 | #define ATA_SECTOR (*((volatile unsigned char*)ATA_IOBASE + 3)) | ||
37 | #define ATA_LCYL (*((volatile unsigned char*)ATA_IOBASE + 4)) | ||
38 | #define ATA_HCYL (*((volatile unsigned char*)ATA_IOBASE + 5)) | ||
39 | #define ATA_SELECT (*((volatile unsigned char*)ATA_IOBASE + 6)) | ||
40 | #define ATA_COMMAND (*((volatile unsigned char*)ATA_IOBASE + 7)) | ||
41 | |||
42 | extern volatile unsigned char* ata_control; | ||
43 | |||
44 | |||
45 | #endif | ||
diff --git a/firmware/target/sh/archos/audio-archos.c b/firmware/target/sh/archos/audio-archos.c deleted file mode 100644 index 2c2579bec5..0000000000 --- a/firmware/target/sh/archos/audio-archos.c +++ /dev/null | |||
@@ -1,543 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Code that has been in mpeg.c before, now creating an encapsulated play | ||
11 | * data module, to be used by other sources than file playback as well. | ||
12 | * | ||
13 | * Copyright (C) 2004 by Linus Nielsen Feltzing | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version 2 | ||
18 | * of the License, or (at your option) any later version. | ||
19 | * | ||
20 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
21 | * KIND, either express or implied. | ||
22 | * | ||
23 | ****************************************************************************/ | ||
24 | #include <stdbool.h> | ||
25 | #include "config.h" | ||
26 | #include "debug.h" | ||
27 | #include "panic.h" | ||
28 | #include <kernel.h> | ||
29 | #include "mp3_playback.h" | ||
30 | #include "sound.h" | ||
31 | #include "i2c.h" | ||
32 | #include "system.h" | ||
33 | #include "audiohw.h" | ||
34 | |||
35 | /* hacking into mpeg.c, recording is still there */ | ||
36 | #if CONFIG_CODEC == MAS3587F | ||
37 | enum | ||
38 | { | ||
39 | MPEG_DECODER, | ||
40 | MPEG_ENCODER | ||
41 | } mpeg_mode; | ||
42 | #endif /* #ifdef MAS3587F */ | ||
43 | |||
44 | #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) && !defined(SIMULATOR) | ||
45 | extern unsigned long shadow_io_control_main; | ||
46 | extern unsigned shadow_codec_reg0; | ||
47 | #endif | ||
48 | |||
49 | /**** globals ****/ | ||
50 | |||
51 | /* own version, independent of mpeg.c */ | ||
52 | static bool paused; /* playback is paused */ | ||
53 | static bool playing; /* We are playing an MP3 stream */ | ||
54 | |||
55 | /* the registered callback function to ask for more mp3 data */ | ||
56 | static mp3_play_callback_t callback_for_more; | ||
57 | |||
58 | /* list of tracks in memory */ | ||
59 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ | ||
60 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) | ||
61 | |||
62 | bool audio_is_initialized = false; | ||
63 | |||
64 | /* FIX: this code pretty much assumes a MAS */ | ||
65 | |||
66 | /* dirty calls to mpeg.c */ | ||
67 | extern void playback_tick(void); | ||
68 | extern void rec_tick(void); | ||
69 | |||
70 | unsigned long mas_version_code; | ||
71 | |||
72 | #if CONFIG_CODEC == MAS3507D | ||
73 | static void mas_poll_start(void) | ||
74 | { | ||
75 | unsigned int count; | ||
76 | |||
77 | count = 9 * FREQ / 10000 / 8; /* 0.9 ms */ | ||
78 | |||
79 | /* We are using timer 1 */ | ||
80 | |||
81 | TSTR &= ~0x02; /* Stop the timer */ | ||
82 | TSNC &= ~0x02; /* No synchronization */ | ||
83 | TMDR &= ~0x02; /* Operate normally */ | ||
84 | |||
85 | TCNT1 = 0; /* Start counting at 0 */ | ||
86 | GRA1 = count; | ||
87 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
88 | |||
89 | /* Enable interrupt on level 5 */ | ||
90 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
91 | |||
92 | TSR1 &= ~0x02; | ||
93 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
94 | |||
95 | TSTR |= 0x02; /* Start timer 1 */ | ||
96 | } | ||
97 | #elif CONFIG_CODEC != SWCODEC | ||
98 | static void postpone_dma_tick(void) | ||
99 | { | ||
100 | unsigned int count; | ||
101 | |||
102 | count = 8 * FREQ / 10000 / 8; /* 0.8 ms */ | ||
103 | |||
104 | /* We are using timer 1 */ | ||
105 | |||
106 | TSTR &= ~0x02; /* Stop the timer */ | ||
107 | TSNC &= ~0x02; /* No synchronization */ | ||
108 | TMDR &= ~0x02; /* Operate normally */ | ||
109 | |||
110 | TCNT1 = 0; /* Start counting at 0 */ | ||
111 | GRA1 = count; | ||
112 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
113 | |||
114 | /* Enable interrupt on level 5 */ | ||
115 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
116 | |||
117 | TSR1 &= ~0x02; | ||
118 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
119 | |||
120 | TSTR |= 0x02; /* Start timer 1 */ | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
125 | void demand_irq_enable(bool on) | ||
126 | { | ||
127 | int oldlevel = disable_irq_save(); | ||
128 | |||
129 | if(on) | ||
130 | { | ||
131 | IPRA = (IPRA & 0xfff0) | 0x000b; | ||
132 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
133 | } | ||
134 | else | ||
135 | IPRA &= 0xfff0; | ||
136 | |||
137 | restore_irq(oldlevel); | ||
138 | } | ||
139 | #endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ | ||
140 | |||
141 | |||
142 | static void play_tick(void) | ||
143 | { | ||
144 | if(playing && !paused) | ||
145 | { | ||
146 | /* Start DMA if it is disabled and the DEMAND pin is high */ | ||
147 | if(!(SCR0 & 0x80) && (PBDR & 0x4000)) | ||
148 | { | ||
149 | SCR0 |= 0x80; | ||
150 | } | ||
151 | |||
152 | playback_tick(); /* dirty call to mpeg.c */ | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void DEI3(void) __attribute__((interrupt_handler)); | ||
157 | void DEI3(void) | ||
158 | { | ||
159 | const void* start; | ||
160 | size_t size = 0; | ||
161 | |||
162 | if (callback_for_more != NULL) | ||
163 | { | ||
164 | callback_for_more(&start, &size); | ||
165 | } | ||
166 | |||
167 | if (size > 0) | ||
168 | { | ||
169 | DTCR3 = size & 0xffff; | ||
170 | SAR3 = (unsigned int) start; | ||
171 | } | ||
172 | else | ||
173 | { | ||
174 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | ||
175 | } | ||
176 | |||
177 | CHCR3 &= ~0x0002; /* Clear DMA interrupt */ | ||
178 | } | ||
179 | |||
180 | void IMIA1(void) __attribute__((interrupt_handler)); | ||
181 | void IMIA1(void) /* Timer 1 interrupt */ | ||
182 | { | ||
183 | if(playing) | ||
184 | play_tick(); | ||
185 | TSR1 &= ~0x01; | ||
186 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
187 | /* Disable interrupt */ | ||
188 | IPRC &= ~0x000f; | ||
189 | #endif | ||
190 | } | ||
191 | |||
192 | void IRQ6(void) __attribute__((interrupt_handler)); | ||
193 | void IRQ6(void) /* PB14: MAS stop demand IRQ */ | ||
194 | { | ||
195 | SCR0 &= ~0x80; | ||
196 | } | ||
197 | |||
198 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
199 | void IRQ3(void) __attribute__((interrupt_handler)); | ||
200 | void IRQ3(void) /* PA15: MAS demand IRQ */ | ||
201 | { | ||
202 | /* Begin with setting the IRQ to edge sensitive */ | ||
203 | ICR |= 0x0010; | ||
204 | |||
205 | #if CONFIG_CODEC == MAS3587F | ||
206 | if(mpeg_mode == MPEG_ENCODER) | ||
207 | rec_tick(); | ||
208 | else | ||
209 | #endif | ||
210 | postpone_dma_tick(); | ||
211 | |||
212 | /* Workaround for sh-elf-gcc 3.3.x bug with -O2 or -Os and ISRs | ||
213 | * (invalid cross-jump optimisation) */ | ||
214 | asm volatile (""); | ||
215 | } | ||
216 | #endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ | ||
217 | |||
218 | static void setup_sci0(void) | ||
219 | { | ||
220 | /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */ | ||
221 | PBCR1 = (PBCR1 & 0x0cff) | 0x1208; | ||
222 | |||
223 | /* Set PB12 to output */ | ||
224 | or_b(0x10, &PBIORH); | ||
225 | |||
226 | /* Disable serial port */ | ||
227 | SCR0 = 0x00; | ||
228 | |||
229 | /* Synchronous, no prescale */ | ||
230 | SMR0 = 0x80; | ||
231 | |||
232 | /* Set baudrate 1Mbit/s */ | ||
233 | BRR0 = 0x02; | ||
234 | |||
235 | /* use SCK as serial clock output */ | ||
236 | SCR0 = 0x01; | ||
237 | |||
238 | /* Clear FER and PER */ | ||
239 | SSR0 &= 0xe7; | ||
240 | |||
241 | /* Set interrupt ITU2 and SCI0 priority to 0 */ | ||
242 | IPRD &= 0x0ff0; | ||
243 | |||
244 | /* set PB15 and PB14 to inputs */ | ||
245 | and_b(~0x80, &PBIORH); | ||
246 | and_b(~0x40, &PBIORH); | ||
247 | |||
248 | /* Enable End of DMA interrupt at prio 8 */ | ||
249 | IPRC = (IPRC & 0xf0ff) | 0x0800; | ||
250 | |||
251 | /* Enable Tx (only!) */ | ||
252 | SCR0 |= 0x20; | ||
253 | } | ||
254 | |||
255 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
256 | static void init_playback(void) | ||
257 | { | ||
258 | unsigned long val; | ||
259 | int rc; | ||
260 | |||
261 | mp3_play_pause(false); | ||
262 | |||
263 | mas_reset(); | ||
264 | |||
265 | /* Enable the audio CODEC and the DSP core, max analog voltage range */ | ||
266 | rc = mas_direct_config_write(MAS_CONTROL, 0x8c00); | ||
267 | if(rc < 0) | ||
268 | panicf("mas_ctrl_w: %d", rc); | ||
269 | |||
270 | /* Stop the current application */ | ||
271 | val = 0; | ||
272 | mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1); | ||
273 | do | ||
274 | { | ||
275 | mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1); | ||
276 | } while(val); | ||
277 | |||
278 | /* Enable the D/A Converter */ | ||
279 | shadow_codec_reg0 = 0x0001; | ||
280 | mas_codec_writereg(0x0, shadow_codec_reg0); | ||
281 | |||
282 | /* ADC scale 0%, DSP scale 100% */ | ||
283 | mas_codec_writereg(6, 0x0000); | ||
284 | mas_codec_writereg(7, 0x4000); | ||
285 | |||
286 | #ifdef HAVE_SPDIF_OUT | ||
287 | val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */ | ||
288 | #else | ||
289 | val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */ | ||
290 | #endif | ||
291 | mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1); | ||
292 | |||
293 | /* Set Demand mode and validate all settings */ | ||
294 | shadow_io_control_main = 0x25; | ||
295 | mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); | ||
296 | |||
297 | /* Start the Layer2/3 decoder applications */ | ||
298 | val = 0x0c; | ||
299 | mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1); | ||
300 | do | ||
301 | { | ||
302 | mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1); | ||
303 | } while((val & 0x0c) != 0x0c); | ||
304 | |||
305 | #if CONFIG_CODEC == MAS3587F | ||
306 | mpeg_mode = MPEG_DECODER; | ||
307 | #endif | ||
308 | |||
309 | /* set IRQ6 to edge detect */ | ||
310 | ICR |= 0x02; | ||
311 | |||
312 | /* set IRQ6 prio 8 */ | ||
313 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
314 | |||
315 | DEBUGF("MAS Decoding application started\n"); | ||
316 | } | ||
317 | #endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ | ||
318 | |||
319 | void mp3_init(int volume, int bass, int treble, int balance, int loudness, | ||
320 | int avc, int channel_config, int stereo_width, | ||
321 | int mdb_strength, int mdb_harmonics, | ||
322 | int mdb_center, int mdb_shape, bool mdb_enable, | ||
323 | bool superbass) | ||
324 | { | ||
325 | #if CONFIG_CODEC == MAS3507D | ||
326 | unsigned long val; | ||
327 | (void)loudness; | ||
328 | (void)avc; | ||
329 | (void)mdb_strength; | ||
330 | (void)mdb_harmonics; | ||
331 | (void)mdb_center; | ||
332 | (void)mdb_shape; | ||
333 | (void)mdb_enable; | ||
334 | (void)superbass; | ||
335 | #endif | ||
336 | |||
337 | setup_sci0(); | ||
338 | |||
339 | #ifdef HAVE_MAS_SIBI_CONTROL | ||
340 | and_b(~0x01, &PBDRH); /* drive SIBI low */ | ||
341 | or_b(0x01, &PBIORH); /* output for PB8 */ | ||
342 | #endif | ||
343 | |||
344 | #if CONFIG_CODEC == MAS3507D | ||
345 | mas_reset(); | ||
346 | #elif CONFIG_CODEC == MAS3587F | ||
347 | or_b(0x08, &PAIORH); /* output for /PR */ | ||
348 | init_playback(); | ||
349 | |||
350 | mas_version_code = mas_readver(); | ||
351 | DEBUGF("MAS3587 derivate %d, version %c%d\n", | ||
352 | (mas_version_code & 0xf000) >> 12, | ||
353 | 'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff); | ||
354 | #elif CONFIG_CODEC == MAS3539F | ||
355 | or_b(0x08, &PAIORH); /* output for /PR */ | ||
356 | init_playback(); | ||
357 | |||
358 | mas_version_code = mas_readver(); | ||
359 | DEBUGF("MAS3539 derivate %d, version %c%d\n", | ||
360 | (mas_version_code & 0xf000) >> 12, | ||
361 | 'A' + ((mas_version_code & 0x0f00) >> 8), mas_version_code & 0xff); | ||
362 | #endif | ||
363 | |||
364 | #ifdef HAVE_DAC3550A | ||
365 | dac_init(); | ||
366 | #endif | ||
367 | |||
368 | #if CONFIG_CODEC == MAS3507D | ||
369 | /* set IRQ6 to edge detect */ | ||
370 | ICR |= 0x02; | ||
371 | |||
372 | /* set IRQ6 prio 8 */ | ||
373 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
374 | |||
375 | mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1); | ||
376 | |||
377 | mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */ | ||
378 | mas_run(1); | ||
379 | sleep(HZ); | ||
380 | |||
381 | /* Clear the upper 12 bits of the 32-bit samples */ | ||
382 | mas_writereg(0xc5, 0); | ||
383 | mas_writereg(0xc6, 0); | ||
384 | |||
385 | /* We need to set the PLL for a 14.31818MHz crystal */ | ||
386 | if(mas_version_code == 0x0601) /* Version F10? */ | ||
387 | { | ||
388 | val = 0x5d9d0; | ||
389 | mas_writemem(MAS_BANK_D0, 0x32d, &val, 1); | ||
390 | val = 0xfffceceb; | ||
391 | mas_writemem(MAS_BANK_D0, 0x32e, &val, 1); | ||
392 | val = 0x0; | ||
393 | mas_writemem(MAS_BANK_D0, 0x32f, &val, 1); | ||
394 | mas_run(0x475); | ||
395 | } | ||
396 | else | ||
397 | { | ||
398 | val = 0x5d9d0; | ||
399 | mas_writemem(MAS_BANK_D0, 0x36d, &val, 1); | ||
400 | val = 0xfffceceb; | ||
401 | mas_writemem(MAS_BANK_D0, 0x36e, &val, 1); | ||
402 | val = 0x0; | ||
403 | mas_writemem(MAS_BANK_D0, 0x36f, &val, 1); | ||
404 | mas_run(0xfcb); | ||
405 | } | ||
406 | |||
407 | #endif | ||
408 | |||
409 | #if CONFIG_CODEC == MAS3507D | ||
410 | mas_poll_start(); | ||
411 | |||
412 | mas_writereg(MAS_REG_KPRESCALE, 0xe9400); | ||
413 | dac_enable(true); | ||
414 | #endif | ||
415 | |||
416 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
417 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
418 | PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ | ||
419 | #endif | ||
420 | |||
421 | /* Must be done before calling sound_set() */ | ||
422 | audio_is_initialized = true; | ||
423 | |||
424 | sound_set(SOUND_BASS, bass); | ||
425 | sound_set(SOUND_TREBLE, treble); | ||
426 | sound_set(SOUND_BALANCE, balance); | ||
427 | sound_set(SOUND_VOLUME, volume); | ||
428 | sound_set(SOUND_CHANNELS, channel_config); | ||
429 | sound_set(SOUND_STEREO_WIDTH, stereo_width); | ||
430 | |||
431 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
432 | sound_set(SOUND_LOUDNESS, loudness); | ||
433 | sound_set(SOUND_AVC, avc); | ||
434 | sound_set(SOUND_MDB_STRENGTH, mdb_strength); | ||
435 | sound_set(SOUND_MDB_HARMONICS, mdb_harmonics); | ||
436 | sound_set(SOUND_MDB_CENTER, mdb_center); | ||
437 | sound_set(SOUND_MDB_SHAPE, mdb_shape); | ||
438 | sound_set(SOUND_MDB_ENABLE, mdb_enable); | ||
439 | sound_set(SOUND_SUPERBASS, superbass); | ||
440 | #endif | ||
441 | |||
442 | playing = false; | ||
443 | paused = true; | ||
444 | } | ||
445 | |||
446 | void mp3_shutdown(void) | ||
447 | { | ||
448 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
449 | unsigned long val = 1; | ||
450 | mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &val, 1); /* Mute */ | ||
451 | #endif | ||
452 | |||
453 | #if CONFIG_CODEC == MAS3507D | ||
454 | dac_volume(0, 0, false); | ||
455 | #endif | ||
456 | } | ||
457 | |||
458 | /* new functions, to be exported to plugin API */ | ||
459 | |||
460 | #if CONFIG_CODEC == MAS3587F | ||
461 | void mp3_play_init(void) | ||
462 | { | ||
463 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
464 | init_playback(); | ||
465 | #endif | ||
466 | playing = false; | ||
467 | paused = true; | ||
468 | callback_for_more = NULL; | ||
469 | } | ||
470 | #endif | ||
471 | |||
472 | void mp3_play_data(const void* start, size_t size, | ||
473 | mp3_play_callback_t get_more) | ||
474 | { | ||
475 | /* init DMA */ | ||
476 | DAR3 = 0x5FFFEC3; | ||
477 | CHCR3 &= ~0x0002; /* Clear interrupt */ | ||
478 | CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */ | ||
479 | DMAOR = 0x0001; /* Enable DMA */ | ||
480 | |||
481 | callback_for_more = get_more; | ||
482 | |||
483 | SAR3 = (unsigned int)start; | ||
484 | DTCR3 = size & 0xffff; | ||
485 | |||
486 | playing = true; | ||
487 | paused = true; | ||
488 | |||
489 | CHCR3 |= 0x0001; /* Enable DMA IRQ */ | ||
490 | |||
491 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
492 | demand_irq_enable(true); | ||
493 | #endif | ||
494 | } | ||
495 | |||
496 | void mp3_play_pause(bool play) | ||
497 | { | ||
498 | if (paused && play) | ||
499 | { /* resume playback */ | ||
500 | SCR0 |= 0x80; | ||
501 | paused = false; | ||
502 | } | ||
503 | else if (!paused && !play) | ||
504 | { /* stop playback */ | ||
505 | SCR0 &= 0x7f; | ||
506 | paused = true; | ||
507 | } | ||
508 | } | ||
509 | |||
510 | bool mp3_pause_done(void) | ||
511 | { | ||
512 | unsigned long frame_count; | ||
513 | |||
514 | if (!paused) | ||
515 | return false; | ||
516 | |||
517 | mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count, 1); | ||
518 | /* This works because the frame counter never wraps, | ||
519 | * i.e. zero always means lost sync. */ | ||
520 | return frame_count == 0; | ||
521 | } | ||
522 | |||
523 | void mp3_play_stop(void) | ||
524 | { | ||
525 | playing = false; | ||
526 | mp3_play_pause(false); | ||
527 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | ||
528 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
529 | demand_irq_enable(false); | ||
530 | #endif | ||
531 | } | ||
532 | |||
533 | bool mp3_is_playing(void) | ||
534 | { | ||
535 | return playing; | ||
536 | } | ||
537 | |||
538 | |||
539 | /* returns the next byte position which would be transferred */ | ||
540 | unsigned char* mp3_get_pos(void) | ||
541 | { | ||
542 | return (unsigned char*)SAR3; | ||
543 | } | ||
diff --git a/firmware/target/sh/archos/boot.lds b/firmware/target/sh/archos/boot.lds deleted file mode 100644 index b3c2c90a6c..0000000000 --- a/firmware/target/sh/archos/boot.lds +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | ENTRY(start) | ||
4 | OUTPUT_FORMAT(elf32-sh) | ||
5 | STARTUP(target/sh/crt0.o) | ||
6 | |||
7 | #define DRAMSIZE (MEMORYSIZE * 0x100000) | ||
8 | |||
9 | #define DRAMORIG 0x09000000 | ||
10 | #define IRAMORIG 0x0f000000 | ||
11 | #define IRAMSIZE 0x1000 | ||
12 | #define FLASHORIG 0x02000000 + ROM_START | ||
13 | #define FLASHSIZE 256K - ROM_START | ||
14 | |||
15 | MEMORY | ||
16 | { | ||
17 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE | ||
18 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE | ||
19 | FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE | ||
20 | } | ||
21 | |||
22 | SECTIONS | ||
23 | { | ||
24 | .vectors : | ||
25 | { | ||
26 | _datacopy = .; | ||
27 | } > FLASH | ||
28 | |||
29 | .data : AT ( _datacopy ) | ||
30 | { | ||
31 | _datastart = .; | ||
32 | KEEP(*(.resetvectors)); | ||
33 | *(.resetvectors); | ||
34 | KEEP(*(.vectors)); | ||
35 | *(.vectors); | ||
36 | . = ALIGN(0x200); | ||
37 | *(.icode) | ||
38 | *(.irodata) | ||
39 | *(.idata) | ||
40 | *(.data*) | ||
41 | . = ALIGN(0x4); | ||
42 | _dataend = .; | ||
43 | . = ALIGN(0x10); /* Maintain proper alignment for .text section */ | ||
44 | } > IRAM | ||
45 | |||
46 | /* TRICK ALERT! Newer versions of the linker don't allow output sections | ||
47 | to overlap even if one of them is empty, so advance the location pointer | ||
48 | "by hand" */ | ||
49 | .text LOADADDR(.data) + SIZEOF(.data) : | ||
50 | { | ||
51 | *(.init.text) | ||
52 | *(.text*) | ||
53 | . = ALIGN(0x4); | ||
54 | } > FLASH | ||
55 | |||
56 | .rodata : | ||
57 | { | ||
58 | *(.rodata*) | ||
59 | . = ALIGN(0x4); | ||
60 | _iramcopy = .; | ||
61 | } > FLASH | ||
62 | |||
63 | .stack : | ||
64 | { | ||
65 | *(.stack) | ||
66 | _stackbegin = .; | ||
67 | stackbegin = .; | ||
68 | . += 0x2000; | ||
69 | _stackend = .; | ||
70 | stackend = .; | ||
71 | } > IRAM | ||
72 | |||
73 | .bss : | ||
74 | { | ||
75 | _edata = .; | ||
76 | *(.ibss) | ||
77 | *(.bss*) | ||
78 | *(COMMON) | ||
79 | _end = .; | ||
80 | } > IRAM | ||
81 | } | ||
diff --git a/firmware/target/sh/archos/descramble.S b/firmware/target/sh/archos/descramble.S deleted file mode 100644 index 0ab5e93dce..0000000000 --- a/firmware/target/sh/archos/descramble.S +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | .section .icode,"ax",@progbits | ||
23 | |||
24 | .align 2 /* this aligns to 2^2=4 byte bounday */ | ||
25 | .global _descramble | ||
26 | .type _descramble,@function | ||
27 | |||
28 | /* Descramble a block of byte data, from source to dest, processing len | ||
29 | * bytes. Size only limited by the len argument. Note that len must | ||
30 | * be an even multiple of 4 (something rolo_load() already assumes. | ||
31 | * (Does the Archos firmware loader also require that?). | ||
32 | * | ||
33 | * Returns the 16-bit "sum" checksum of the descrambled data. | ||
34 | * | ||
35 | * Arguments: | ||
36 | * r4 - source (unsigned char*) | ||
37 | * r5 - dest (unsigned char*) | ||
38 | * r6 - len (unsigned int) | ||
39 | * | ||
40 | * Register usage: | ||
41 | * r0 - data | ||
42 | * r1 - temp | ||
43 | * r2 - checksum | ||
44 | * r3 - current src address | ||
45 | * r4 - source | ||
46 | * r5 - dest | ||
47 | * r6 - len -> source_end | ||
48 | * r7 - dest_end | ||
49 | * r8 - len / 4 | ||
50 | */ | ||
51 | |||
52 | _descramble: | ||
53 | mov.l r8,@-r15 | ||
54 | mov r6,r8 | ||
55 | shlr2 r8 /* r8 = len / 4 */ | ||
56 | mov r5,r7 | ||
57 | add r6,r7 /* dest_end = dest + len */ | ||
58 | add r4,r6 /* source_end = source + len */ | ||
59 | mov r4,r3 /* addr = source */ | ||
60 | mov #0,r2 /* checksum = 0 */ | ||
61 | |||
62 | .loop: | ||
63 | mov.b @r3,r0 /* data = *addr */ | ||
64 | add r8,r3 /* addr += len / 4 */ | ||
65 | extu.b r0,r0 /* zero extend data byte */ | ||
66 | swap.b r0,r1 /* byte swap low word to temp */ | ||
67 | or r1,r0 /* r0's two lower bytes now identical */ | ||
68 | shlr r0 /* -> this equals "rotr.b r0" now */ | ||
69 | not r0,r0 /* negate */ | ||
70 | extu.b r0,r0 /* zero extend low byte (only needed for sum) */ | ||
71 | mov.b r0,@r5 /* *dest = data */ | ||
72 | add r0,r2 /* checksum += data */ | ||
73 | add #1,r5 /* dest++ */ | ||
74 | cmp/hi r3,r6 /* addr < source_end ? */ | ||
75 | bt .loop | ||
76 | |||
77 | add #1,r4 /* source++ */ | ||
78 | mov r4,r3 /* addr = source */ | ||
79 | cmp/hi r5,r7 /* dest < dest_end */ | ||
80 | bt .loop | ||
81 | |||
82 | /* 15 clock cycles if no reset of source address, 19 if reset, | ||
83 | * avg. 16 cycles per byte. Magnus' Version needed 17-22 cycles per byte | ||
84 | */ | ||
85 | |||
86 | mov.l @r15+,r8 | ||
87 | rts | ||
88 | extu.w r2,r0 | ||
89 | |||
90 | |||
91 | /* Move len bytes from source to dest (which must be suitably aligned for | ||
92 | * long moves) and jump to dest + 0x200. | ||
93 | * | ||
94 | * Arguments: | ||
95 | * r4 - source | ||
96 | * r5 - dest | ||
97 | * r6 - len | ||
98 | */ | ||
99 | |||
100 | .align 2 | ||
101 | .global _rolo_restart | ||
102 | .type _rolo_restart,@function | ||
103 | |||
104 | _rolo_restart: | ||
105 | mov r5,r0 | ||
106 | sub r4,r0 /* r0 = dest - source */ | ||
107 | add #-4,r0 /* adjust for early increment */ | ||
108 | add r4,r6 /* r6 = source + len */ | ||
109 | |||
110 | .copy: /* loop takes 6 cycles per longword */ | ||
111 | mov.l @r4+,r1 | ||
112 | cmp/hi r4,r6 | ||
113 | mov.l r1,@(r0,r4) | ||
114 | bt .copy | ||
115 | |||
116 | mov.l @r5+,r0 /* start address from image */ | ||
117 | jmp @r0 | ||
118 | mov.l @r5+,r15 /* stack pointer from image */ | ||
119 | |||
120 | .end: | ||
121 | .size _descramble,.end-_descramble | ||
diff --git a/firmware/target/sh/archos/fm_v2/adc-target.h b/firmware/target/sh/archos/fm_v2/adc-target.h deleted file mode 100644 index 0070828cf3..0000000000 --- a/firmware/target/sh/archos/fm_v2/adc-target.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef _ADC_TARGET_H_ | ||
22 | #define _ADC_TARGET_H_ | ||
23 | |||
24 | #define NUM_ADC_CHANNELS 8 | ||
25 | |||
26 | #define ADC_BATTERY 0 /* Battery voltage always reads 0x3FF due to | ||
27 | silly scaling */ | ||
28 | #define ADC_CHARGE_REGULATOR 0 /* Uh, we read the battery voltage? */ | ||
29 | #define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */ | ||
30 | #define ADC_BUTTON_OFF 2 /* the off button, high value if pressed */ | ||
31 | #define ADC_BUTTON_ON 3 /* the on button, low value if pressed */ | ||
32 | #define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different | ||
33 | voltages for different keys */ | ||
34 | #define ADC_BUTTON_ROW2 5 /* Used for scanning the keys, different | ||
35 | voltages for different keys */ | ||
36 | #define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */ | ||
37 | #define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */ | ||
38 | |||
39 | #define EXT_SCALE_FACTOR 14800 | ||
40 | |||
41 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/fm_v2/backlight-target.h b/firmware/target/sh/archos/fm_v2/backlight-target.h deleted file mode 100644 index c3dd395eca..0000000000 --- a/firmware/target/sh/archos/fm_v2/backlight-target.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef BACKLIGHT_TARGET_H | ||
22 | #define BACKLIGHT_TARGET_H | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "rtc.h" | ||
26 | |||
27 | #define backlight_hw_init() true | ||
28 | |||
29 | static inline void backlight_hw_on(void) | ||
30 | { | ||
31 | rtc_write(0x13, 0x10); /* 32 kHz square wave */ | ||
32 | rtc_write(0x0a, rtc_read(0x0a) | 0x40); /* Enable square wave */ | ||
33 | } | ||
34 | |||
35 | static inline void backlight_hw_off(void) | ||
36 | { | ||
37 | /* While on, backlight is flashing at 32 kHz. If the square wave output | ||
38 | is disabled while the backlight is lit, it will become constantly lit, | ||
39 | (brighter) and slowly fade. This resets the square wave counter and | ||
40 | results in the unlit state */ | ||
41 | unsigned char rtc_0a = rtc_read(0x0a) & ~0x40; | ||
42 | rtc_write(0x0a, rtc_0a); /* Disable square wave */ | ||
43 | rtc_write(0x13, 0xF0); /* 1 Hz square wave */ | ||
44 | rtc_write(0x0a, rtc_0a | 0x40); /* Enable square wave */ | ||
45 | |||
46 | /* When the square wave output is disabled in the unlit state, | ||
47 | the backlight stays off */ | ||
48 | rtc_write(0x0a, rtc_0a); | ||
49 | } | ||
50 | |||
51 | #endif | ||
diff --git a/firmware/target/sh/archos/fm_v2/button-fm_v2.c b/firmware/target/sh/archos/fm_v2/button-fm_v2.c deleted file mode 100644 index 458917d2d5..0000000000 --- a/firmware/target/sh/archos/fm_v2/button-fm_v2.c +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include "button.h" | ||
25 | #include "backlight.h" | ||
26 | #include "adc.h" | ||
27 | |||
28 | /* | ||
29 | Recorder FM/V2 hardware button hookup | ||
30 | ===================================== | ||
31 | |||
32 | F1, F2, F3, UP: connected to AN4 through a resistor network | ||
33 | DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5 | ||
34 | |||
35 | The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed | ||
36 | FM/V2 has PLAY and RIGHT switched compared to plain recorder | ||
37 | |||
38 | ON: AN3, low active | ||
39 | OFF: AN2, high active | ||
40 | */ | ||
41 | |||
42 | void button_init_device(void) | ||
43 | { | ||
44 | /* Set PB4 and PB8 as input pins */ | ||
45 | PBCR1 &= 0xfffc; /* PB8MD = 00 */ | ||
46 | PBCR2 &= 0xfcff; /* PB4MD = 00 */ | ||
47 | PBIOR &= ~0x0110; /* Inputs */ | ||
48 | } | ||
49 | |||
50 | int button_read_device(void) | ||
51 | { | ||
52 | int btn = BUTTON_NONE; | ||
53 | int data; | ||
54 | |||
55 | /* check F1..F3 and UP */ | ||
56 | data = adc_read(ADC_BUTTON_ROW1); | ||
57 | if (data >= 150) | ||
58 | { | ||
59 | if (data >= 545) | ||
60 | if (data >= 700) | ||
61 | btn = BUTTON_F3; | ||
62 | else | ||
63 | btn = BUTTON_UP; | ||
64 | else | ||
65 | if (data >= 385) | ||
66 | btn = BUTTON_F2; | ||
67 | else | ||
68 | btn = BUTTON_F1; | ||
69 | } | ||
70 | |||
71 | /* Some units have mushy keypads, so pressing UP also activates | ||
72 | the Left/Right buttons. Let's combat that by skipping the AN5 | ||
73 | checks when UP is pressed. */ | ||
74 | if(!(btn & BUTTON_UP)) | ||
75 | { | ||
76 | /* check DOWN, PLAY, LEFT, RIGHT */ | ||
77 | data = adc_read(ADC_BUTTON_ROW2); | ||
78 | if (data >= 150) | ||
79 | { | ||
80 | if (data >= 545) | ||
81 | if (data >= 700) | ||
82 | btn |= BUTTON_DOWN; | ||
83 | else | ||
84 | btn |= BUTTON_RIGHT; | ||
85 | else | ||
86 | if (data >= 385) | ||
87 | btn |= BUTTON_LEFT; | ||
88 | else | ||
89 | btn |= BUTTON_PLAY; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if ( adc_read(ADC_BUTTON_ON) < 512 ) | ||
94 | btn |= BUTTON_ON; | ||
95 | if ( adc_read(ADC_BUTTON_OFF) > 512 ) | ||
96 | btn |= BUTTON_OFF; | ||
97 | |||
98 | return btn; | ||
99 | } | ||
diff --git a/firmware/target/sh/archos/fm_v2/button-target.h b/firmware/target/sh/archos/fm_v2/button-target.h deleted file mode 100644 index 47eb48c32d..0000000000 --- a/firmware/target/sh/archos/fm_v2/button-target.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef _BUTTON_TARGET_H_ | ||
23 | #define _BUTTON_TARGET_H_ | ||
24 | |||
25 | /* Main unit's buttons */ | ||
26 | #define BUTTON_ON 0x00000001 | ||
27 | #define BUTTON_OFF 0x00000002 | ||
28 | |||
29 | #define BUTTON_LEFT 0x00000004 | ||
30 | #define BUTTON_RIGHT 0x00000008 | ||
31 | #define BUTTON_UP 0x00000010 | ||
32 | #define BUTTON_DOWN 0x00000020 | ||
33 | |||
34 | #define BUTTON_PLAY 0x00000040 | ||
35 | |||
36 | #define BUTTON_F1 0x00000080 | ||
37 | #define BUTTON_F2 0x00000100 | ||
38 | #define BUTTON_F3 0x00000200 | ||
39 | |||
40 | #define BUTTON_MAIN (BUTTON_ON|BUTTON_OFF|BUTTON_LEFT|BUTTON_RIGHT\ | ||
41 | |BUTTON_UP|BUTTON_DOWN|BUTTON_PLAY\ | ||
42 | |BUTTON_F1|BUTTON_F2|BUTTON_F3) | ||
43 | |||
44 | #define POWEROFF_BUTTON BUTTON_OFF | ||
45 | #define POWEROFF_COUNT 10 | ||
46 | |||
47 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/fm_v2/power-fm_v2.c b/firmware/target/sh/archos/fm_v2/power-fm_v2.c deleted file mode 100644 index ce1ef19970..0000000000 --- a/firmware/target/sh/archos/fm_v2/power-fm_v2.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include <stdbool.h> | ||
24 | #include "adc.h" | ||
25 | #include "kernel.h" | ||
26 | #include "system.h" | ||
27 | #include "power.h" | ||
28 | #include "usb.h" | ||
29 | |||
30 | #if CONFIG_TUNER | ||
31 | bool tuner_power(bool status) | ||
32 | { | ||
33 | (void)status; | ||
34 | return true; | ||
35 | } | ||
36 | |||
37 | #endif /* #if CONFIG_TUNER */ | ||
38 | |||
39 | void power_init(void) | ||
40 | { | ||
41 | PBCR2 &= ~0x0c00; /* GPIO for PB5 */ | ||
42 | or_b(0x20, &PBIORL); | ||
43 | or_b(0x20, &PBDRL); /* hold power */ | ||
44 | } | ||
45 | |||
46 | unsigned int power_input_status(void) | ||
47 | { | ||
48 | unsigned int status = POWER_INPUT_NONE; | ||
49 | |||
50 | /* FM or V2 can also charge from the USB port */ | ||
51 | if (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF) | ||
52 | status = POWER_INPUT_MAIN_CHARGER; | ||
53 | |||
54 | #ifdef HAVE_USB_POWER | ||
55 | if (usb_detect() == USB_INSERTED) | ||
56 | status |= POWER_INPUT_USB_CHARGER; | ||
57 | #endif | ||
58 | |||
59 | return status; | ||
60 | } | ||
61 | |||
62 | /* Returns true if the unit is charging the batteries. */ | ||
63 | bool charging_state(void) | ||
64 | { | ||
65 | /* We use the information from the ADC_EXT_POWER ADC channel, which | ||
66 | tells us the charging current from the LTC1734. When DC is | ||
67 | connected (either via the external adapter, or via USB), we try | ||
68 | to determine if it is actively charging or only maintaining the | ||
69 | charge. My tests show that ADC readings below about 0x80 means | ||
70 | that the LTC1734 is only maintaining the charge. */ | ||
71 | return adc_read(ADC_EXT_POWER) >= 0x80; | ||
72 | } | ||
73 | |||
74 | void ide_power_enable(bool on) | ||
75 | { | ||
76 | bool touched = false; | ||
77 | |||
78 | if(on) | ||
79 | { | ||
80 | or_b(0x20, &PADRL); | ||
81 | touched = true; | ||
82 | } | ||
83 | #ifdef HAVE_ATA_POWER_OFF | ||
84 | if(!on) | ||
85 | { | ||
86 | and_b(~0x20, &PADRL); | ||
87 | touched = true; | ||
88 | } | ||
89 | #endif /* HAVE_ATA_POWER_OFF */ | ||
90 | |||
91 | /* late port preparation, else problems with read/modify/write | ||
92 | of other bits on same port, while input and floating high */ | ||
93 | if (touched) | ||
94 | { | ||
95 | or_b(0x20, &PAIORL); /* PA5 is an output */ | ||
96 | PACR2 &= 0xFBFF; /* GPIO for PA5 */ | ||
97 | } | ||
98 | } | ||
99 | |||
100 | |||
101 | bool ide_powered(void) | ||
102 | { | ||
103 | if ((PACR2 & 0x0400) || !(PAIORL & 0x20)) /* not configured for output */ | ||
104 | return true; /* would be floating high, disk on */ | ||
105 | else | ||
106 | return (PADRL & 0x20) != 0; | ||
107 | } | ||
108 | |||
109 | void power_off(void) | ||
110 | { | ||
111 | disable_irq(); | ||
112 | and_b(~0x20, &PBDRL); | ||
113 | or_b(0x20, &PBIORL); | ||
114 | while(1); | ||
115 | } | ||
diff --git a/firmware/target/sh/archos/fm_v2/powermgmt-fm_v2.c b/firmware/target/sh/archos/fm_v2/powermgmt-fm_v2.c deleted file mode 100644 index 5dd7f26d2f..0000000000 --- a/firmware/target/sh/archos/fm_v2/powermgmt-fm_v2.c +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "adc.h" | ||
25 | #include "powermgmt.h" | ||
26 | |||
27 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
28 | { | ||
29 | 2800 | ||
30 | }; | ||
31 | |||
32 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
33 | { | ||
34 | 2580 | ||
35 | }; | ||
36 | |||
37 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
38 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
39 | { | ||
40 | /* measured values */ | ||
41 | { 2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000 } | ||
42 | }; | ||
43 | |||
44 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
45 | const unsigned short percent_to_volt_charge[11] = | ||
46 | { | ||
47 | /* TODO: This is identical to the discharge curve. | ||
48 | * Calibrate charging curve using a battery_bench log. */ | ||
49 | 2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000 | ||
50 | }; | ||
51 | |||
52 | /* Battery scale factor (guessed, seems to be 1,25 * value from recorder) */ | ||
53 | #define BATTERY_SCALE_FACTOR 8275 | ||
54 | /* full-scale ADC readout (2^10) in millivolt */ | ||
55 | |||
56 | /* Returns battery voltage from ADC [millivolts] */ | ||
57 | int _battery_voltage(void) | ||
58 | { | ||
59 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | ||
60 | } | ||
diff --git a/firmware/target/sh/archos/fm_v2/usb-fm_v2.c b/firmware/target/sh/archos/fm_v2/usb-fm_v2.c deleted file mode 100644 index 5b11d778b6..0000000000 --- a/firmware/target/sh/archos/fm_v2/usb-fm_v2.c +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include <stdbool.h> | ||
23 | #include "adc.h" | ||
24 | #include "cpu.h" | ||
25 | #include "hwcompat.h" | ||
26 | #include "system.h" | ||
27 | #include "usb.h" | ||
28 | |||
29 | int usb_detect(void) | ||
30 | { | ||
31 | return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED; | ||
32 | } | ||
33 | |||
34 | void usb_enable(bool on) | ||
35 | { | ||
36 | if(HW_MASK & USB_ACTIVE_HIGH) | ||
37 | on = !on; | ||
38 | |||
39 | if(on) | ||
40 | and_b(~0x04, &PADRH); /* enable USB */ | ||
41 | else | ||
42 | or_b(0x04, &PADRH); | ||
43 | } | ||
44 | |||
45 | void usb_init_device(void) | ||
46 | { | ||
47 | usb_enable(false); | ||
48 | or_b(0x04, &PAIORH); | ||
49 | } | ||
diff --git a/firmware/target/sh/archos/i2c-archos.c b/firmware/target/sh/archos/i2c-archos.c deleted file mode 100644 index 5b415926f2..0000000000 --- a/firmware/target/sh/archos/i2c-archos.c +++ /dev/null | |||
@@ -1,254 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "lcd.h" | ||
22 | #include "cpu.h" | ||
23 | #include "kernel.h" | ||
24 | #include "thread.h" | ||
25 | #include "debug.h" | ||
26 | #include "system.h" | ||
27 | #include "i2c.h" | ||
28 | |||
29 | /* cute little functions, atomic read-modify-write */ | ||
30 | |||
31 | /* SDA is PB7 */ | ||
32 | #define SDA_LO and_b(~0x80, &PBDRL) | ||
33 | #define SDA_HI or_b(0x80, &PBDRL) | ||
34 | #define SDA_INPUT and_b(~0x80, &PBIORL) | ||
35 | #define SDA_OUTPUT or_b(0x80, &PBIORL) | ||
36 | #define SDA (PBDRL & 0x80) | ||
37 | |||
38 | #if CONFIG_I2C == I2C_ONDIO | ||
39 | /* Ondio pinout, SCL moved to PB6 */ | ||
40 | #define SCL_INPUT and_b(~0x40, &PBIORL) | ||
41 | #define SCL_OUTPUT or_b(0x40, &PBIORL) | ||
42 | #define SCL_LO and_b(~0x40, &PBDRL) | ||
43 | #define SCL_HI or_b(0x40, &PBDRL) | ||
44 | #define SCL (PBDRL & 0x40) | ||
45 | #else | ||
46 | /* "classic" pinout, SCL is PB13 */ | ||
47 | #define SCL_INPUT and_b(~0x20, &PBIORH) | ||
48 | #define SCL_OUTPUT or_b(0x20, &PBIORH) | ||
49 | #define SCL_LO and_b(~0x20, &PBDRH) | ||
50 | #define SCL_HI or_b(0x20, &PBDRH) | ||
51 | #define SCL (PBDRH & 0x20) | ||
52 | #endif | ||
53 | |||
54 | /* arbitrary delay loop */ | ||
55 | #define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0) | ||
56 | |||
57 | static struct mutex i2c_mtx SHAREDBSS_ATTR; | ||
58 | |||
59 | void i2c_begin(void) | ||
60 | { | ||
61 | mutex_lock(&i2c_mtx); | ||
62 | } | ||
63 | |||
64 | void i2c_end(void) | ||
65 | { | ||
66 | mutex_unlock(&i2c_mtx); | ||
67 | } | ||
68 | |||
69 | void i2c_start(void) | ||
70 | { | ||
71 | SDA_OUTPUT; | ||
72 | SDA_HI; | ||
73 | SCL_HI; | ||
74 | SDA_LO; | ||
75 | DELAY; | ||
76 | SCL_LO; | ||
77 | } | ||
78 | |||
79 | void i2c_stop(void) | ||
80 | { | ||
81 | SDA_LO; | ||
82 | SCL_HI; | ||
83 | DELAY; | ||
84 | SDA_HI; | ||
85 | } | ||
86 | |||
87 | void i2c_init(void) | ||
88 | { | ||
89 | int i; | ||
90 | |||
91 | mutex_init(&i2c_mtx); | ||
92 | |||
93 | #if CONFIG_I2C == I2C_ONDIO | ||
94 | /* make PB6 & PB7 general I/O */ | ||
95 | PBCR2 &= ~0xf000; | ||
96 | #else /* not Ondio */ | ||
97 | /* make PB7 & PB13 general I/O */ | ||
98 | PBCR1 &= ~0x0c00; /* PB13 */ | ||
99 | PBCR2 &= ~0xc000; /* PB7 */ | ||
100 | #endif | ||
101 | |||
102 | SCL_OUTPUT; | ||
103 | SDA_OUTPUT; | ||
104 | SDA_HI; | ||
105 | SCL_LO; | ||
106 | for (i=0;i<3;i++) | ||
107 | i2c_stop(); | ||
108 | } | ||
109 | |||
110 | void i2c_ack(int bit) | ||
111 | { | ||
112 | /* Here's the deal. The MAS is slow, and sometimes needs to wait | ||
113 | before it can receive the acknowledge. Therefore it forces the clock | ||
114 | low until it is ready. We need to poll the clock line until it goes | ||
115 | high before we release the ack. */ | ||
116 | |||
117 | SCL_LO; /* Set the clock low */ | ||
118 | if ( bit ) | ||
119 | { | ||
120 | SDA_HI; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | SDA_LO; | ||
125 | } | ||
126 | |||
127 | SCL_INPUT; /* Set the clock to input */ | ||
128 | while(!SCL) /* and wait for the MAS to release it */ | ||
129 | sleep(0); | ||
130 | |||
131 | DELAY; | ||
132 | SCL_OUTPUT; | ||
133 | SCL_LO; | ||
134 | } | ||
135 | |||
136 | int i2c_getack(void) | ||
137 | { | ||
138 | int ret = 1; | ||
139 | |||
140 | /* Here's the deal. The MAS is slow, and sometimes needs to wait | ||
141 | before it can send the acknowledge. Therefore it forces the clock | ||
142 | low until it is ready. We need to poll the clock line until it goes | ||
143 | high before we read the ack. */ | ||
144 | |||
145 | #ifdef HAVE_I2C_LOW_FIRST | ||
146 | SDA_LO; /* First, discharge the data line */ | ||
147 | #endif | ||
148 | SDA_INPUT; /* And set to input */ | ||
149 | SCL_INPUT; /* Set the clock to input */ | ||
150 | while(!SCL) /* and wait for the MAS to release it */ | ||
151 | sleep(0); | ||
152 | |||
153 | if (SDA) | ||
154 | /* ack failed */ | ||
155 | ret = 0; | ||
156 | |||
157 | SCL_OUTPUT; | ||
158 | SCL_LO; | ||
159 | SDA_HI; | ||
160 | SDA_OUTPUT; | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | void i2c_outb(unsigned char byte) | ||
165 | { | ||
166 | int i; | ||
167 | |||
168 | /* clock out each bit, MSB first */ | ||
169 | for ( i=0x80; i; i>>=1 ) { | ||
170 | if ( i & byte ) | ||
171 | { | ||
172 | SDA_HI; | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | SDA_LO; | ||
177 | } | ||
178 | SCL_HI; | ||
179 | SCL_LO; | ||
180 | } | ||
181 | |||
182 | SDA_HI; | ||
183 | } | ||
184 | |||
185 | unsigned char i2c_inb(int ack) | ||
186 | { | ||
187 | int i; | ||
188 | unsigned char byte = 0; | ||
189 | |||
190 | /* clock in each bit, MSB first */ | ||
191 | for ( i=0x80; i; i>>=1 ) { | ||
192 | #ifdef HAVE_I2C_LOW_FIRST | ||
193 | /* Tricky business. Here we discharge the data line by driving it low | ||
194 | and then set it to input to see if it stays low or goes high */ | ||
195 | SDA_LO; /* First, discharge the data line */ | ||
196 | #endif | ||
197 | SDA_INPUT; /* And set to input */ | ||
198 | SCL_HI; | ||
199 | if ( SDA ) | ||
200 | byte |= i; | ||
201 | SCL_LO; | ||
202 | SDA_OUTPUT; | ||
203 | } | ||
204 | |||
205 | i2c_ack(ack); | ||
206 | |||
207 | return byte; | ||
208 | } | ||
209 | |||
210 | int i2c_write(int address, const unsigned char* buf, int count ) | ||
211 | { | ||
212 | int i,x=0; | ||
213 | |||
214 | i2c_start(); | ||
215 | i2c_outb(address & 0xfe); | ||
216 | if (i2c_getack()) | ||
217 | { | ||
218 | for (i=0; i<count; i++) | ||
219 | { | ||
220 | i2c_outb(buf[i]); | ||
221 | if (!i2c_getack()) | ||
222 | { | ||
223 | x=-2; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | debugf("i2c_write() - no ack\n"); | ||
231 | x=-1; | ||
232 | } | ||
233 | i2c_stop(); | ||
234 | return x; | ||
235 | } | ||
236 | |||
237 | #if 0 /* Currently unused, left for reference and future use */ | ||
238 | int i2c_read(int address, unsigned char* buf, int count ) | ||
239 | { | ||
240 | int i,x=0; | ||
241 | |||
242 | i2c_start(); | ||
243 | i2c_outb(address | 1); | ||
244 | if (i2c_getack()) { | ||
245 | for (i=0; i<count; i++) { | ||
246 | buf[i] = i2c_inb(0); | ||
247 | } | ||
248 | } | ||
249 | else | ||
250 | x=-1; | ||
251 | i2c_stop(); | ||
252 | return x; | ||
253 | } | ||
254 | #endif | ||
diff --git a/firmware/target/sh/archos/lcd-archos-bitmap.c b/firmware/target/sh/archos/lcd-archos-bitmap.c deleted file mode 100644 index f23289053d..0000000000 --- a/firmware/target/sh/archos/lcd-archos-bitmap.c +++ /dev/null | |||
@@ -1,224 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Alan Korr | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | |||
23 | #include "hwcompat.h" | ||
24 | #include "kernel.h" | ||
25 | #include "lcd.h" | ||
26 | #include "system.h" | ||
27 | |||
28 | /*** definitions ***/ | ||
29 | |||
30 | #define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00) | ||
31 | #define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10) | ||
32 | #define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20) | ||
33 | #define LCD_SET_POWER_CONTROL_REGISTER ((char)0x28) | ||
34 | #define LCD_SET_DISPLAY_START_LINE ((char)0x40) | ||
35 | #define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81) | ||
36 | #define LCD_SET_SEGMENT_REMAP ((char)0xA0) | ||
37 | #define LCD_SET_LCD_BIAS ((char)0xA2) | ||
38 | #define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4) | ||
39 | #define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5) | ||
40 | #define LCD_SET_NORMAL_DISPLAY ((char)0xA6) | ||
41 | #define LCD_SET_REVERSE_DISPLAY ((char)0xA7) | ||
42 | #define LCD_SET_MULTIPLEX_RATIO ((char)0xA8) | ||
43 | #define LCD_SET_BIAS_TC_OSC ((char)0xA9) | ||
44 | #define LCD_SET_1OVER4_BIAS_RATIO ((char)0xAA) | ||
45 | #define LCD_SET_INDICATOR_OFF ((char)0xAC) | ||
46 | #define LCD_SET_INDICATOR_ON ((char)0xAD) | ||
47 | #define LCD_SET_DISPLAY_OFF ((char)0xAE) | ||
48 | #define LCD_SET_DISPLAY_ON ((char)0xAF) | ||
49 | #define LCD_SET_PAGE_ADDRESS ((char)0xB0) | ||
50 | #define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0) | ||
51 | #define LCD_SET_TOTAL_FRAME_PHASES ((char)0xD2) | ||
52 | #define LCD_SET_DISPLAY_OFFSET ((char)0xD3) | ||
53 | #define LCD_SET_READ_MODIFY_WRITE_MODE ((char)0xE0) | ||
54 | #define LCD_SOFTWARE_RESET ((char)0xE2) | ||
55 | #define LCD_NOP ((char)0xE3) | ||
56 | #define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE ((char)0xEE) | ||
57 | |||
58 | /* LCD command codes */ | ||
59 | #define LCD_CNTL_RESET 0xe2 /* Software reset */ | ||
60 | #define LCD_CNTL_POWER 0x2f /* Power control */ | ||
61 | #define LCD_CNTL_CONTRAST 0x81 /* Contrast */ | ||
62 | #define LCD_CNTL_OUTSCAN 0xc8 /* Output scan direction */ | ||
63 | #define LCD_CNTL_SEGREMAP 0xa1 /* Segment remap */ | ||
64 | #define LCD_CNTL_DISPON 0xaf /* Display on */ | ||
65 | |||
66 | #define LCD_CNTL_PAGE 0xb0 /* Page address */ | ||
67 | #define LCD_CNTL_HIGHCOL 0x10 /* Upper column address */ | ||
68 | #define LCD_CNTL_LOWCOL 0x00 /* Lower column address */ | ||
69 | |||
70 | /** globals **/ | ||
71 | |||
72 | static int xoffset; /* needed for flip */ | ||
73 | |||
74 | /*** hardware configuration ***/ | ||
75 | |||
76 | int lcd_default_contrast(void) | ||
77 | { | ||
78 | return (HW_MASK & LCD_CONTRAST_BIAS) ? 31 : 49; | ||
79 | } | ||
80 | |||
81 | void lcd_set_contrast(int val) | ||
82 | { | ||
83 | lcd_write_command(LCD_CNTL_CONTRAST); | ||
84 | lcd_write_command(val); | ||
85 | } | ||
86 | |||
87 | void lcd_set_invert_display(bool yesno) | ||
88 | { | ||
89 | if (yesno) | ||
90 | lcd_write_command(LCD_SET_REVERSE_DISPLAY); | ||
91 | else | ||
92 | lcd_write_command(LCD_SET_NORMAL_DISPLAY); | ||
93 | } | ||
94 | |||
95 | /* turn the display upside down (call lcd_update() afterwards) */ | ||
96 | void lcd_set_flip(bool yesno) | ||
97 | { | ||
98 | #ifdef HAVE_DISPLAY_FLIPPED | ||
99 | if (!yesno) | ||
100 | #else | ||
101 | if (yesno) | ||
102 | #endif | ||
103 | { | ||
104 | lcd_write_command(LCD_SET_SEGMENT_REMAP); | ||
105 | lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION); | ||
106 | xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */ | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01); | ||
111 | lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08); | ||
112 | xoffset = 0; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void lcd_init_device(void) | ||
117 | { | ||
118 | /* Initialize PB0-3 as output pins */ | ||
119 | PBCR2 &= 0xff00; /* MD = 00 */ | ||
120 | PBIOR |= 0x000f; /* IOR = 1 */ | ||
121 | |||
122 | /* inits like the original firmware */ | ||
123 | lcd_write_command(LCD_SOFTWARE_RESET); | ||
124 | lcd_write_command(LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 4); | ||
125 | lcd_write_command(LCD_SET_1OVER4_BIAS_RATIO + 0); /* force 1/4 bias: 0 */ | ||
126 | lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7); | ||
127 | /* power control register: op-amp=1, regulator=1, booster=1 */ | ||
128 | lcd_write_command(LCD_SET_DISPLAY_ON); | ||
129 | lcd_write_command(LCD_SET_NORMAL_DISPLAY); | ||
130 | lcd_set_flip(false); | ||
131 | lcd_write_command(LCD_SET_DISPLAY_START_LINE + 0); | ||
132 | lcd_set_contrast(lcd_default_contrast()); | ||
133 | lcd_write_command(LCD_SET_PAGE_ADDRESS); | ||
134 | lcd_write_command(LCD_SET_LOWER_COLUMN_ADDRESS + 0); | ||
135 | lcd_write_command(LCD_SET_HIGHER_COLUMN_ADDRESS + 0); | ||
136 | |||
137 | lcd_clear_display(); | ||
138 | lcd_update(); | ||
139 | } | ||
140 | |||
141 | /*** Update functions ***/ | ||
142 | |||
143 | /* Performance function that works with an external buffer | ||
144 | note that by and bheight are in 8-pixel units! */ | ||
145 | void lcd_blit_mono(const unsigned char *data, int x, int by, int width, | ||
146 | int bheight, int stride) | ||
147 | { | ||
148 | /* Copy display bitmap to hardware */ | ||
149 | while (bheight--) | ||
150 | { | ||
151 | lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); | ||
152 | lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf)); | ||
153 | lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf)); | ||
154 | |||
155 | lcd_write_data(data, width); | ||
156 | data += stride; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /* Helper function for lcd_grey_phase_blit(). */ | ||
161 | void lcd_grey_data(unsigned char *values, unsigned char *phases, int count); | ||
162 | |||
163 | /* Performance function that works with an external buffer | ||
164 | note that by and bheight are in 8-pixel units! */ | ||
165 | void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases, | ||
166 | int x, int by, int width, int bheight, int stride) | ||
167 | { | ||
168 | stride <<= 3; /* 8 pixels per block */ | ||
169 | while (bheight--) | ||
170 | { | ||
171 | lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf)); | ||
172 | lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf)); | ||
173 | lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf)); | ||
174 | |||
175 | lcd_grey_data(values, phases, width); | ||
176 | values += stride; | ||
177 | phases += stride; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | |||
182 | /* Update the display. | ||
183 | This must be called after all other LCD functions that change the display. */ | ||
184 | void lcd_update(void) | ||
185 | { | ||
186 | int y; | ||
187 | |||
188 | /* Copy display bitmap to hardware */ | ||
189 | for (y = 0; y < LCD_FBHEIGHT; y++) | ||
190 | { | ||
191 | lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); | ||
192 | lcd_write_command (LCD_CNTL_HIGHCOL | ((xoffset >> 4) & 0xf)); | ||
193 | lcd_write_command (LCD_CNTL_LOWCOL | (xoffset & 0xf)); | ||
194 | |||
195 | lcd_write_data (FBADDR(0, y), LCD_WIDTH); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* Update a fraction of the display. */ | ||
200 | void lcd_update_rect(int x, int y, int width, int height) | ||
201 | { | ||
202 | int ymax; | ||
203 | |||
204 | /* The Y coordinates have to work on even 8 pixel rows */ | ||
205 | ymax = (y + height-1) >> 3; | ||
206 | y >>= 3; | ||
207 | |||
208 | if(x + width > LCD_WIDTH) | ||
209 | width = LCD_WIDTH - x; | ||
210 | if (width <= 0) | ||
211 | return; /* nothing left to do, 0 is harmful to lcd_write_data() */ | ||
212 | if(ymax >= LCD_FBHEIGHT) | ||
213 | ymax = LCD_FBHEIGHT-1; | ||
214 | |||
215 | /* Copy specified rectange bitmap to hardware */ | ||
216 | for (; y <= ymax; y++) | ||
217 | { | ||
218 | lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); | ||
219 | lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset) >> 4) & 0xf)); | ||
220 | lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf)); | ||
221 | |||
222 | lcd_write_data (FBADDR(x,y), width); | ||
223 | } | ||
224 | } | ||
diff --git a/firmware/target/sh/archos/lcd-as-archos-bitmap.S b/firmware/target/sh/archos/lcd-as-archos-bitmap.S deleted file mode 100644 index 0396483737..0000000000 --- a/firmware/target/sh/archos/lcd-as-archos-bitmap.S +++ /dev/null | |||
@@ -1,354 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 by Jens Arnold | ||
11 | * Based on the work of Alan Korr and Jörg Hohensohn | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "cpu.h" | ||
25 | |||
26 | #define LCDR (PBDR_ADDR+1) | ||
27 | |||
28 | #define LCD_SD 1 /* PB0 = 1 --- 0001 */ | ||
29 | #define LCD_SC 2 /* PB1 = 1 --- 0010 */ | ||
30 | #define LCD_DS 4 /* PB2 = 1 --- 0100 */ | ||
31 | #define LCD_CS 8 /* PB3 = 1 --- 1000 */ | ||
32 | |||
33 | /* | ||
34 | * About /CS,DS,SC,SD | ||
35 | * ------------------ | ||
36 | * | ||
37 | * LCD on JBP and JBR uses a SPI protocol to receive orders (SDA and SCK lines) | ||
38 | * | ||
39 | * - /CS -> Chip Selection line : | ||
40 | * 0 : LCD chipset is activated. | ||
41 | * - DS -> Data Selection line, latched at the rising edge | ||
42 | * of the 8th serial clock (*) : | ||
43 | * 0 : instruction register, | ||
44 | * 1 : data register; | ||
45 | * - SC -> Serial Clock line (SDA). | ||
46 | * - SD -> Serial Data line (SCK), latched at the rising edge | ||
47 | * of each serial clock (*). | ||
48 | * | ||
49 | * _ _ | ||
50 | * /CS \ / | ||
51 | * \______________________________________________________/ | ||
52 | * _____ ____ ____ ____ ____ ____ ____ ____ ____ _____ | ||
53 | * SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/ | ||
54 | * _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____ | ||
55 | * | ||
56 | * _____ _ _ _ _ _ _ _ ________ | ||
57 | * SC \ * \ * \ * \ * \ * \ * \ * \ * | ||
58 | * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ | ||
59 | * _ _________________________________________________________ | ||
60 | * DS \/ | ||
61 | * _/\_________________________________________________________ | ||
62 | * | ||
63 | */ | ||
64 | |||
65 | .section .icode,"ax",@progbits | ||
66 | |||
67 | .align 2 | ||
68 | .global _lcd_write_command | ||
69 | .type _lcd_write_command,@function | ||
70 | |||
71 | /* Write a command byte to the lcd controller | ||
72 | * | ||
73 | * Arguments: | ||
74 | * r4 - data byte (int) | ||
75 | * | ||
76 | * Register usage: | ||
77 | * r0 - scratch | ||
78 | * r1 - data byte (copied) | ||
79 | * r2 - precalculated port value (CS, DS and SC low, SD high), | ||
80 | * negated (neg)! | ||
81 | * r3 - lcd port address | ||
82 | * r5 - 1 (byte count for reuse of the loop in _lcd_write_data) | ||
83 | */ | ||
84 | |||
85 | _lcd_write_command: | ||
86 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
87 | mov r4, r1 /* copy data byte to r1 */ | ||
88 | |||
89 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
90 | * If so, we must disable the interrupt here. */ | ||
91 | |||
92 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
93 | mov #0, r5 /* fake end address - stop after first iteration */ | ||
94 | or #(LCD_SD), r0 /* r0 |= LCD_SD */ | ||
95 | and #(~(LCD_CS|LCD_DS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ | ||
96 | |||
97 | bra .single_transfer /* jump into the transfer loop */ | ||
98 | neg r0, r2 /* r2 = 0 - r0 */ | ||
99 | |||
100 | |||
101 | .align 2 | ||
102 | .global _lcd_write_data | ||
103 | .type _lcd_write_data,@function | ||
104 | |||
105 | /* A high performance function to write data to the display, | ||
106 | * one or multiple bytes. | ||
107 | * | ||
108 | * Arguments: | ||
109 | * r4 - data address | ||
110 | * r5 - byte count | ||
111 | * | ||
112 | * Register usage: | ||
113 | * r0 - scratch | ||
114 | * r1 - current data byte | ||
115 | * r2 - precalculated port value (CS and SC low, DS and SD high), | ||
116 | * negated (neg)! | ||
117 | * r3 - lcd port address | ||
118 | */ | ||
119 | |||
120 | _lcd_write_data: | ||
121 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
122 | add r4, r5 /* end address */ | ||
123 | |||
124 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
125 | * If so, we must disable the interrupt here. If disabling interrupts | ||
126 | * for a long time (~9200 clks = ~830 µs for transferring 112 bytes on | ||
127 | * recorders)is undesirable, the loop has to be rewritten to | ||
128 | * disable/precalculate/transfer/enable for each iteration. However, | ||
129 | * this would significantly decrease performance. */ | ||
130 | |||
131 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
132 | or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */ | ||
133 | and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */ | ||
134 | neg r0, r2 /* r2 = 0 - r0 */ | ||
135 | |||
136 | /* loop exploits that SD is on bit 0 for recorders and Ondios */ | ||
137 | |||
138 | .align 2 | ||
139 | .multi_transfer: | ||
140 | mov.b @r4+, r1 /* load data byte from memory */ | ||
141 | nop | ||
142 | |||
143 | .single_transfer: | ||
144 | shll16 r1 /* shift data to most significant byte */ | ||
145 | shll8 r1 | ||
146 | not r1, r1 /* and invert for use with negc */ | ||
147 | |||
148 | shll r1 /* shift the MSB into carry */ | ||
149 | negc r2, r0 /* carry to SD, SC low */ | ||
150 | shll r1 /* next shift here for alignment */ | ||
151 | mov.b r0, @r3 /* set data to port */ | ||
152 | or #(LCD_SC), r0 /* rise SC (independent of SD level) */ | ||
153 | mov.b r0, @r3 /* set to port */ | ||
154 | |||
155 | negc r2, r0 | ||
156 | mov.b r0, @r3 | ||
157 | or #(LCD_SC), r0 | ||
158 | mov.b r0, @r3 | ||
159 | |||
160 | shll r1 | ||
161 | negc r2, r0 | ||
162 | shll r1 | ||
163 | mov.b r0, @r3 | ||
164 | or #(LCD_SC), r0 | ||
165 | mov.b r0, @r3 | ||
166 | |||
167 | negc r2, r0 | ||
168 | mov.b r0, @r3 | ||
169 | or #(LCD_SC), r0 | ||
170 | mov.b r0, @r3 | ||
171 | |||
172 | shll r1 | ||
173 | negc r2, r0 | ||
174 | shll r1 | ||
175 | mov.b r0, @r3 | ||
176 | or #(LCD_SC), r0 | ||
177 | mov.b r0, @r3 | ||
178 | |||
179 | negc r2, r0 | ||
180 | mov.b r0, @r3 | ||
181 | or #(LCD_SC), r0 | ||
182 | mov.b r0, @r3 | ||
183 | |||
184 | shll r1 | ||
185 | negc r2, r0 | ||
186 | shll r1 | ||
187 | mov.b r0, @r3 | ||
188 | or #(LCD_SC), r0 | ||
189 | mov.b r0, @r3 | ||
190 | |||
191 | negc r2, r0 | ||
192 | mov.b r0, @r3 | ||
193 | or #(LCD_SC), r0 | ||
194 | mov.b r0, @r3 | ||
195 | |||
196 | cmp/hi r4, r5 /* some blocks left? */ | ||
197 | bt .multi_transfer | ||
198 | |||
199 | or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0 /* restore port */ | ||
200 | rts | ||
201 | mov.b r0, @r3 | ||
202 | |||
203 | /* This is the place to reenable the interrupts, if we have disabled | ||
204 | * them. See above. */ | ||
205 | |||
206 | #ifndef BOOTLOADER | ||
207 | .align 2 | ||
208 | .global _lcd_grey_data | ||
209 | .type _lcd_grey_data,@function | ||
210 | |||
211 | /* A high performance function to write grey phase data to the display, | ||
212 | * one or multiple pixels. | ||
213 | * | ||
214 | * Arguments: | ||
215 | * r4 - pixel value data address | ||
216 | * r5 - pixel phase data address | ||
217 | * r6 - pixel block count | ||
218 | * | ||
219 | * Register usage: | ||
220 | * r0 - scratch / phase signs mask | ||
221 | * r1 - scratch | ||
222 | * r2 - precalculated port value (CS and SC low, DS and SD high), | ||
223 | * negated (neg)! | ||
224 | * r3 - lcd port address | ||
225 | * r4 - current value address | ||
226 | * r5 - current phase address | ||
227 | * r6 - end address | ||
228 | * r7/r8 - current/next block of phases (alternating) | ||
229 | * r9/r10 - current blocks of values | ||
230 | * r11 - 0x00000080 \ | ||
231 | * r12 - 0x00008000 > for phase sign check | ||
232 | * r13 - 0x00800000 / | ||
233 | */ | ||
234 | |||
235 | _lcd_grey_data: | ||
236 | mov.l r8, @-r15 /* save r8 */ | ||
237 | mov.l r9, @-r15 /* save r9 */ | ||
238 | mov.l r10, @-r15 /* save r10 */ | ||
239 | shll2 r6 /* v */ | ||
240 | mov.l r11, @-r15 /* save r11 */ | ||
241 | shll r6 /* r6 *= 8; (8 pixels per block) */ | ||
242 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
243 | add r4, r6 /* end address */ | ||
244 | |||
245 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
246 | * If so, we must disable the interrupt here. If disabling interrupts | ||
247 | * for a long time is undesirable, the loop has to be rewritten to | ||
248 | * disable/precalculate/transfer/enable for each iteration. However, | ||
249 | * this would significantly decrease performance. */ | ||
250 | |||
251 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
252 | or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */ | ||
253 | mov.l r12, @-r15 /* save r12 */ | ||
254 | and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */ | ||
255 | mov.l r13, @-r15 /* save r13 */ | ||
256 | neg r0, r2 /* r2 = 0 - r0 */ | ||
257 | |||
258 | /* loop exploits that SD is on bit 0 for recorders and Ondios */ | ||
259 | |||
260 | mov.w .ptest, r11 | ||
261 | swap.b r11, r12 | ||
262 | mov.l @r5, r7 | ||
263 | swap.w r11, r13 | ||
264 | mov.l .pmask, r0 | ||
265 | |||
266 | .greyloop: | ||
267 | cmp/pz r7 | ||
268 | mov.l @r4+, r9 | ||
269 | negc r2, r1 | ||
270 | mov.b r1, @r3 | ||
271 | add #(LCD_SC), r1 | ||
272 | mov.b r1, @r3 | ||
273 | |||
274 | tst r13, r7 | ||
275 | mov.l @r4+, r10 | ||
276 | negc r2, r1 | ||
277 | mov.b r1, @r3 | ||
278 | add #(LCD_SC), r1 | ||
279 | mov.b r1, @r3 | ||
280 | |||
281 | tst r12, r7 | ||
282 | mov.l @(4,r5), r8 | ||
283 | negc r2, r1 | ||
284 | mov.b r1, @r3 | ||
285 | add #(LCD_SC), r1 | ||
286 | mov.b r1, @r3 | ||
287 | |||
288 | tst r11, r7 | ||
289 | or r0, r7 | ||
290 | negc r2, r1 | ||
291 | mov.b r1, @r3 | ||
292 | add #(LCD_SC), r1 | ||
293 | mov.b r1, @r3 | ||
294 | |||
295 | cmp/pz r8 | ||
296 | sub r9, r7 | ||
297 | negc r2, r1 | ||
298 | mov.b r1, @r3 | ||
299 | add #(LCD_SC), r1 | ||
300 | mov.b r1, @r3 | ||
301 | |||
302 | tst r13, r8 | ||
303 | mov.l r7, @r5 | ||
304 | negc r2, r1 | ||
305 | mov.b r1, @r3 | ||
306 | add #(LCD_SC), r1 | ||
307 | mov.b r1, @r3 | ||
308 | |||
309 | tst r12, r8 | ||
310 | mov.l @(8,r5), r7 | ||
311 | negc r2, r1 | ||
312 | mov.b r1, @r3 | ||
313 | add #(LCD_SC), r1 | ||
314 | mov.b r1, @r3 | ||
315 | |||
316 | tst r11, r8 | ||
317 | or r0, r8 | ||
318 | negc r2, r1 | ||
319 | mov.b r1, @r3 | ||
320 | add #(LCD_SC), r1 | ||
321 | mov.b r1, @r3 | ||
322 | |||
323 | sub r10, r8 | ||
324 | mov.l r8, @(4,r5) | ||
325 | |||
326 | add #8, r5 | ||
327 | cmp/hi r4, r6 | ||
328 | bt .greyloop | ||
329 | |||
330 | mov.l @r15+, r13 /* restore r13 */ | ||
331 | mov #(LCD_CS|LCD_DS|LCD_SD|LCD_SC), r0 | ||
332 | mov.l @r15+, r12 /* restore r12 */ | ||
333 | or r0, r1 /* restore port */ | ||
334 | mov.l @r15+, r11 /* restore r11 */ | ||
335 | mov.l @r15+, r10 /* restore r10 */ | ||
336 | mov.l @r15+, r9 /* restore r9 */ | ||
337 | mov.l @r15+, r8 /* restore r8 */ | ||
338 | rts | ||
339 | mov.b r1, @r3 | ||
340 | |||
341 | /* This is the place to reenable the interrupts, if we have disabled | ||
342 | * them. See above. */ | ||
343 | |||
344 | .ptest: | ||
345 | .short 0x0080 | ||
346 | |||
347 | .align 2 | ||
348 | .pmask: | ||
349 | .long 0x80808080 | ||
350 | #endif | ||
351 | |||
352 | .align 2 | ||
353 | .lcdr: | ||
354 | .long LCDR | ||
diff --git a/firmware/target/sh/archos/mascodec-archos.c b/firmware/target/sh/archos/mascodec-archos.c deleted file mode 100644 index faa5c7ef2b..0000000000 --- a/firmware/target/sh/archos/mascodec-archos.c +++ /dev/null | |||
@@ -1,491 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "stdbool.h" | ||
22 | #include "config.h" | ||
23 | #include "sh7034.h" | ||
24 | #include "i2c.h" | ||
25 | #include "debug.h" | ||
26 | #include "mas35xx.h" | ||
27 | #include "kernel.h" | ||
28 | #include "system.h" | ||
29 | #include "hwcompat.h" | ||
30 | |||
31 | static int mas_devread(unsigned long *dest, int len); | ||
32 | |||
33 | #if 0 /* Currently unused, left for reference and future use */ | ||
34 | int mas_default_read(unsigned short *buf) | ||
35 | { | ||
36 | unsigned char *dest = (unsigned char *)buf; | ||
37 | int ret = 0; | ||
38 | |||
39 | i2c_begin(); | ||
40 | |||
41 | i2c_start(); | ||
42 | i2c_outb(MAS_DEV_WRITE); | ||
43 | if (i2c_getack()) { | ||
44 | i2c_outb(MAS_DATA_READ); | ||
45 | if (i2c_getack()) { | ||
46 | i2c_start(); | ||
47 | i2c_outb(MAS_DEV_READ); | ||
48 | if (i2c_getack()) { | ||
49 | dest[0] = i2c_inb(0); | ||
50 | dest[1] = i2c_inb(1); | ||
51 | } | ||
52 | else | ||
53 | ret = -3; | ||
54 | } | ||
55 | else | ||
56 | ret = -2; | ||
57 | } | ||
58 | else | ||
59 | ret = -1; | ||
60 | |||
61 | i2c_stop(); | ||
62 | |||
63 | i2c_end(); | ||
64 | return ret; | ||
65 | } | ||
66 | #endif | ||
67 | |||
68 | #if CONFIG_CODEC == MAS3507D | ||
69 | int mas_run(unsigned short address) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | unsigned char buf[3]; | ||
73 | |||
74 | i2c_begin(); | ||
75 | |||
76 | buf[0] = MAS_DATA_WRITE; | ||
77 | buf[1] = address >> 8; | ||
78 | buf[2] = address & 0xff; | ||
79 | |||
80 | /* send run command */ | ||
81 | if (i2c_write(MAS_DEV_WRITE,buf,3)) | ||
82 | { | ||
83 | ret = -1; | ||
84 | } | ||
85 | |||
86 | i2c_end(); | ||
87 | return ret; | ||
88 | } | ||
89 | #endif | ||
90 | |||
91 | /* note: 'len' is number of 32-bit words, not number of bytes! */ | ||
92 | int mas_readmem(int bank, int addr, unsigned long* dest, int len) | ||
93 | { | ||
94 | int ret = 0; | ||
95 | unsigned char buf[7]; | ||
96 | |||
97 | i2c_begin(); | ||
98 | |||
99 | buf[0] = MAS_DATA_WRITE; | ||
100 | buf[1] = bank?MAS_CMD_READ_D1_MEM:MAS_CMD_READ_D0_MEM; | ||
101 | buf[2] = 0x00; | ||
102 | buf[3] = (len & 0xff00) >> 8; | ||
103 | buf[4] = len & 0xff; | ||
104 | buf[5] = (addr & 0xff00) >> 8; | ||
105 | buf[6] = addr & 0xff; | ||
106 | |||
107 | /* send read command */ | ||
108 | if (i2c_write(MAS_DEV_WRITE,buf,7)) | ||
109 | { | ||
110 | ret = -1; | ||
111 | } | ||
112 | |||
113 | ret = mas_devread(dest, len); | ||
114 | |||
115 | i2c_end(); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | /* note: 'len' is number of 32-bit words, not number of bytes! */ | ||
120 | int mas_writemem(int bank, int addr, const unsigned long* src, int len) | ||
121 | { | ||
122 | int ret = 0; | ||
123 | int i, j; | ||
124 | unsigned char buf[60]; | ||
125 | const unsigned char* ptr = (const unsigned char*)src; | ||
126 | |||
127 | i2c_begin(); | ||
128 | |||
129 | i=0; | ||
130 | buf[i++] = MAS_DATA_WRITE; | ||
131 | buf[i++] = bank?MAS_CMD_WRITE_D1_MEM:MAS_CMD_WRITE_D0_MEM; | ||
132 | buf[i++] = 0x00; | ||
133 | buf[i++] = (len & 0xff00) >> 8; | ||
134 | buf[i++] = len & 0xff; | ||
135 | buf[i++] = (addr & 0xff00) >> 8; | ||
136 | buf[i++] = addr & 0xff; | ||
137 | |||
138 | j = 0; | ||
139 | while(len--) { | ||
140 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
141 | buf[i++] = 0; | ||
142 | buf[i++] = ptr[j+1]; | ||
143 | buf[i++] = ptr[j+2]; | ||
144 | buf[i++] = ptr[j+3]; | ||
145 | #else | ||
146 | buf[i++] = ptr[j+2]; | ||
147 | buf[i++] = ptr[j+3]; | ||
148 | buf[i++] = 0; | ||
149 | buf[i++] = ptr[j+1]; | ||
150 | #endif | ||
151 | j += 4; | ||
152 | } | ||
153 | |||
154 | /* send write command */ | ||
155 | if (i2c_write(MAS_DEV_WRITE,buf,i)) | ||
156 | { | ||
157 | ret = -1; | ||
158 | } | ||
159 | |||
160 | i2c_end(); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | int mas_readreg(int reg) | ||
165 | { | ||
166 | int ret = 0; | ||
167 | unsigned char buf[16]; | ||
168 | unsigned long value; | ||
169 | |||
170 | i2c_begin(); | ||
171 | |||
172 | buf[0] = MAS_DATA_WRITE; | ||
173 | buf[1] = MAS_CMD_READ_REG | (reg >> 4); | ||
174 | buf[2] = (reg & 0x0f) << 4; | ||
175 | |||
176 | /* send read command */ | ||
177 | if (i2c_write(MAS_DEV_WRITE,buf,3)) | ||
178 | { | ||
179 | ret = -1; | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | if(mas_devread(&value, 1)) | ||
184 | { | ||
185 | ret = -2; | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | ret = value; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | i2c_end(); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | int mas_writereg(int reg, unsigned int val) | ||
198 | { | ||
199 | int ret = 0; | ||
200 | unsigned char buf[5]; | ||
201 | |||
202 | i2c_begin(); | ||
203 | |||
204 | buf[0] = MAS_DATA_WRITE; | ||
205 | buf[1] = MAS_CMD_WRITE_REG | (reg >> 4); | ||
206 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
207 | buf[2] = ((reg & 0x0f) << 4) | (val >> 16 & 0x0f); | ||
208 | buf[3] = (val >> 8) & 0xff; | ||
209 | buf[4] = val & 0xff; | ||
210 | #else | ||
211 | buf[2] = ((reg & 0x0f) << 4) | (val & 0x0f); | ||
212 | buf[3] = (val >> 12) & 0xff; | ||
213 | buf[4] = (val >> 4) & 0xff; | ||
214 | #endif | ||
215 | |||
216 | /* send write command */ | ||
217 | if (i2c_write(MAS_DEV_WRITE,buf,5)) | ||
218 | { | ||
219 | ret = -1; | ||
220 | } | ||
221 | |||
222 | i2c_end(); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | /* note: 'len' is number of 32-bit words, not number of bytes! */ | ||
227 | static int mas_devread(unsigned long *dest, int len) | ||
228 | { | ||
229 | int ret = 0; | ||
230 | unsigned char* ptr = (unsigned char*)dest; | ||
231 | int i; | ||
232 | |||
233 | /* handle read-back */ | ||
234 | /* Remember, the MAS values are only 20 bits, so we set | ||
235 | the upper 12 bits to 0 */ | ||
236 | i2c_start(); | ||
237 | i2c_outb(MAS_DEV_WRITE); | ||
238 | if (i2c_getack()) { | ||
239 | i2c_outb(MAS_DATA_READ); | ||
240 | if (i2c_getack()) { | ||
241 | i2c_start(); | ||
242 | i2c_outb(MAS_DEV_READ); | ||
243 | if (i2c_getack()) { | ||
244 | for (i=0;len;i++) { | ||
245 | len--; | ||
246 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
247 | i2c_inb(0); /* Dummy read */ | ||
248 | ptr[i*4+0] = 0; | ||
249 | ptr[i*4+1] = i2c_inb(0) & 0x0f; | ||
250 | ptr[i*4+2] = i2c_inb(0); | ||
251 | if(len) | ||
252 | ptr[i*4+3] = i2c_inb(0); | ||
253 | else | ||
254 | ptr[i*4+3] = i2c_inb(1); /* NAK the last byte */ | ||
255 | #else | ||
256 | ptr[i*4+2] = i2c_inb(0); | ||
257 | ptr[i*4+3] = i2c_inb(0); | ||
258 | ptr[i*4+0] = i2c_inb(0); | ||
259 | if(len) | ||
260 | ptr[i*4+1] = i2c_inb(0); | ||
261 | else | ||
262 | ptr[i*4+1] = i2c_inb(1); /* NAK the last byte */ | ||
263 | #endif | ||
264 | } | ||
265 | } | ||
266 | else | ||
267 | ret = -3; | ||
268 | } | ||
269 | else | ||
270 | ret = -2; | ||
271 | } | ||
272 | else | ||
273 | ret = -1; | ||
274 | |||
275 | i2c_stop(); | ||
276 | |||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | void mas_reset(void) | ||
281 | { | ||
282 | or_b(0x01, &PAIORH); | ||
283 | |||
284 | #if CONFIG_CODEC == MAS3507D | ||
285 | /* PB5 is "MAS enable". make it GPIO output and high */ | ||
286 | PBCR2 &= ~0x0c00; | ||
287 | or_b(0x20, &PBIORL); | ||
288 | or_b(0x20, &PBDRL); | ||
289 | |||
290 | and_b(~0x01, &PADRH); | ||
291 | sleep(HZ/100); | ||
292 | or_b(0x01, &PADRH); | ||
293 | sleep(HZ/5); | ||
294 | #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
295 | if (HW_MASK & ATA_ADDRESS_200) | ||
296 | { | ||
297 | and_b(~0x01, &PADRH); | ||
298 | sleep(HZ/100); | ||
299 | or_b(0x01, &PADRH); | ||
300 | sleep(HZ/5); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | /* Older recorder models don't invert the POR signal */ | ||
305 | or_b(0x01, &PADRH); | ||
306 | sleep(HZ/100); | ||
307 | and_b(~0x01, &PADRH); | ||
308 | sleep(HZ/5); | ||
309 | } | ||
310 | #endif | ||
311 | } | ||
312 | |||
313 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | ||
314 | #if 0 /* Currently unused, left for reference and future use */ | ||
315 | int mas_direct_config_read(unsigned char reg) | ||
316 | { | ||
317 | int ret = 0; | ||
318 | unsigned char tmp[2]; | ||
319 | |||
320 | i2c_begin(); | ||
321 | |||
322 | i2c_start(); | ||
323 | i2c_outb(MAS_DEV_WRITE); | ||
324 | if (i2c_getack()) { | ||
325 | i2c_outb(reg); | ||
326 | if (i2c_getack()) { | ||
327 | i2c_start(); | ||
328 | i2c_outb(MAS_DEV_READ); | ||
329 | if (i2c_getack()) { | ||
330 | tmp[0] = i2c_inb(0); | ||
331 | tmp[1] = i2c_inb(1); /* NAK the last byte */ | ||
332 | ret = (tmp[0] << 8) | tmp[1]; | ||
333 | } | ||
334 | else | ||
335 | ret = -3; | ||
336 | } | ||
337 | else | ||
338 | ret = -2; | ||
339 | } | ||
340 | else | ||
341 | ret = -1; | ||
342 | |||
343 | i2c_stop(); | ||
344 | |||
345 | i2c_end(); | ||
346 | return ret; | ||
347 | } | ||
348 | #endif | ||
349 | |||
350 | int mas_direct_config_write(unsigned char reg, unsigned int val) | ||
351 | { | ||
352 | int ret = 0; | ||
353 | unsigned char buf[3]; | ||
354 | |||
355 | i2c_begin(); | ||
356 | |||
357 | buf[0] = reg; | ||
358 | buf[1] = (val >> 8) & 0xff; | ||
359 | buf[2] = val & 0xff; | ||
360 | |||
361 | /* send write command */ | ||
362 | if (i2c_write(MAS_DEV_WRITE,buf,3)) | ||
363 | { | ||
364 | ret = -1; | ||
365 | } | ||
366 | |||
367 | i2c_end(); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | int mas_codec_writereg(int reg, unsigned int val) | ||
372 | { | ||
373 | int ret = 0; | ||
374 | unsigned char buf[5]; | ||
375 | |||
376 | i2c_begin(); | ||
377 | |||
378 | buf[0] = MAS_CODEC_WRITE; | ||
379 | buf[1] = (reg >> 8) & 0xff; | ||
380 | buf[2] = reg & 0xff; | ||
381 | buf[3] = (val >> 8) & 0xff; | ||
382 | buf[4] = val & 0xff; | ||
383 | |||
384 | /* send write command */ | ||
385 | if (i2c_write(MAS_DEV_WRITE,buf,5)) | ||
386 | { | ||
387 | ret = -1; | ||
388 | } | ||
389 | |||
390 | i2c_end(); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | int mas_codec_readreg(int reg) | ||
395 | { | ||
396 | int ret = 0; | ||
397 | unsigned char buf[16]; | ||
398 | unsigned char tmp[2]; | ||
399 | |||
400 | i2c_begin(); | ||
401 | |||
402 | buf[0] = MAS_CODEC_WRITE; | ||
403 | buf[1] = (reg >> 8) & 0xff; | ||
404 | buf[2] = reg & 0xff; | ||
405 | |||
406 | /* send read command */ | ||
407 | if (i2c_write(MAS_DEV_WRITE,buf,3)) | ||
408 | { | ||
409 | ret = -1; | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | i2c_start(); | ||
414 | i2c_outb(MAS_DEV_WRITE); | ||
415 | if (i2c_getack()) { | ||
416 | i2c_outb(MAS_CODEC_READ); | ||
417 | if (i2c_getack()) { | ||
418 | i2c_start(); | ||
419 | i2c_outb(MAS_DEV_READ); | ||
420 | if (i2c_getack()) { | ||
421 | tmp[0] = i2c_inb(0); | ||
422 | tmp[1] = i2c_inb(1); /* NAK the last byte */ | ||
423 | ret = (tmp[0] << 8) | tmp[1]; | ||
424 | } | ||
425 | else | ||
426 | ret = -4; | ||
427 | } | ||
428 | else | ||
429 | ret = -3; | ||
430 | } | ||
431 | else | ||
432 | ret = -2; | ||
433 | |||
434 | i2c_stop(); | ||
435 | } | ||
436 | |||
437 | i2c_end(); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | unsigned long mas_readver(void) | ||
442 | { | ||
443 | int ret = 0; | ||
444 | unsigned char buf[16]; | ||
445 | unsigned long value; | ||
446 | |||
447 | i2c_begin(); | ||
448 | |||
449 | buf[0] = MAS_DATA_WRITE; | ||
450 | buf[1] = MAS_CMD_READ_IC_VER; | ||
451 | buf[2] = 0; | ||
452 | |||
453 | /* send read command */ | ||
454 | if (i2c_write(MAS_DEV_WRITE,buf,3)) | ||
455 | { | ||
456 | ret = -1; | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | if(mas_devread(&value, 1)) | ||
461 | { | ||
462 | ret = -2; | ||
463 | } | ||
464 | else | ||
465 | { | ||
466 | ret = value; | ||
467 | } | ||
468 | } | ||
469 | |||
470 | i2c_end(); | ||
471 | return ret; | ||
472 | } | ||
473 | |||
474 | #endif | ||
475 | |||
476 | #if CONFIG_TUNER & S1A0903X01 | ||
477 | static int pllfreq; | ||
478 | |||
479 | void mas_store_pllfreq(int freq) | ||
480 | { | ||
481 | pllfreq = freq; | ||
482 | } | ||
483 | |||
484 | int mas_get_pllfreq(void) | ||
485 | { | ||
486 | return pllfreq; | ||
487 | } | ||
488 | #endif | ||
489 | |||
490 | |||
491 | |||
diff --git a/firmware/target/sh/archos/ondio/adc-target.h b/firmware/target/sh/archos/ondio/adc-target.h deleted file mode 100644 index a39ee110f3..0000000000 --- a/firmware/target/sh/archos/ondio/adc-target.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef _ADC_TARGET_H_ | ||
22 | #define _ADC_TARGET_H_ | ||
23 | |||
24 | #define NUM_ADC_CHANNELS 8 | ||
25 | |||
26 | #define ADC_MMC_SWITCH 0 /* low values if MMC inserted */ | ||
27 | #define ADC_USB_POWER 1 /* USB, reads 0x000 when USB is inserted */ | ||
28 | #define ADC_BUTTON_OPTION 2 /* the option button, low value if pressed */ | ||
29 | #define ADC_BUTTON_ONOFF 3 /* the on/off button, high value if pressed */ | ||
30 | #define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different | ||
31 | voltages for different keys */ | ||
32 | #define ADC_USB_ACTIVE 5 /* USB bridge activity */ | ||
33 | #define ADC_UNREG_POWER 7 /* Battery voltage */ | ||
34 | |||
35 | #define EXT_SCALE_FACTOR 14800 | ||
36 | |||
37 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/ondio/ata_mmc.c b/firmware/target/sh/archos/ondio/ata_mmc.c deleted file mode 100644 index f252e1c4ce..0000000000 --- a/firmware/target/sh/archos/ondio/ata_mmc.c +++ /dev/null | |||
@@ -1,978 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "ata_mmc.h" | ||
23 | #include "sdmmc.h" | ||
24 | #include "kernel.h" | ||
25 | #include "led.h" | ||
26 | #include "sh7034.h" | ||
27 | #include "system.h" | ||
28 | #include "debug.h" | ||
29 | #include "panic.h" | ||
30 | #include "power.h" | ||
31 | #include "string.h" | ||
32 | #include "hwcompat.h" | ||
33 | #include "adc.h" | ||
34 | #include "bitswap.h" | ||
35 | #include "storage.h" | ||
36 | |||
37 | |||
38 | #ifdef HAVE_MULTIDRIVE | ||
39 | #define MMC_NUM_DRIVES 2 | ||
40 | #else | ||
41 | #define MMC_NUM_DRIVES 1 | ||
42 | #endif | ||
43 | |||
44 | #define BLOCK_SIZE 512 /* fixed */ | ||
45 | |||
46 | /* Command definitions */ | ||
47 | #define CMD_GO_IDLE_STATE 0x40 /* R1 */ | ||
48 | #define CMD_SEND_OP_COND 0x41 /* R1 */ | ||
49 | #define CMD_SEND_CSD 0x49 /* R1 */ | ||
50 | #define CMD_SEND_CID 0x4a /* R1 */ | ||
51 | #define CMD_STOP_TRANSMISSION 0x4c /* R1 */ | ||
52 | #define CMD_SEND_STATUS 0x4d /* R2 */ | ||
53 | #define CMD_SET_BLOCKLEN 0x50 /* R1 */ | ||
54 | #define CMD_READ_SINGLE_BLOCK 0x51 /* R1 */ | ||
55 | #define CMD_READ_MULTIPLE_BLOCK 0x52 /* R1 */ | ||
56 | #define CMD_WRITE_BLOCK 0x58 /* R1b */ | ||
57 | #define CMD_WRITE_MULTIPLE_BLOCK 0x59 /* R1b */ | ||
58 | #define CMD_READ_OCR 0x7a /* R3 */ | ||
59 | |||
60 | /* Response formats: | ||
61 | R1 = single byte, msb=0, various error flags | ||
62 | R1b = R1 + busy token(s) | ||
63 | R2 = 2 bytes (1st byte identical to R1), additional flags | ||
64 | R3 = 5 bytes (R1 + OCR register) | ||
65 | */ | ||
66 | |||
67 | #define R1_PARAMETER_ERR 0x40 | ||
68 | #define R1_ADDRESS_ERR 0x20 | ||
69 | #define R1_ERASE_SEQ_ERR 0x10 | ||
70 | #define R1_COM_CRC_ERR 0x08 | ||
71 | #define R1_ILLEGAL_CMD 0x04 | ||
72 | #define R1_ERASE_RESET 0x02 | ||
73 | #define R1_IN_IDLE_STATE 0x01 | ||
74 | |||
75 | #define R2_OUT_OF_RANGE 0x80 | ||
76 | #define R2_ERASE_PARAM 0x40 | ||
77 | #define R2_WP_VIOLATION 0x20 | ||
78 | #define R2_CARD_ECC_FAIL 0x10 | ||
79 | #define R2_CC_ERROR 0x08 | ||
80 | #define R2_ERROR 0x04 | ||
81 | #define R2_ERASE_SKIP 0x02 | ||
82 | #define R2_CARD_LOCKED 0x01 | ||
83 | |||
84 | /* Data start tokens */ | ||
85 | |||
86 | #define DT_START_BLOCK 0xfe | ||
87 | #define DT_START_WRITE_MULTIPLE 0xfc | ||
88 | #define DT_STOP_TRAN 0xfd | ||
89 | |||
90 | /* for compatibility */ | ||
91 | static long last_disk_activity = -1; | ||
92 | |||
93 | /* private variables */ | ||
94 | |||
95 | #ifdef CONFIG_STORAGE_MULTI | ||
96 | static int mmc_first_drive = 0; | ||
97 | #else | ||
98 | #define mmc_first_drive 0 | ||
99 | #endif | ||
100 | |||
101 | static struct mutex mmc_mutex SHAREDBSS_ATTR; | ||
102 | |||
103 | static bool initialized = false; | ||
104 | static bool new_mmc_circuit; | ||
105 | |||
106 | static enum { | ||
107 | MMC_UNKNOWN, | ||
108 | MMC_UNTOUCHED, | ||
109 | MMC_TOUCHED | ||
110 | } mmc_status = MMC_UNKNOWN; | ||
111 | |||
112 | static enum { | ||
113 | SER_POLL_WRITE, | ||
114 | SER_POLL_READ, | ||
115 | SER_DISABLED | ||
116 | } serial_mode; | ||
117 | |||
118 | static const unsigned char dummy[] = { | ||
119 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | ||
120 | }; | ||
121 | |||
122 | /* 2 buffers used alternatively for writing, including start token, | ||
123 | * dummy CRC and an extra byte to keep word alignment. */ | ||
124 | static unsigned char write_buffer[2][BLOCK_SIZE+4]; | ||
125 | static int current_buffer = 0; | ||
126 | static const unsigned char *send_block_addr = NULL; | ||
127 | |||
128 | static tCardInfo card_info[2]; | ||
129 | #ifndef HAVE_MULTIDRIVE | ||
130 | static int current_card = 0; | ||
131 | #endif | ||
132 | static bool last_mmc_status = false; | ||
133 | static int countdown = -1; /* for mmc switch debouncing. -1 because the | ||
134 | countdown should not happen if the card | ||
135 | is inserted at boot */ | ||
136 | static bool usb_activity; /* monitoring the USB bridge */ | ||
137 | static long last_usb_activity; | ||
138 | |||
139 | /* private function declarations */ | ||
140 | |||
141 | static int select_card(int card_no); | ||
142 | static void deselect_card(void); | ||
143 | static void setup_sci1(int bitrate_register); | ||
144 | static void set_sci1_poll_read(void); | ||
145 | static void write_transfer(const unsigned char *buf, int len) | ||
146 | __attribute__ ((section(".icode"))); | ||
147 | static void read_transfer(unsigned char *buf, int len) | ||
148 | __attribute__ ((section(".icode"))); | ||
149 | static unsigned char poll_byte(long timeout); | ||
150 | static unsigned char poll_busy(long timeout); | ||
151 | static unsigned char send_cmd(int cmd, unsigned long parameter, void *data); | ||
152 | static int receive_cxd(unsigned char *buf); | ||
153 | static int initialize_card(int card_no); | ||
154 | static int receive_block(unsigned char *inbuf, long timeout); | ||
155 | static void send_block_prepare(void); | ||
156 | static int send_block_send(unsigned char start_token, long timeout, | ||
157 | bool prepare_next); | ||
158 | static void mmc_tick(void); | ||
159 | |||
160 | /* implementation */ | ||
161 | |||
162 | static void enable_controller(bool on) | ||
163 | { | ||
164 | PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, | ||
165 | * if not modified below */ | ||
166 | if (on) | ||
167 | PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */ | ||
168 | |||
169 | and_b(~0x80, &PADRL); /* assert flash reset */ | ||
170 | sleep(HZ/100); | ||
171 | or_b(0x80, &PADRL); /* de-assert flash reset */ | ||
172 | sleep(HZ/100); | ||
173 | card_info[0].initialized = false; | ||
174 | card_info[1].initialized = false; | ||
175 | } | ||
176 | |||
177 | void mmc_enable_int_flash_clock(bool on) | ||
178 | { | ||
179 | /* Internal flash clock is enabled by setting PA12 high with the new | ||
180 | * clock circuit, and by setting it low with the old clock circuit */ | ||
181 | if (on ^ new_mmc_circuit) | ||
182 | and_b(~0x10, &PADRH); /* clear clock gate PA12 */ | ||
183 | else | ||
184 | or_b(0x10, &PADRH); /* set clock gate PA12 */ | ||
185 | } | ||
186 | |||
187 | static int select_card(int card_no) | ||
188 | { | ||
189 | mutex_lock(&mmc_mutex); | ||
190 | led(true); | ||
191 | last_disk_activity = current_tick; | ||
192 | |||
193 | mmc_enable_int_flash_clock(card_no == 0); | ||
194 | |||
195 | if (!card_info[card_no].initialized) | ||
196 | { | ||
197 | setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */ | ||
198 | write_transfer(dummy, 10); /* allow the card to synchronize */ | ||
199 | while (!(SSR1 & SCI_TEND)); | ||
200 | } | ||
201 | |||
202 | if (card_no == 0) /* internal */ | ||
203 | and_b(~0x04, &PADRH); /* assert CS */ | ||
204 | else /* external */ | ||
205 | and_b(~0x02, &PADRH); /* assert CS */ | ||
206 | |||
207 | if (card_info[card_no].initialized) | ||
208 | { | ||
209 | setup_sci1(card_info[card_no].bitrate_register); | ||
210 | return 0; | ||
211 | } | ||
212 | else | ||
213 | { | ||
214 | return initialize_card(card_no); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | static void deselect_card(void) | ||
219 | { | ||
220 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
221 | or_b(0x06, &PADRH); /* deassert CS (both cards) */ | ||
222 | |||
223 | led(false); | ||
224 | mutex_unlock(&mmc_mutex); | ||
225 | last_disk_activity = current_tick; | ||
226 | } | ||
227 | |||
228 | static void setup_sci1(int bitrate_register) | ||
229 | { | ||
230 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
231 | |||
232 | SCR1 = 0; /* disable serial port */ | ||
233 | SMR1 = SYNC_MODE; /* no prescale */ | ||
234 | BRR1 = bitrate_register; | ||
235 | SSR1 = 0; | ||
236 | |||
237 | SCR1 = SCI_TE; /* enable transmitter */ | ||
238 | serial_mode = SER_POLL_WRITE; | ||
239 | } | ||
240 | |||
241 | static void set_sci1_poll_read(void) | ||
242 | { | ||
243 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
244 | SCR1 = 0; /* disable transmitter (& receiver) */ | ||
245 | SCR1 = (SCI_TE|SCI_RE); /* re-enable transmitter & receiver */ | ||
246 | while (!(SSR1 & SCI_TEND)); /* wait for SCI init completion (!) */ | ||
247 | serial_mode = SER_POLL_READ; | ||
248 | TDR1 = 0xFF; /* send do-nothing while reading */ | ||
249 | } | ||
250 | |||
251 | static void write_transfer(const unsigned char *buf, int len) | ||
252 | { | ||
253 | const unsigned char *buf_end = buf + len; | ||
254 | register unsigned char data; | ||
255 | |||
256 | if (serial_mode != SER_POLL_WRITE) | ||
257 | { | ||
258 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
259 | SCR1 = 0; /* disable transmitter & receiver */ | ||
260 | SSR1 = 0; /* clear all flags */ | ||
261 | SCR1 = SCI_TE; /* enable transmitter only */ | ||
262 | serial_mode = SER_POLL_WRITE; | ||
263 | } | ||
264 | |||
265 | while (buf < buf_end) | ||
266 | { | ||
267 | data = fliptable[(signed char)(*buf++)]; /* bitswap */ | ||
268 | while (!(SSR1 & SCI_TDRE)); /* wait for end of transfer */ | ||
269 | TDR1 = data; /* write byte */ | ||
270 | SSR1 = 0; /* start transmitting */ | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /* don't call this with len == 0 */ | ||
275 | static void read_transfer(unsigned char *buf, int len) | ||
276 | { | ||
277 | unsigned char *buf_end = buf + len - 1; | ||
278 | register signed char data; | ||
279 | |||
280 | if (serial_mode != SER_POLL_READ) | ||
281 | set_sci1_poll_read(); | ||
282 | |||
283 | SSR1 = 0; /* start receiving first byte */ | ||
284 | while (buf < buf_end) | ||
285 | { | ||
286 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
287 | data = RDR1; /* read byte */ | ||
288 | SSR1 = 0; /* start receiving */ | ||
289 | *buf++ = fliptable[data]; /* bitswap */ | ||
290 | } | ||
291 | while (!(SSR1 & SCI_RDRF)); /* wait for last byte */ | ||
292 | *buf = fliptable[(signed char)(RDR1)]; /* read & bitswap */ | ||
293 | } | ||
294 | |||
295 | /* returns 0xFF on timeout, timeout is in bytes */ | ||
296 | static unsigned char poll_byte(long timeout) | ||
297 | { | ||
298 | long i; | ||
299 | unsigned char data = 0; /* stop the compiler complaining */ | ||
300 | |||
301 | if (serial_mode != SER_POLL_READ) | ||
302 | set_sci1_poll_read(); | ||
303 | |||
304 | i = 0; | ||
305 | do { | ||
306 | SSR1 = 0; /* start receiving */ | ||
307 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
308 | data = RDR1; /* read byte */ | ||
309 | } while ((data == 0xFF) && (++i < timeout)); | ||
310 | |||
311 | return fliptable[(signed char)data]; | ||
312 | } | ||
313 | |||
314 | /* returns 0 on timeout, timeout is in bytes */ | ||
315 | static unsigned char poll_busy(long timeout) | ||
316 | { | ||
317 | long i; | ||
318 | unsigned char data, dummy; | ||
319 | |||
320 | if (serial_mode != SER_POLL_READ) | ||
321 | set_sci1_poll_read(); | ||
322 | |||
323 | /* get data response */ | ||
324 | SSR1 = 0; /* start receiving */ | ||
325 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
326 | data = fliptable[(signed char)(RDR1)]; /* read byte */ | ||
327 | |||
328 | /* wait until the card is ready again */ | ||
329 | i = 0; | ||
330 | do { | ||
331 | SSR1 = 0; /* start receiving */ | ||
332 | while (!(SSR1 & SCI_RDRF)); /* wait for data */ | ||
333 | dummy = RDR1; /* read byte */ | ||
334 | } while ((dummy != 0xFF) && (++i < timeout)); | ||
335 | |||
336 | return (dummy == 0xFF) ? data : 0; | ||
337 | } | ||
338 | |||
339 | /* Send MMC command and get response. Returns R1 byte directly. | ||
340 | * Returns further R2 or R3 bytes in *data (can be NULL for other commands) */ | ||
341 | static unsigned char send_cmd(int cmd, unsigned long parameter, void *data) | ||
342 | { | ||
343 | static struct { | ||
344 | unsigned char cmd; | ||
345 | unsigned long parameter; | ||
346 | const unsigned char crc7; /* fixed, valid for CMD0 only */ | ||
347 | const unsigned char trailer; | ||
348 | } __attribute__((packed)) command = {0x40, 0, 0x95, 0xFF}; | ||
349 | |||
350 | unsigned char ret; | ||
351 | |||
352 | command.cmd = cmd; | ||
353 | command.parameter = htobe32(parameter); | ||
354 | |||
355 | write_transfer((unsigned char *)&command, sizeof(command)); | ||
356 | |||
357 | ret = poll_byte(20); | ||
358 | |||
359 | switch (cmd) | ||
360 | { | ||
361 | case CMD_SEND_CSD: /* R1 response, leave open */ | ||
362 | case CMD_SEND_CID: | ||
363 | case CMD_READ_SINGLE_BLOCK: | ||
364 | case CMD_READ_MULTIPLE_BLOCK: | ||
365 | return ret; | ||
366 | |||
367 | case CMD_SEND_STATUS: /* R2 response, close with dummy */ | ||
368 | read_transfer(data, 1); | ||
369 | break; | ||
370 | |||
371 | case CMD_READ_OCR: /* R3 response, close with dummy */ | ||
372 | read_transfer(data, 4); | ||
373 | break; | ||
374 | |||
375 | default: /* R1 response, close with dummy */ | ||
376 | break; /* also catches block writes */ | ||
377 | } | ||
378 | write_transfer(dummy, 1); | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | /* Receive CID/ CSD data (16 bytes) */ | ||
383 | static int receive_cxd(unsigned char *buf) | ||
384 | { | ||
385 | if (poll_byte(20) != DT_START_BLOCK) | ||
386 | { | ||
387 | write_transfer(dummy, 1); | ||
388 | return -1; /* not start of data */ | ||
389 | } | ||
390 | |||
391 | read_transfer(buf, 16); | ||
392 | write_transfer(dummy, 3); /* 2 bytes dontcare crc + 1 byte trailer */ | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | |||
397 | static int initialize_card(int card_no) | ||
398 | { | ||
399 | int rc, i; | ||
400 | int blk_exp, ts_exp, taac_exp; | ||
401 | tCardInfo *card = &card_info[card_no]; | ||
402 | |||
403 | static const char mantissa[] = { /* *10 */ | ||
404 | 0, 10, 12, 13, 15, 20, 25, 30, | ||
405 | 35, 40, 45, 50, 55, 60, 70, 80 | ||
406 | }; | ||
407 | static const int exponent[] = { /* use varies */ | ||
408 | 1, 10, 100, 1000, 10000, 100000, 1000000, | ||
409 | 10000000, 100000000, 1000000000 | ||
410 | }; | ||
411 | |||
412 | if (card_no == 1) | ||
413 | mmc_status = MMC_TOUCHED; | ||
414 | |||
415 | /* switch to SPI mode */ | ||
416 | if (send_cmd(CMD_GO_IDLE_STATE, 0, NULL) != 0x01) | ||
417 | return -1; /* error or no response */ | ||
418 | |||
419 | /* initialize card */ | ||
420 | for (i = HZ;;) /* try for 1 second*/ | ||
421 | { | ||
422 | sleep(1); | ||
423 | if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0) | ||
424 | break; | ||
425 | if (--i <= 0) | ||
426 | return -2; /* timeout */ | ||
427 | } | ||
428 | |||
429 | /* get OCR register */ | ||
430 | if (send_cmd(CMD_READ_OCR, 0, &card->ocr)) | ||
431 | return -3; | ||
432 | card->ocr = betoh32(card->ocr); /* no-op on big endian */ | ||
433 | |||
434 | /* check voltage */ | ||
435 | if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */ | ||
436 | return -4; | ||
437 | |||
438 | /* get CSD register */ | ||
439 | if (send_cmd(CMD_SEND_CSD, 0, NULL)) | ||
440 | return -5; | ||
441 | rc = receive_cxd((unsigned char*)card->csd); | ||
442 | if (rc) | ||
443 | return rc * 10 - 5; | ||
444 | |||
445 | blk_exp = card_extract_bits(card->csd, 83, 4); | ||
446 | if (blk_exp < 9) /* block size < 512 bytes not supported */ | ||
447 | return -6; | ||
448 | |||
449 | card->numblocks = (card_extract_bits(card->csd, 73, 12) + 1) | ||
450 | << (card_extract_bits(card->csd, 49, 3) + 2 + blk_exp - 9); | ||
451 | card->blocksize = BLOCK_SIZE; | ||
452 | |||
453 | /* max transmission speed, clock divider */ | ||
454 | ts_exp = card_extract_bits(card->csd, 98, 3); | ||
455 | ts_exp = (ts_exp > 3) ? 3 : ts_exp; | ||
456 | card->speed = mantissa[card_extract_bits(card->csd, 102, 4)] | ||
457 | * exponent[ts_exp + 4]; | ||
458 | card->bitrate_register = (FREQ/4-1) / card->speed; | ||
459 | |||
460 | /* NSAC, TAAC, read timeout */ | ||
461 | card->nsac = 100 * card_extract_bits(card->csd, 111, 8); | ||
462 | card->taac = mantissa[card_extract_bits(card->csd, 118, 4)]; | ||
463 | taac_exp = card_extract_bits(card->csd, 114, 3); | ||
464 | card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1) | ||
465 | * card->taac / exponent[9 - taac_exp] | ||
466 | + (10 * card->nsac)); | ||
467 | card->read_timeout /= 8; /* clocks -> bytes */ | ||
468 | card->taac = card->taac * exponent[taac_exp] / 10; | ||
469 | |||
470 | /* r2w_factor, write timeout */ | ||
471 | card->r2w_factor = BIT_N(card_extract_bits(card->csd, 28, 3)); | ||
472 | card->write_timeout = card->read_timeout * card->r2w_factor; | ||
473 | |||
474 | if (card->r2w_factor > 32) /* Such cards often need extra read delay */ | ||
475 | card->read_timeout *= 4; | ||
476 | |||
477 | /* switch to full speed */ | ||
478 | setup_sci1(card->bitrate_register); | ||
479 | |||
480 | /* always use 512 byte blocks */ | ||
481 | if (send_cmd(CMD_SET_BLOCKLEN, BLOCK_SIZE, NULL)) | ||
482 | return -7; | ||
483 | |||
484 | /* get CID register */ | ||
485 | if (send_cmd(CMD_SEND_CID, 0, NULL)) | ||
486 | return -8; | ||
487 | rc = receive_cxd((unsigned char*)card->cid); | ||
488 | if (rc) | ||
489 | return rc * 10 - 8; | ||
490 | |||
491 | card->initialized = true; | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | tCardInfo *mmc_card_info(int card_no) | ||
496 | { | ||
497 | tCardInfo *card = &card_info[card_no]; | ||
498 | |||
499 | if (!card->initialized && ((card_no == 0) || mmc_detect())) | ||
500 | { | ||
501 | select_card(card_no); | ||
502 | deselect_card(); | ||
503 | } | ||
504 | return card; | ||
505 | } | ||
506 | |||
507 | /* Receive one block with DMA and bitswap it (chasing bitswap). */ | ||
508 | static int receive_block(unsigned char *inbuf, long timeout) | ||
509 | { | ||
510 | unsigned long buf_end; | ||
511 | |||
512 | if (poll_byte(timeout) != DT_START_BLOCK) | ||
513 | { | ||
514 | write_transfer(dummy, 1); | ||
515 | return -1; /* not start of data */ | ||
516 | } | ||
517 | |||
518 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
519 | |||
520 | SCR1 = 0; /* disable serial */ | ||
521 | SSR1 = 0; /* clear all flags */ | ||
522 | |||
523 | /* setup DMA channel 0 */ | ||
524 | CHCR0 = 0; /* disable */ | ||
525 | SAR0 = RDR1_ADDR; | ||
526 | DAR0 = (unsigned long) inbuf; | ||
527 | DTCR0 = BLOCK_SIZE; | ||
528 | CHCR0 = 0x4601; /* fixed source address, RXI1, enable */ | ||
529 | DMAOR = 0x0001; | ||
530 | SCR1 = (SCI_RE|SCI_RIE); /* kick off DMA */ | ||
531 | |||
532 | /* DMA receives 2 bytes more than DTCR2, but the last 2 bytes are not | ||
533 | * stored. The first extra byte is available from RDR1 after the DMA ends, | ||
534 | * the second one is lost because of the SCI overrun. However, this | ||
535 | * behaviour conveniently discards the crc. */ | ||
536 | |||
537 | yield(); /* be nice */ | ||
538 | |||
539 | /* Bitswap received data, chasing the DMA pointer */ | ||
540 | buf_end = (unsigned long)inbuf + BLOCK_SIZE; | ||
541 | do | ||
542 | { | ||
543 | /* Call bitswap whenever (a multiple of) 8 bytes are | ||
544 | * available (value optimised by experimentation). */ | ||
545 | int swap_now = (DAR0 - (unsigned long)inbuf) & ~0x00000007; | ||
546 | if (swap_now) | ||
547 | { | ||
548 | bitswap(inbuf, swap_now); | ||
549 | inbuf += swap_now; | ||
550 | } | ||
551 | } | ||
552 | while ((unsigned long)inbuf < buf_end); | ||
553 | |||
554 | while (!(CHCR0 & 0x0002)); /* wait for end of DMA */ | ||
555 | while (!(SSR1 & SCI_ORER)); /* wait for the trailing bytes */ | ||
556 | SCR1 = 0; | ||
557 | serial_mode = SER_DISABLED; | ||
558 | |||
559 | write_transfer(dummy, 1); /* send trailer */ | ||
560 | last_disk_activity = current_tick; | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | /* Prepare a block for sending by copying it to the next write buffer | ||
565 | * and bitswapping it. */ | ||
566 | static void send_block_prepare(void) | ||
567 | { | ||
568 | unsigned char *dest; | ||
569 | |||
570 | current_buffer ^= 1; /* toggle buffer */ | ||
571 | dest = write_buffer[current_buffer] + 2; | ||
572 | |||
573 | memcpy(dest, send_block_addr, BLOCK_SIZE); | ||
574 | bitswap(dest, BLOCK_SIZE); | ||
575 | |||
576 | send_block_addr += BLOCK_SIZE; | ||
577 | } | ||
578 | |||
579 | /* Send one block with DMA from the current write buffer, possibly preparing | ||
580 | * the next block within the next write buffer in the background. */ | ||
581 | static int send_block_send(unsigned char start_token, long timeout, | ||
582 | bool prepare_next) | ||
583 | { | ||
584 | int rc = 0; | ||
585 | unsigned char *curbuf = write_buffer[current_buffer]; | ||
586 | |||
587 | curbuf[1] = fliptable[(signed char)start_token]; | ||
588 | *(unsigned short *)(curbuf + BLOCK_SIZE + 2) = 0xFFFF; | ||
589 | |||
590 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
591 | |||
592 | SCR1 = 0; /* disable serial */ | ||
593 | SSR1 = 0; /* clear all flags */ | ||
594 | |||
595 | /* setup DMA channel 0 */ | ||
596 | CHCR0 = 0; /* disable */ | ||
597 | SAR0 = (unsigned long)(curbuf + 1); | ||
598 | DAR0 = TDR1_ADDR; | ||
599 | DTCR0 = BLOCK_SIZE + 3; /* start token + block + dummy crc */ | ||
600 | CHCR0 = 0x1701; /* fixed dest. address, TXI1, enable */ | ||
601 | DMAOR = 0x0001; | ||
602 | SCR1 = (SCI_TE|SCI_TIE); /* kick off DMA */ | ||
603 | |||
604 | if (prepare_next) | ||
605 | send_block_prepare(); | ||
606 | yield(); /* be nice */ | ||
607 | |||
608 | while (!(CHCR0 & 0x0002)); /* wait for end of DMA */ | ||
609 | while (!(SSR1 & SCI_TEND)); /* wait for end of transfer */ | ||
610 | SCR1 = 0; | ||
611 | serial_mode = SER_DISABLED; | ||
612 | |||
613 | if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */ | ||
614 | rc = -1; | ||
615 | |||
616 | write_transfer(dummy, 1); | ||
617 | last_disk_activity = current_tick; | ||
618 | |||
619 | return rc; | ||
620 | } | ||
621 | |||
622 | int mmc_read_sectors(IF_MD(int drive,) | ||
623 | unsigned long start, | ||
624 | int incount, | ||
625 | void* inbuf) | ||
626 | { | ||
627 | int rc = 0; | ||
628 | int lastblock = 0; | ||
629 | unsigned long end_block; | ||
630 | tCardInfo *card; | ||
631 | #ifndef HAVE_MULTIDRIVE | ||
632 | int drive = current_card; | ||
633 | #endif | ||
634 | |||
635 | card = &card_info[drive]; | ||
636 | rc = select_card(drive); | ||
637 | if (rc) | ||
638 | { | ||
639 | rc = rc * 10 - 1; | ||
640 | goto error; | ||
641 | } | ||
642 | |||
643 | end_block = start + incount; | ||
644 | if (end_block > card->numblocks) | ||
645 | { | ||
646 | rc = -2; | ||
647 | goto error; | ||
648 | } | ||
649 | |||
650 | /* Some cards don't like reading the very last block with | ||
651 | * CMD_READ_MULTIPLE_BLOCK, so make sure this block is always | ||
652 | * read with CMD_READ_SINGLE_BLOCK. */ | ||
653 | if (end_block == card->numblocks) | ||
654 | lastblock = 1; | ||
655 | |||
656 | if (incount > 1) | ||
657 | { | ||
658 | /* MMC4.2: make multiplication conditional */ | ||
659 | if (send_cmd(CMD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL)) | ||
660 | { | ||
661 | rc = -3; | ||
662 | goto error; | ||
663 | } | ||
664 | while (--incount >= lastblock) | ||
665 | { | ||
666 | rc = receive_block(inbuf, card->read_timeout); | ||
667 | if (rc) | ||
668 | { | ||
669 | /* If an error occurs during multiple block reading, the | ||
670 | * host still needs to send CMD_STOP_TRANSMISSION */ | ||
671 | send_cmd(CMD_STOP_TRANSMISSION, 0, NULL); | ||
672 | rc = rc * 10 - 4; | ||
673 | goto error; | ||
674 | } | ||
675 | inbuf += BLOCK_SIZE; | ||
676 | start++; | ||
677 | /* ^^ necessary for the abovementioned last block special case */ | ||
678 | } | ||
679 | if (send_cmd(CMD_STOP_TRANSMISSION, 0, NULL)) | ||
680 | { | ||
681 | rc = -5; | ||
682 | goto error; | ||
683 | } | ||
684 | } | ||
685 | if (incount > 0) | ||
686 | { | ||
687 | /* MMC4.2: make multiplication conditional */ | ||
688 | if (send_cmd(CMD_READ_SINGLE_BLOCK, start * BLOCK_SIZE, NULL)) | ||
689 | { | ||
690 | rc = -6; | ||
691 | goto error; | ||
692 | } | ||
693 | rc = receive_block(inbuf, card->read_timeout); | ||
694 | if (rc) | ||
695 | { | ||
696 | rc = rc * 10 - 7; | ||
697 | goto error; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | error: | ||
702 | |||
703 | deselect_card(); | ||
704 | |||
705 | return rc; | ||
706 | } | ||
707 | |||
708 | int mmc_write_sectors(IF_MD(int drive,) | ||
709 | unsigned long start, | ||
710 | int count, | ||
711 | const void* buf) | ||
712 | { | ||
713 | int rc = 0; | ||
714 | int write_cmd; | ||
715 | unsigned char start_token; | ||
716 | tCardInfo *card; | ||
717 | #ifndef HAVE_MULTIDRIVE | ||
718 | int drive = current_card; | ||
719 | #endif | ||
720 | |||
721 | card = &card_info[drive]; | ||
722 | rc = select_card(drive); | ||
723 | if (rc) | ||
724 | { | ||
725 | rc = rc * 10 - 1; | ||
726 | goto error; | ||
727 | } | ||
728 | |||
729 | if (start + count > card->numblocks) | ||
730 | panicf("Writing past end of card"); | ||
731 | |||
732 | send_block_addr = buf; | ||
733 | send_block_prepare(); | ||
734 | |||
735 | if (count > 1) | ||
736 | { | ||
737 | write_cmd = CMD_WRITE_MULTIPLE_BLOCK; | ||
738 | start_token = DT_START_WRITE_MULTIPLE; | ||
739 | } | ||
740 | else | ||
741 | { | ||
742 | write_cmd = CMD_WRITE_BLOCK; | ||
743 | start_token = DT_START_BLOCK; | ||
744 | } | ||
745 | /* MMC4.2: make multiplication conditional */ | ||
746 | if (send_cmd(write_cmd, start * BLOCK_SIZE, NULL)) | ||
747 | { | ||
748 | rc = -2; | ||
749 | goto error; | ||
750 | } | ||
751 | while (--count >= 0) | ||
752 | { | ||
753 | rc = send_block_send(start_token, card->write_timeout, count > 0); | ||
754 | if (rc) | ||
755 | { | ||
756 | rc = rc * 10 - 3; | ||
757 | break; | ||
758 | /* If an error occurs during multiple block writing, | ||
759 | * the STOP_TRAN token still needs to be sent. */ | ||
760 | } | ||
761 | } | ||
762 | if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK) | ||
763 | { | ||
764 | static const unsigned char stop_tran = DT_STOP_TRAN; | ||
765 | write_transfer(&stop_tran, 1); | ||
766 | poll_busy(card->write_timeout); | ||
767 | } | ||
768 | |||
769 | error: | ||
770 | |||
771 | deselect_card(); | ||
772 | |||
773 | return rc; | ||
774 | } | ||
775 | |||
776 | bool mmc_disk_is_active(void) | ||
777 | { | ||
778 | /* this is correct unless early return from write gets implemented */ | ||
779 | return mutex_test(&mmc_mutex); | ||
780 | } | ||
781 | |||
782 | bool mmc_detect(void) | ||
783 | { | ||
784 | return (adc_read(ADC_MMC_SWITCH) < 0x200); | ||
785 | } | ||
786 | |||
787 | bool mmc_touched(void) | ||
788 | { | ||
789 | if (mmc_status == MMC_UNKNOWN) /* try to detect */ | ||
790 | { | ||
791 | mutex_lock(&mmc_mutex); | ||
792 | setup_sci1(7); /* safe value */ | ||
793 | and_b(~0x02, &PADRH); /* assert CS */ | ||
794 | if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0xFF) | ||
795 | mmc_status = MMC_UNTOUCHED; | ||
796 | else | ||
797 | mmc_status = MMC_TOUCHED; | ||
798 | |||
799 | deselect_card(); | ||
800 | } | ||
801 | return mmc_status == MMC_TOUCHED; | ||
802 | } | ||
803 | |||
804 | bool mmc_usb_active(int delayticks) | ||
805 | { | ||
806 | /* reading "inactive" is delayed by user-supplied monoflop value */ | ||
807 | return (usb_activity || | ||
808 | TIME_BEFORE(current_tick, last_usb_activity + delayticks)); | ||
809 | } | ||
810 | |||
811 | static void mmc_tick(void) | ||
812 | { | ||
813 | bool current_status; | ||
814 | |||
815 | if (new_mmc_circuit) | ||
816 | /* USB bridge activity is 0 on idle, ~527 on active */ | ||
817 | current_status = adc_read(ADC_USB_ACTIVE) > 0x100; | ||
818 | else | ||
819 | current_status = adc_read(ADC_USB_ACTIVE) < 0x190; | ||
820 | |||
821 | if (!current_status && usb_activity) | ||
822 | last_usb_activity = current_tick; | ||
823 | usb_activity = current_status; | ||
824 | |||
825 | current_status = mmc_detect(); | ||
826 | /* Only report when the status has changed */ | ||
827 | if (current_status != last_mmc_status) | ||
828 | { | ||
829 | last_mmc_status = current_status; | ||
830 | countdown = HZ/3; | ||
831 | } | ||
832 | else | ||
833 | { | ||
834 | /* Count down until it gets negative */ | ||
835 | if (countdown >= 0) | ||
836 | countdown--; | ||
837 | |||
838 | if (countdown == 0) | ||
839 | { | ||
840 | if (current_status) | ||
841 | { | ||
842 | queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1); | ||
843 | } | ||
844 | else | ||
845 | { | ||
846 | queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1); | ||
847 | mmc_status = MMC_UNTOUCHED; | ||
848 | card_info[1].initialized = false; | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | } | ||
853 | |||
854 | void mmc_enable(bool on) | ||
855 | { | ||
856 | mutex_lock(&mmc_mutex); | ||
857 | enable_controller(on); | ||
858 | mutex_unlock(&mmc_mutex); | ||
859 | } | ||
860 | |||
861 | int mmc_init(void) | ||
862 | { | ||
863 | int rc = 0; | ||
864 | |||
865 | if (!initialized) | ||
866 | mutex_init(&mmc_mutex); | ||
867 | |||
868 | mutex_lock(&mmc_mutex); | ||
869 | led(false); | ||
870 | |||
871 | last_mmc_status = mmc_detect(); | ||
872 | #ifndef HAVE_MULTIDRIVE | ||
873 | /* Use MMC if inserted, internal flash otherwise */ | ||
874 | current_card = last_mmc_status ? 1 : 0; | ||
875 | #endif | ||
876 | |||
877 | if (!initialized) | ||
878 | { | ||
879 | if (!last_mmc_status) | ||
880 | mmc_status = MMC_UNTOUCHED; | ||
881 | |||
882 | /* Port setup */ | ||
883 | PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12 | ||
884 | * (clk gate), PA10 (flash CS), PA9 (MMC CS) */ | ||
885 | PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */ | ||
886 | PADR |= 0x0680; /* set all the selects + reset high (=inactive) */ | ||
887 | PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */ | ||
888 | |||
889 | PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */ | ||
890 | PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */ | ||
891 | PBIOR |= 0x2000; /* SCK1 output */ | ||
892 | PBIOR &= ~0x0C00; /* TxD1, RxD1 input */ | ||
893 | |||
894 | IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ | ||
895 | |||
896 | new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); | ||
897 | tick_add_task(mmc_tick); | ||
898 | initialized = true; | ||
899 | } | ||
900 | enable_controller(true); | ||
901 | |||
902 | mutex_unlock(&mmc_mutex); | ||
903 | return rc; | ||
904 | } | ||
905 | |||
906 | long mmc_last_disk_activity(void) | ||
907 | { | ||
908 | return last_disk_activity; | ||
909 | } | ||
910 | |||
911 | #ifdef STORAGE_GET_INFO | ||
912 | void mmc_get_info(IF_MD(int drive,) struct storage_info *info) | ||
913 | { | ||
914 | #ifndef HAVE_MULTIDRIVE | ||
915 | const int drive=0; | ||
916 | #endif | ||
917 | info->sector_size=card_info[drive].blocksize; | ||
918 | info->num_sectors=card_info[drive].numblocks; | ||
919 | info->vendor="Rockbox"; | ||
920 | if(drive==0) | ||
921 | { | ||
922 | info->product="Internal Storage"; | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | info->product="MMC Card Slot"; | ||
927 | } | ||
928 | info->revision="0.00"; | ||
929 | } | ||
930 | #endif | ||
931 | |||
932 | #ifdef HAVE_HOTSWAP | ||
933 | bool mmc_removable(IF_MD_NONVOID(int drive)) | ||
934 | { | ||
935 | #ifndef HAVE_MULTIDRIVE | ||
936 | const int drive=0; | ||
937 | #endif | ||
938 | return (drive==1); | ||
939 | } | ||
940 | |||
941 | bool mmc_present(IF_MD_NONVOID(int drive)) | ||
942 | { | ||
943 | #ifndef HAVE_MULTIDRIVE | ||
944 | const int drive=0; | ||
945 | #endif | ||
946 | if(drive==0) | ||
947 | { | ||
948 | return true; | ||
949 | } | ||
950 | else | ||
951 | { | ||
952 | return mmc_detect(); | ||
953 | } | ||
954 | } | ||
955 | #endif | ||
956 | |||
957 | void mmc_spin(void) | ||
958 | { | ||
959 | } | ||
960 | |||
961 | void mmc_spindown(int seconds) | ||
962 | { | ||
963 | (void)seconds; | ||
964 | } | ||
965 | |||
966 | #ifdef CONFIG_STORAGE_MULTI | ||
967 | int mmc_num_drives(int first_drive) | ||
968 | { | ||
969 | mmc_first_drive = first_drive; | ||
970 | return MMC_NUM_DRIVES; | ||
971 | } | ||
972 | #endif /* CONFIG_STORAGE_MULTI */ | ||
973 | |||
974 | int mmc_event(long id, intptr_t data) | ||
975 | { | ||
976 | return storage_event_default_handler(id, data, last_disk_activity, | ||
977 | STORAGE_MMC); | ||
978 | } | ||
diff --git a/firmware/target/sh/archos/ondio/backlight-target.h b/firmware/target/sh/archos/ondio/backlight-target.h deleted file mode 100644 index 438c8c926a..0000000000 --- a/firmware/target/sh/archos/ondio/backlight-target.h +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef BACKLIGHT_TARGET_H | ||
22 | #define BACKLIGHT_TARGET_H | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "cpu.h" | ||
26 | |||
27 | #ifdef HAVE_BACKLIGHT | ||
28 | /* A stock Ondio has no backlight, it needs a hardware mod. */ | ||
29 | |||
30 | static inline bool backlight_hw_init(void) | ||
31 | { | ||
32 | PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */ | ||
33 | or_b(0x40, &PADRH); /* drive it high */ | ||
34 | or_b(0x40, &PAIORH); /* ..and output */ | ||
35 | return true; | ||
36 | } | ||
37 | |||
38 | static inline void backlight_hw_on(void) | ||
39 | { | ||
40 | or_b(0x40, &PADRH); /* drive it high */ | ||
41 | } | ||
42 | |||
43 | static inline void backlight_hw_off(void) | ||
44 | { | ||
45 | and_b(~0x40, &PADRH); /* drive it low */ | ||
46 | } | ||
47 | #endif /* HAVE_BACKLIGHT */ | ||
48 | |||
49 | #endif | ||
diff --git a/firmware/target/sh/archos/ondio/button-ondio.c b/firmware/target/sh/archos/ondio/button-ondio.c deleted file mode 100644 index e3b370bc1f..0000000000 --- a/firmware/target/sh/archos/ondio/button-ondio.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include "button.h" | ||
25 | #include "backlight.h" | ||
26 | #include "adc.h" | ||
27 | |||
28 | /* | ||
29 | Ondio hardware button hookup | ||
30 | ============================ | ||
31 | |||
32 | LEFT, RIGHT, UP, DOWN: connected to AN4 through a resistor network | ||
33 | |||
34 | The voltage on AN4 depends on which keys (or key combo) is pressed | ||
35 | |||
36 | OPTION: AN2, high active (assigned as MENU) | ||
37 | ON/OFF: AN3, low active (assigned as OFF) | ||
38 | */ | ||
39 | |||
40 | void button_init_device(void) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | int button_read_device(void) | ||
45 | { | ||
46 | int btn = BUTTON_NONE; | ||
47 | int data; | ||
48 | |||
49 | /* Check the 4 direction keys */ | ||
50 | data = adc_read(ADC_BUTTON_ROW1); | ||
51 | if (data >= 165) | ||
52 | { | ||
53 | if (data >= 585) | ||
54 | if (data >= 755) | ||
55 | btn = BUTTON_LEFT; | ||
56 | else | ||
57 | btn = BUTTON_RIGHT; | ||
58 | else | ||
59 | if (data >= 415) | ||
60 | btn = BUTTON_UP; | ||
61 | else | ||
62 | btn = BUTTON_DOWN; | ||
63 | } | ||
64 | |||
65 | if(adc_read(ADC_BUTTON_OPTION) > 0x200) /* active high */ | ||
66 | btn |= BUTTON_MENU; | ||
67 | if(adc_read(ADC_BUTTON_ONOFF) < 0x120) /* active low */ | ||
68 | btn |= BUTTON_OFF; | ||
69 | |||
70 | return btn; | ||
71 | } | ||
diff --git a/firmware/target/sh/archos/ondio/button-target.h b/firmware/target/sh/archos/ondio/button-target.h deleted file mode 100644 index a84be2851a..0000000000 --- a/firmware/target/sh/archos/ondio/button-target.h +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef _BUTTON_TARGET_H_ | ||
23 | #define _BUTTON_TARGET_H_ | ||
24 | |||
25 | #define BUTTON_OFF 0x00000001 | ||
26 | #define BUTTON_MENU 0x00000002 | ||
27 | |||
28 | #define BUTTON_LEFT 0x00000004 | ||
29 | #define BUTTON_RIGHT 0x00000008 | ||
30 | #define BUTTON_UP 0x00000010 | ||
31 | #define BUTTON_DOWN 0x00000020 | ||
32 | |||
33 | #define BUTTON_MAIN (BUTTON_OFF|BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT\ | ||
34 | |BUTTON_UP|BUTTON_DOWN) | ||
35 | |||
36 | #define POWEROFF_BUTTON BUTTON_OFF | ||
37 | #define POWEROFF_COUNT 10 | ||
38 | |||
39 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c b/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c deleted file mode 100644 index b901bd0019..0000000000 --- a/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * Physical interface of the Philips TEA5767 in Archos Ondio | ||
10 | * | ||
11 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "cpu.h" | ||
25 | #include "kernel.h" | ||
26 | #include "logf.h" | ||
27 | #include "system.h" | ||
28 | #include "fmradio_i2c.h" | ||
29 | |||
30 | #if (CONFIG_TUNER & TEA5767) | ||
31 | |||
32 | /* cute little functions, atomic read-modify-write */ | ||
33 | /* SDA is PB4 */ | ||
34 | #define SDA_LO and_b(~0x10, &PBDRL) | ||
35 | #define SDA_HI or_b(0x10, &PBDRL) | ||
36 | #define SDA_INPUT and_b(~0x10, &PBIORL) | ||
37 | #define SDA_OUTPUT or_b(0x10, &PBIORL) | ||
38 | #define SDA (PBDR & 0x0010) | ||
39 | |||
40 | /* SCL is PB1 */ | ||
41 | #define SCL_INPUT and_b(~0x02, &PBIORL) | ||
42 | #define SCL_OUTPUT or_b(0x02, &PBIORL) | ||
43 | #define SCL_LO and_b(~0x02, &PBDRL) | ||
44 | #define SCL_HI or_b(0x02, &PBDRL) | ||
45 | #define SCL (PBDR & 0x0002) | ||
46 | |||
47 | /* arbitrary delay loop */ | ||
48 | #define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0) | ||
49 | |||
50 | static void fmradio_i2c_start(void) | ||
51 | { | ||
52 | SDA_OUTPUT; | ||
53 | SDA_HI; | ||
54 | SCL_HI; | ||
55 | SDA_LO; | ||
56 | DELAY; | ||
57 | SCL_LO; | ||
58 | } | ||
59 | |||
60 | static void fmradio_i2c_stop(void) | ||
61 | { | ||
62 | SDA_LO; | ||
63 | SCL_HI; | ||
64 | DELAY; | ||
65 | SDA_HI; | ||
66 | } | ||
67 | |||
68 | |||
69 | static void fmradio_i2c_ack(bool nack) | ||
70 | { | ||
71 | /* Here's the deal. The slave is slow, and sometimes needs to wait | ||
72 | before it can receive the acknowledge. Therefore it forces the clock | ||
73 | low until it is ready. We need to poll the clock line until it goes | ||
74 | high before we release the ack. */ | ||
75 | |||
76 | SCL_LO; /* Set the clock low */ | ||
77 | |||
78 | if (nack) | ||
79 | SDA_HI; | ||
80 | else | ||
81 | SDA_LO; | ||
82 | |||
83 | SCL_INPUT; /* Set the clock to input */ | ||
84 | while(!SCL) /* and wait for the slave to release it */ | ||
85 | sleep(0); | ||
86 | |||
87 | DELAY; | ||
88 | SCL_OUTPUT; | ||
89 | SCL_LO; | ||
90 | } | ||
91 | |||
92 | static int fmradio_i2c_getack(void) | ||
93 | { | ||
94 | int ret = 1; | ||
95 | |||
96 | /* Here's the deal. The slave is slow, and sometimes needs to wait | ||
97 | before it can send the acknowledge. Therefore it forces the clock | ||
98 | low until it is ready. We need to poll the clock line until it goes | ||
99 | high before we read the ack. */ | ||
100 | |||
101 | SDA_INPUT; /* And set to input */ | ||
102 | SCL_INPUT; /* Set the clock to input */ | ||
103 | while(!SCL) /* and wait for the slave to release it */ | ||
104 | sleep(0); | ||
105 | |||
106 | if (SDA) | ||
107 | /* ack failed */ | ||
108 | ret = 0; | ||
109 | |||
110 | SCL_OUTPUT; | ||
111 | SCL_LO; | ||
112 | SDA_HI; | ||
113 | SDA_OUTPUT; | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static void fmradio_i2c_outb(unsigned char byte) | ||
118 | { | ||
119 | int i; | ||
120 | |||
121 | /* clock out each bit, MSB first */ | ||
122 | for ( i=0x80; i; i>>=1 ) { | ||
123 | if ( i & byte ) | ||
124 | { | ||
125 | SDA_HI; | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | SDA_LO; | ||
130 | } | ||
131 | SCL_HI; | ||
132 | SCL_LO; | ||
133 | } | ||
134 | |||
135 | SDA_HI; | ||
136 | } | ||
137 | |||
138 | static unsigned char fmradio_i2c_inb(void) | ||
139 | { | ||
140 | int i; | ||
141 | unsigned char byte = 0; | ||
142 | |||
143 | /* clock in each bit, MSB first */ | ||
144 | for ( i=0x80; i; i>>=1 ) { | ||
145 | SDA_INPUT; /* And set to input */ | ||
146 | SCL_HI; | ||
147 | if ( SDA ) | ||
148 | byte |= i; | ||
149 | SCL_LO; | ||
150 | SDA_OUTPUT; | ||
151 | } | ||
152 | |||
153 | return byte; | ||
154 | } | ||
155 | |||
156 | int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) | ||
157 | { | ||
158 | int i,x=0; | ||
159 | |||
160 | fmradio_i2c_start(); | ||
161 | fmradio_i2c_outb(address & 0xfe); | ||
162 | if (fmradio_i2c_getack()) | ||
163 | { | ||
164 | for (i=0; i<count; i++) | ||
165 | { | ||
166 | fmradio_i2c_outb(buf[i]); | ||
167 | if (!fmradio_i2c_getack()) | ||
168 | { | ||
169 | x=-2; | ||
170 | break; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | logf("fmradio_i2c_write() - no ack\n"); | ||
177 | x=-1; | ||
178 | } | ||
179 | fmradio_i2c_stop(); | ||
180 | return x; | ||
181 | } | ||
182 | |||
183 | int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | ||
184 | { | ||
185 | int i,x=0; | ||
186 | |||
187 | fmradio_i2c_start(); | ||
188 | fmradio_i2c_outb(address | 1); | ||
189 | if (fmradio_i2c_getack()) { | ||
190 | for (i=count; i>0; i--) | ||
191 | { | ||
192 | *buf++ = fmradio_i2c_inb(); | ||
193 | fmradio_i2c_ack(i == 1); | ||
194 | } | ||
195 | } | ||
196 | else | ||
197 | x=-1; | ||
198 | fmradio_i2c_stop(); | ||
199 | return x; | ||
200 | } | ||
201 | |||
202 | #endif | ||
diff --git a/firmware/target/sh/archos/ondio/power-ondio.c b/firmware/target/sh/archos/ondio/power-ondio.c deleted file mode 100644 index d7bbc08f4f..0000000000 --- a/firmware/target/sh/archos/ondio/power-ondio.c +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include <stdbool.h> | ||
24 | #include "kernel.h" | ||
25 | #include "system.h" | ||
26 | #include "power.h" | ||
27 | #include "usb.h" | ||
28 | #include "backlight-target.h" | ||
29 | |||
30 | #if CONFIG_TUNER | ||
31 | |||
32 | static bool powered = false; | ||
33 | |||
34 | bool tuner_power(bool status) | ||
35 | { | ||
36 | bool old_status = powered; | ||
37 | |||
38 | powered = status; | ||
39 | if (status) | ||
40 | { | ||
41 | and_b(~0x04, &PADRL); /* drive PA2 low for tuner enable */ | ||
42 | sleep(1); /* let the voltage settle */ | ||
43 | } | ||
44 | else | ||
45 | or_b(0x04, &PADRL); /* drive PA2 high for tuner disable */ | ||
46 | return old_status; | ||
47 | } | ||
48 | |||
49 | #endif /* #if CONFIG_TUNER */ | ||
50 | |||
51 | void power_init(void) | ||
52 | { | ||
53 | PBCR2 &= ~0x0c00; /* GPIO for PB5 */ | ||
54 | or_b(0x20, &PBIORL); | ||
55 | or_b(0x20, &PBDRL); /* hold power */ | ||
56 | #ifndef HAVE_BACKLIGHT | ||
57 | /* Disable backlight on backlight-modded Ondios when running | ||
58 | * a standard build (always on otherwise). */ | ||
59 | PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */ | ||
60 | and_b(~0x40, &PADRH); /* drive it low */ | ||
61 | or_b(0x40, &PAIORH); /* ..and output */ | ||
62 | #endif | ||
63 | PACR2 &= ~0x0030; /* GPIO for PA2 */ | ||
64 | or_b(0x04, &PADRL); /* drive PA2 high for tuner disable */ | ||
65 | or_b(0x04, &PAIORL); /* output for PA2 */ | ||
66 | } | ||
67 | |||
68 | void power_off(void) | ||
69 | { | ||
70 | disable_irq(); | ||
71 | #ifdef HAVE_BACKLIGHT | ||
72 | /* Switch off the light on backlight-modded Ondios */ | ||
73 | backlight_hw_off(); | ||
74 | #endif | ||
75 | and_b(~0x20, &PBDRL); | ||
76 | or_b(0x20, &PBIORL); | ||
77 | while(1); | ||
78 | } | ||
diff --git a/firmware/target/sh/archos/ondio/powermgmt-ondio.c b/firmware/target/sh/archos/ondio/powermgmt-ondio.c deleted file mode 100644 index dc3cab031f..0000000000 --- a/firmware/target/sh/archos/ondio/powermgmt-ondio.c +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "adc.h" | ||
25 | #include "powermgmt.h" | ||
26 | |||
27 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
28 | { | ||
29 | 3100, 3450 | ||
30 | }; | ||
31 | |||
32 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
33 | { | ||
34 | 2700, 2800 | ||
35 | }; | ||
36 | |||
37 | /* voltages (millivolt) of 0%, 10%, ... 100% */ | ||
38 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
39 | { | ||
40 | /* measured values */ | ||
41 | { 2800, 3250, 3410, 3530, 3640, 3740, 3850, 3950, 4090, 4270, 4750 }, /* Alkaline */ | ||
42 | { 3100, 3550, 3630, 3690, 3720, 3740, 3760, 3780, 3800, 3860, 4050 } /* NiMH */ | ||
43 | }; | ||
44 | |||
45 | #define BATTERY_SCALE_FACTOR 4849 /* average from 3 Ondios */ | ||
46 | /* full-scale ADC readout (2^10) in millivolt */ | ||
47 | |||
48 | /* Returns battery voltage from ADC [millivolts] */ | ||
49 | int _battery_voltage(void) | ||
50 | { | ||
51 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | ||
52 | } | ||
53 | |||
diff --git a/firmware/target/sh/archos/ondio/usb-ondio.c b/firmware/target/sh/archos/ondio/usb-ondio.c deleted file mode 100644 index 093ebd3ad8..0000000000 --- a/firmware/target/sh/archos/ondio/usb-ondio.c +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include <stdbool.h> | ||
23 | #include "adc.h" | ||
24 | #include "ata_mmc.h" | ||
25 | #include "cpu.h" | ||
26 | #include "hwcompat.h" | ||
27 | #include "system.h" | ||
28 | #include "usb.h" | ||
29 | |||
30 | int usb_detect(void) | ||
31 | { | ||
32 | return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED; | ||
33 | } | ||
34 | |||
35 | void usb_enable(bool on) | ||
36 | { | ||
37 | if (on) | ||
38 | { | ||
39 | mmc_enable_int_flash_clock(!mmc_detect()); | ||
40 | |||
41 | if (!(HW_MASK & MMC_CLOCK_POLARITY)) | ||
42 | and_b(~0x20, &PBDRH); /* old circuit needs SCK1 = low while on USB */ | ||
43 | or_b(0x20, &PADRL); /* enable USB */ | ||
44 | and_b(~0x08, &PADRL); /* assert card detect */ | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | if (!(HW_MASK & MMC_CLOCK_POLARITY)) | ||
49 | or_b(0x20, &PBDRH); /* reset SCK1 = high for old circuit */ | ||
50 | and_b(~0x20, &PADRL); /* disable USB */ | ||
51 | or_b(0x08, &PADRL); /* deassert card detect */ | ||
52 | } | ||
53 | } | ||
54 | |||
55 | void usb_init_device(void) | ||
56 | { | ||
57 | PACR2 &= ~0x04C0; /* use PA3 (card detect) and PA5 (USB enabled) as GPIO */ | ||
58 | and_b(~0x20, &PADRL); /* disable USB */ | ||
59 | or_b(0x08, &PADRL); /* deassert card detect */ | ||
60 | or_b(0x28, &PAIORL); /* output for USB enable and card detect */ | ||
61 | } | ||
diff --git a/firmware/target/sh/archos/player/adc-target.h b/firmware/target/sh/archos/player/adc-target.h deleted file mode 100644 index a26f79de28..0000000000 --- a/firmware/target/sh/archos/player/adc-target.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef _ADC_TARGET_H_ | ||
22 | #define _ADC_TARGET_H_ | ||
23 | |||
24 | #define NUM_ADC_CHANNELS 8 | ||
25 | |||
26 | #define ADC_BUTTON_LEFT 0 | ||
27 | #define ADC_BUTTON_MENU 1 | ||
28 | #define ADC_BUTTON_RIGHT 2 | ||
29 | #define ADC_BUTTON_PLAY 3 | ||
30 | #define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */ | ||
31 | #define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */ | ||
32 | |||
33 | #define EXT_SCALE_FACTOR 14800 | ||
34 | |||
35 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/player/backlight-target.h b/firmware/target/sh/archos/player/backlight-target.h deleted file mode 100644 index b97d21a40f..0000000000 --- a/firmware/target/sh/archos/player/backlight-target.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef BACKLIGHT_TARGET_H | ||
22 | #define BACKLIGHT_TARGET_H | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "cpu.h" | ||
26 | |||
27 | static inline bool backlight_hw_init(void) | ||
28 | { | ||
29 | PACR1 &= ~0x3000; /* Set PA14 (backlight control) to GPIO */ | ||
30 | and_b(~0x40, &PADRH); /* drive and set low */ | ||
31 | or_b(0x40, &PAIORH); /* ..and output */ | ||
32 | return true; | ||
33 | } | ||
34 | |||
35 | static inline void backlight_hw_on(void) | ||
36 | { | ||
37 | and_b(~0x40, &PADRH); /* drive and set low */ | ||
38 | or_b(0x40, &PAIORH); | ||
39 | } | ||
40 | |||
41 | static inline void backlight_hw_off(void) | ||
42 | { | ||
43 | and_b(~0x40, &PAIORH); /* let it float (up) */ | ||
44 | } | ||
45 | |||
46 | #endif | ||
diff --git a/firmware/target/sh/archos/player/button-player.c b/firmware/target/sh/archos/player/button-player.c deleted file mode 100644 index 3cf634853e..0000000000 --- a/firmware/target/sh/archos/player/button-player.c +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include "button.h" | ||
25 | #include "backlight.h" | ||
26 | #include "adc.h" | ||
27 | |||
28 | /* | ||
29 | Player hardware button hookup | ||
30 | ============================= | ||
31 | |||
32 | Player | ||
33 | ------ | ||
34 | LEFT: AN0 | ||
35 | MENU: AN1 | ||
36 | RIGHT: AN2 | ||
37 | PLAY: AN3 | ||
38 | |||
39 | STOP: PA11 | ||
40 | ON: PA5 | ||
41 | |||
42 | All buttons are low active | ||
43 | */ | ||
44 | |||
45 | void button_init_device(void) | ||
46 | { | ||
47 | /* set PA5 and PA11 as input pins */ | ||
48 | PACR1 &= 0xff3f; /* PA11MD = 00 */ | ||
49 | PACR2 &= 0xfbff; /* PA5MD = 0 */ | ||
50 | PAIOR &= ~0x0820; /* Inputs */ | ||
51 | } | ||
52 | |||
53 | int button_read_device(void) | ||
54 | { | ||
55 | int btn = BUTTON_NONE; | ||
56 | int data; | ||
57 | |||
58 | /* buttons are active low */ | ||
59 | if (adc_read(ADC_BUTTON_LEFT) < 0x180) | ||
60 | btn = BUTTON_LEFT; | ||
61 | if (adc_read(ADC_BUTTON_MENU) < 0x180) | ||
62 | btn |= BUTTON_MENU; | ||
63 | if (adc_read(ADC_BUTTON_RIGHT) < 0x180) | ||
64 | btn |= BUTTON_RIGHT; | ||
65 | if (adc_read(ADC_BUTTON_PLAY) < 0x180) | ||
66 | btn |= BUTTON_PLAY; | ||
67 | |||
68 | /* check port A pins for ON and STOP */ | ||
69 | data = PADR; | ||
70 | if ( !(data & 0x0020) ) | ||
71 | btn |= BUTTON_ON; | ||
72 | if ( !(data & 0x0800) ) | ||
73 | btn |= BUTTON_STOP; | ||
74 | |||
75 | return btn; | ||
76 | } | ||
diff --git a/firmware/target/sh/archos/player/button-target.h b/firmware/target/sh/archos/player/button-target.h deleted file mode 100644 index dd85d731be..0000000000 --- a/firmware/target/sh/archos/player/button-target.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef _BUTTON_TARGET_H_ | ||
23 | #define _BUTTON_TARGET_H_ | ||
24 | |||
25 | #define HAS_SERIAL_REMOTE | ||
26 | |||
27 | /* Main unit's buttons */ | ||
28 | #define BUTTON_ON 0x00000001 | ||
29 | #define BUTTON_STOP 0x00000002 | ||
30 | |||
31 | #define BUTTON_LEFT 0x00000004 | ||
32 | #define BUTTON_RIGHT 0x00000008 | ||
33 | #define BUTTON_PLAY 0x00000010 | ||
34 | #define BUTTON_MENU 0x00000020 | ||
35 | |||
36 | #define BUTTON_MAIN (BUTTON_ON|BUTTON_STOP|BUTTON_LEFT|BUTTON_RIGHT\ | ||
37 | |BUTTON_PLAY|BUTTON_MENU) | ||
38 | |||
39 | /* Remote control's buttons */ | ||
40 | #define BUTTON_RC_PLAY 0x00100000 | ||
41 | #define BUTTON_RC_STOP 0x00080000 | ||
42 | |||
43 | #define BUTTON_RC_LEFT 0x00040000 | ||
44 | #define BUTTON_RC_RIGHT 0x00020000 | ||
45 | #define BUTTON_RC_VOL_UP 0x00010000 | ||
46 | #define BUTTON_RC_VOL_DOWN 0x00008000 | ||
47 | |||
48 | #define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\ | ||
49 | |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\ | ||
50 | |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN) | ||
51 | |||
52 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/player/hwcompat-player.c b/firmware/target/sh/archos/player/hwcompat-player.c deleted file mode 100644 index 49a333d708..0000000000 --- a/firmware/target/sh/archos/player/hwcompat-player.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #include "hwcompat.h" | ||
24 | |||
25 | bool is_new_player(void) | ||
26 | { | ||
27 | return (ROM_VERSION > 449) || (ROM_VERSION == 116); | ||
28 | } | ||
diff --git a/firmware/target/sh/archos/player/lcd-as-player.S b/firmware/target/sh/archos/player/lcd-as-player.S deleted file mode 100644 index 19f812c1c7..0000000000 --- a/firmware/target/sh/archos/player/lcd-as-player.S +++ /dev/null | |||
@@ -1,274 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2004 by Jens Arnold | ||
11 | * Based on the work of Alan Korr and Jörg Hohensohn | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "cpu.h" | ||
25 | |||
26 | #define LCDR (PBDR_ADDR+1) | ||
27 | |||
28 | #define LCD_DS 1 /* PB0 = 1 --- 0001 --- LCD-DS */ | ||
29 | #define LCD_CS 2 /* PB1 = 1 --- 0010 --- /LCD-CS */ | ||
30 | #define LCD_SD 4 /* PB2 = 1 --- 0100 --- LCD-SD */ | ||
31 | #define LCD_SC 8 /* PB3 = 1 --- 1000 --- LCD-SC */ | ||
32 | |||
33 | /* | ||
34 | * About /CS,DS,SC,SD | ||
35 | * ------------------ | ||
36 | * | ||
37 | * LCD on JBP and JBR uses a SPI protocol to receive orders (SDA and SCK lines) | ||
38 | * | ||
39 | * - /CS -> Chip Selection line : | ||
40 | * 0 : LCD chipset is activated. | ||
41 | * - DS -> Data Selection line, latched at the rising edge | ||
42 | * of the 8th serial clock (*) : | ||
43 | * 0 : instruction register, | ||
44 | * 1 : data register; | ||
45 | * - SC -> Serial Clock line (SDA). | ||
46 | * - SD -> Serial Data line (SCK), latched at the rising edge | ||
47 | * of each serial clock (*). | ||
48 | * | ||
49 | * _ _ | ||
50 | * /CS \ / | ||
51 | * \______________________________________________________/ | ||
52 | * _____ ____ ____ ____ ____ ____ ____ ____ ____ _____ | ||
53 | * SD \/ D7 \/ D6 \/ D5 \/ D4 \/ D3 \/ D2 \/ D1 \/ D0 \/ | ||
54 | * _____/\____/\____/\____/\____/\____/\____/\____/\____/\_____ | ||
55 | * | ||
56 | * _____ _ _ _ _ _ _ _ ________ | ||
57 | * SC \ * \ * \ * \ * \ * \ * \ * \ * | ||
58 | * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ | ||
59 | * _ _________________________________________________________ | ||
60 | * DS \/ | ||
61 | * _/\_________________________________________________________ | ||
62 | * | ||
63 | */ | ||
64 | |||
65 | .section .icode,"ax",@progbits | ||
66 | |||
67 | .align 2 | ||
68 | .global _lcd_write_command | ||
69 | .type _lcd_write_command,@function | ||
70 | |||
71 | /* Write a command byte to the lcd controller | ||
72 | * | ||
73 | * Arguments: | ||
74 | * r4 - command byte (int) | ||
75 | * | ||
76 | * Register usage: | ||
77 | * r0 - scratch | ||
78 | * r1 - command byte (copied) | ||
79 | * r2 - precalculated port value (CS, DS and SC low, SD high) | ||
80 | * r3 - lcd port address | ||
81 | * r5 - 1 (byte count for reuse of the loop in _lcd_write_data) | ||
82 | */ | ||
83 | |||
84 | _lcd_write_command: | ||
85 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
86 | mov r4, r1 /* copy data byte to r1 */ | ||
87 | mov #0, r5 /* fake end address - stop after first iteration */ | ||
88 | |||
89 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
90 | * If so, we must disable the interrupt here. */ | ||
91 | |||
92 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
93 | or #(LCD_SD), r0 /* r0 |= LCD_SD */ | ||
94 | and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ | ||
95 | |||
96 | bra .single_transfer /* jump into the transfer loop */ | ||
97 | mov r0, r2 | ||
98 | |||
99 | |||
100 | .align 2 | ||
101 | .global _lcd_write_command_e | ||
102 | .type _lcd_write_command_e,@function | ||
103 | |||
104 | /* Write a command byte and a data byte to the lcd controller | ||
105 | * | ||
106 | * Arguments: | ||
107 | * r4 - command byte | ||
108 | * r5 - data byte | ||
109 | * | ||
110 | * Register usage: | ||
111 | * r0 - scratch | ||
112 | * r1 - command/data byte (copied) | ||
113 | * r2 - precalculated port value (CS, DS and SC low, SD high) | ||
114 | * r3 - lcd port address | ||
115 | * r5 - fake end address | ||
116 | * r6 - data byte (saved) | ||
117 | * r7 - saved pr | ||
118 | */ | ||
119 | |||
120 | _lcd_write_command_e: | ||
121 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
122 | mov r4, r1 /* copy data byte to r1 */ | ||
123 | mov r5, r6 | ||
124 | mov #0, r5 /* fake end address - stop after first iteration */ | ||
125 | |||
126 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
127 | * If so, we must disable the interrupt here. */ | ||
128 | |||
129 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
130 | or #(LCD_SD), r0 /* r0 |= LCD_SD */ | ||
131 | and #(~(LCD_CS|LCD_DS|LCD_SC)),r0 /* r0 &= ~(LCD_CS|LCD_DS|LCD_SC) */ | ||
132 | |||
133 | sts pr, r7 | ||
134 | bsr .single_transfer /* jump into the transfer loop */ | ||
135 | mov r0, r2 | ||
136 | |||
137 | lds r7, pr | ||
138 | mov r6, r1 | ||
139 | or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */ | ||
140 | and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */ | ||
141 | bra .single_transfer /* jump into the transfer loop */ | ||
142 | mov r0, r2 | ||
143 | |||
144 | |||
145 | .align 2 | ||
146 | .global _lcd_write_data | ||
147 | .type _lcd_write_data,@function | ||
148 | |||
149 | |||
150 | /* A high performance function to write data to the display, | ||
151 | * one or multiple bytes. | ||
152 | * | ||
153 | * Arguments: | ||
154 | * r4 - data address | ||
155 | * r5 - byte count | ||
156 | * | ||
157 | * Register usage: | ||
158 | * r0 - scratch | ||
159 | * r1 - current data byte | ||
160 | * r2 - precalculated port value (CS and SC low, DS and SD high) | ||
161 | * r3 - lcd port address | ||
162 | * r4 - current address | ||
163 | * r5 - end address | ||
164 | */ | ||
165 | |||
166 | _lcd_write_data: | ||
167 | mov.l .lcdr, r3 /* put lcd data port address in r3 */ | ||
168 | add r4, r5 /* end address */ | ||
169 | |||
170 | /* This code will fail if an interrupt changes the contents of PBDRL. | ||
171 | * If so, we must disable the interrupt here. If disabling interrupts | ||
172 | * for a long time (~9200 clks = ~830 µs for transferring 112 bytes on | ||
173 | * recorders)is undesirable, the loop has to be rewritten to | ||
174 | * disable/precalculate/transfer/enable for each iteration. However, | ||
175 | * this would significantly decrease performance. */ | ||
176 | |||
177 | mov.b @r3, r0 /* r0 = PBDRL */ | ||
178 | or #(LCD_DS|LCD_SD), r0 /* r0 |= LCD_DS|LCD_SD */ | ||
179 | and #(~(LCD_CS|LCD_SC)), r0 /* r0 &= ~(LCD_CS|LCD_SC) */ | ||
180 | mov r0, r2 | ||
181 | |||
182 | .align 2 | ||
183 | .multi_transfer: | ||
184 | mov.b @r4+, r1 /* load data byte from memory */ | ||
185 | |||
186 | .single_transfer: | ||
187 | shll16 r1 /* shift data to most significant byte */ | ||
188 | shll8 r1 | ||
189 | |||
190 | shll r1 /* shift the msb into carry */ | ||
191 | mov r2, r0 /* copy precalculated port value */ | ||
192 | bt 1f /* data bit = 1? */ | ||
193 | and #(~LCD_SD), r0 /* no: r0 &= ~LCD_SD */ | ||
194 | 1: | ||
195 | shll r1 /* next shift here for alignment */ | ||
196 | mov.b r0, @r3 /* set data to port */ | ||
197 | or #(LCD_SC), r0 /* rise SC (independent of SD level) */ | ||
198 | mov.b r0, @r3 /* set to port */ | ||
199 | |||
200 | mov r2, r0 | ||
201 | bt 1f | ||
202 | and #(~LCD_SD), r0 | ||
203 | 1: | ||
204 | mov.b r0, @r3 | ||
205 | or #(LCD_SC), r0 | ||
206 | mov.b r0, @r3 | ||
207 | |||
208 | shll r1 | ||
209 | mov r2, r0 | ||
210 | bt 1f | ||
211 | and #(~LCD_SD), r0 | ||
212 | 1: | ||
213 | shll r1 | ||
214 | mov.b r0, @r3 | ||
215 | or #(LCD_SC), r0 | ||
216 | mov.b r0, @r3 | ||
217 | |||
218 | mov r2, r0 | ||
219 | bt 1f | ||
220 | and #(~LCD_SD), r0 | ||
221 | 1: | ||
222 | mov.b r0, @r3 | ||
223 | or #(LCD_SC), r0 | ||
224 | mov.b r0, @r3 | ||
225 | |||
226 | shll r1 | ||
227 | mov r2, r0 | ||
228 | bt 1f | ||
229 | and #(~LCD_SD), r0 | ||
230 | 1: | ||
231 | shll r1 | ||
232 | mov.b r0, @r3 | ||
233 | or #(LCD_SC), r0 | ||
234 | mov.b r0, @r3 | ||
235 | |||
236 | mov r2, r0 | ||
237 | bt 1f | ||
238 | and #(~LCD_SD), r0 | ||
239 | 1: | ||
240 | mov.b r0, @r3 | ||
241 | or #(LCD_SC), r0 | ||
242 | mov.b r0, @r3 | ||
243 | |||
244 | shll r1 | ||
245 | mov r2, r0 | ||
246 | bt 1f | ||
247 | and #(~LCD_SD), r0 | ||
248 | 1: | ||
249 | shll r1 | ||
250 | mov.b r0, @r3 | ||
251 | or #(LCD_SC), r0 | ||
252 | mov.b r0, @r3 | ||
253 | |||
254 | mov r2, r0 | ||
255 | bt 1f | ||
256 | and #(~LCD_SD), r0 | ||
257 | 1: | ||
258 | mov.b r0, @r3 | ||
259 | or #(LCD_SC), r0 | ||
260 | mov.b r0, @r3 | ||
261 | |||
262 | cmp/hi r4, r5 /* some blocks left? */ | ||
263 | bt .multi_transfer | ||
264 | |||
265 | or #(LCD_CS|LCD_DS|LCD_SD|LCD_SC),r0 /* restore port */ | ||
266 | rts | ||
267 | mov.b r0, @r3 | ||
268 | |||
269 | /* This is the place to reenable the interrupts, if we have disabled | ||
270 | * them. See above. */ | ||
271 | |||
272 | .align 2 | ||
273 | .lcdr: | ||
274 | .long LCDR | ||
diff --git a/firmware/target/sh/archos/player/lcd-player.c b/firmware/target/sh/archos/player/lcd-player.c deleted file mode 100644 index 95b0164bf5..0000000000 --- a/firmware/target/sh/archos/player/lcd-player.c +++ /dev/null | |||
@@ -1,213 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * Based on the work of Alan Korr, Kjell Ericson and others | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include <string.h> | ||
24 | #include "config.h" | ||
25 | #include "system.h" | ||
26 | #include "kernel.h" | ||
27 | #include "hwcompat.h" | ||
28 | #include "lcd.h" | ||
29 | #include "lcd-charcell.h" | ||
30 | |||
31 | #define OLD_LCD_DDRAM ((char)0xB0) /* Display data (characters) */ | ||
32 | #define OLD_LCD_CGRAM ((char)0x80) /* Character generator (patterns) */ | ||
33 | #define OLD_LCD_ICONRAM ((char)0xE0) | ||
34 | #define OLD_LCD_CONTRAST_SET ((char)0xA8) | ||
35 | #define OLD_LCD_NOP ((char)0x00) | ||
36 | #define OLD_LCD_SYSTEM_SET ((char)0x60) | ||
37 | #define OLD_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x40) | ||
38 | #define OLD_LCD_SET_POWER_CONTROL ((char)0x50) | ||
39 | #define OLD_LCD_SET_DISPLAY_CONTROL ((char)0x30) | ||
40 | |||
41 | #define NEW_LCD_DDRAM ((char)0x80) /* Display data (characters) */ | ||
42 | #define NEW_LCD_CGRAM ((char)0xC0) /* Character generator (patterns) */ | ||
43 | #define NEW_LCD_ICONRAM ((char)0x40) | ||
44 | #define NEW_LCD_CONTRAST_SET ((char)0x50) | ||
45 | #define NEW_LCD_NOP ((char)0x00) | ||
46 | #define NEW_LCD_FUNCTION_SET ((char)0x10) | ||
47 | #define NEW_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x0c) | ||
48 | #define NEW_LCD_SET_POWER_CONTROL_REG ((char)0x20) | ||
49 | #define NEW_LCD_SET_DISPLAY_CONTROL ((char)0x28) | ||
50 | #define NEW_LCD_SET_DOUBLE_HEIGHT ((char)0x08) | ||
51 | |||
52 | #define LCD_CURSOR(x,y) ((char)(lcd_ddram+((y)*16+(x)))) | ||
53 | #define LCD_ICON(i) ((char)(lcd_iconram+i)) | ||
54 | |||
55 | static bool new_lcd; | ||
56 | static char lcd_contrast_set; | ||
57 | static char lcd_ddram; | ||
58 | static char lcd_cgram; | ||
59 | static char lcd_iconram; | ||
60 | |||
61 | /* hardware configuration */ | ||
62 | |||
63 | int lcd_default_contrast(void) | ||
64 | { | ||
65 | return 30; | ||
66 | } | ||
67 | |||
68 | void lcd_set_contrast(int val) | ||
69 | { | ||
70 | lcd_write_command_e(lcd_contrast_set, 31 - val); | ||
71 | } | ||
72 | |||
73 | /* charcell specific */ | ||
74 | |||
75 | void lcd_double_height(bool on) | ||
76 | { | ||
77 | if(new_lcd) | ||
78 | lcd_write_command(on ? (NEW_LCD_SET_DOUBLE_HEIGHT|1) | ||
79 | : NEW_LCD_SET_DOUBLE_HEIGHT); | ||
80 | } | ||
81 | |||
82 | void lcd_icon(int icon, bool enable) | ||
83 | { | ||
84 | static const struct { | ||
85 | char pos; | ||
86 | char mask; | ||
87 | } icontab[] = { | ||
88 | { 0, 0x02}, { 0, 0x08}, { 0, 0x04}, { 0, 0x10}, /* Battery */ | ||
89 | { 2, 0x04}, /* USB */ | ||
90 | { 3, 0x10}, /* Play */ | ||
91 | { 4, 0x10}, /* Record */ | ||
92 | { 5, 0x02}, /* Pause */ | ||
93 | { 5, 0x10}, /* Audio */ | ||
94 | { 6, 0x02}, /* Repeat */ | ||
95 | { 7, 0x01}, /* 1 */ | ||
96 | { 9, 0x04}, /* Volume */ | ||
97 | { 9, 0x02}, { 9, 0x01}, {10, 0x08}, {10, 0x04}, {10, 0x01}, /* Vol 1-5 */ | ||
98 | {10, 0x10}, /* Param */ | ||
99 | }; | ||
100 | static char icon_mirror[11] = {0}; | ||
101 | |||
102 | int pos, mask; | ||
103 | |||
104 | pos = icontab[icon].pos; | ||
105 | mask = icontab[icon].mask; | ||
106 | |||
107 | if (enable) | ||
108 | icon_mirror[pos] |= mask; | ||
109 | else | ||
110 | icon_mirror[pos] &= ~mask; | ||
111 | |||
112 | lcd_write_command_e(LCD_ICON(pos), icon_mirror[pos]); | ||
113 | } | ||
114 | |||
115 | /* device specific init */ | ||
116 | void lcd_init_device(void) | ||
117 | { | ||
118 | unsigned char data_vector[64]; | ||
119 | |||
120 | /* LCD init for cold start */ | ||
121 | PBCR2 &= 0xff00; /* Set PB0..PB3 to GPIO */ | ||
122 | or_b(0x0f, &PBDRL); /* ... high */ | ||
123 | or_b(0x0f, &PBIORL); /* ... and output */ | ||
124 | |||
125 | new_lcd = is_new_player(); | ||
126 | |||
127 | if (new_lcd) | ||
128 | { | ||
129 | lcd_contrast_set = NEW_LCD_CONTRAST_SET; | ||
130 | lcd_ddram = NEW_LCD_DDRAM; | ||
131 | lcd_cgram = NEW_LCD_CGRAM; | ||
132 | lcd_iconram = NEW_LCD_ICONRAM; | ||
133 | |||
134 | lcd_write_command(NEW_LCD_FUNCTION_SET|1); /* CGRAM selected */ | ||
135 | lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08); | ||
136 | lcd_write_command(NEW_LCD_SET_POWER_SAVE_OSC_CONTROL|2); | ||
137 | /* oscillator on */ | ||
138 | lcd_write_command(NEW_LCD_SET_POWER_CONTROL_REG|7); | ||
139 | /* opamp buffer + voltage booster on */ | ||
140 | |||
141 | memset(data_vector, 0x20, 64); | ||
142 | lcd_write_command(NEW_LCD_DDRAM); /* Set DDRAM address */ | ||
143 | lcd_write_data(data_vector, 64); /* all spaces */ | ||
144 | |||
145 | memset(data_vector, 0, 64); | ||
146 | lcd_write_command(NEW_LCD_CGRAM); /* Set CGRAM address */ | ||
147 | lcd_write_data(data_vector, 64); /* zero out */ | ||
148 | lcd_write_command(NEW_LCD_ICONRAM); /* Set ICONRAM address */ | ||
149 | lcd_write_data(data_vector, 16); /* zero out */ | ||
150 | |||
151 | lcd_write_command(NEW_LCD_SET_DISPLAY_CONTROL|1); /* display on */ | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | lcd_contrast_set = OLD_LCD_CONTRAST_SET; | ||
156 | lcd_ddram = OLD_LCD_DDRAM; | ||
157 | lcd_cgram = OLD_LCD_CGRAM; | ||
158 | lcd_iconram = OLD_LCD_ICONRAM; | ||
159 | |||
160 | lcd_write_command(OLD_LCD_NOP); | ||
161 | lcd_write_command(OLD_LCD_SYSTEM_SET|1); /* CGRAM selected */ | ||
162 | lcd_write_command(OLD_LCD_SET_POWER_SAVE_OSC_CONTROL|2); | ||
163 | /* oscillator on */ | ||
164 | lcd_write_command(OLD_LCD_SET_POWER_CONTROL|7); | ||
165 | /* voltage regulator, voltage follower and booster on */ | ||
166 | |||
167 | memset(data_vector, 0x24, 13); | ||
168 | lcd_write_command(OLD_LCD_DDRAM); /* Set DDRAM address */ | ||
169 | lcd_write_data(data_vector, 13); /* all spaces */ | ||
170 | lcd_write_command(OLD_LCD_DDRAM + 0x10); | ||
171 | lcd_write_data(data_vector, 13); | ||
172 | lcd_write_command(OLD_LCD_DDRAM + 0x20); | ||
173 | lcd_write_data(data_vector, 13); | ||
174 | |||
175 | memset(data_vector, 0, 32); | ||
176 | lcd_write_command(OLD_LCD_CGRAM); /* Set CGRAM address */ | ||
177 | lcd_write_data(data_vector, 32); /* zero out */ | ||
178 | lcd_write_command(OLD_LCD_ICONRAM); /* Set ICONRAM address */ | ||
179 | lcd_write_data(data_vector, 13); /* zero out */ | ||
180 | lcd_write_command(OLD_LCD_ICONRAM + 0x10); | ||
181 | lcd_write_data(data_vector, 13); | ||
182 | |||
183 | sleep(HZ/10); | ||
184 | lcd_write_command(OLD_LCD_SET_DISPLAY_CONTROL|1); /* display on */ | ||
185 | } | ||
186 | lcd_set_contrast(lcd_default_contrast()); | ||
187 | } | ||
188 | |||
189 | /*** Update functions ***/ | ||
190 | |||
191 | void lcd_update(void) | ||
192 | { | ||
193 | int y; | ||
194 | |||
195 | for (y = 0; y < lcd_pattern_count; y++) | ||
196 | { | ||
197 | if (lcd_patterns[y].count > 0) | ||
198 | { | ||
199 | lcd_write_command(lcd_cgram | (y << 3)); | ||
200 | lcd_write_data(lcd_patterns[y].pattern, 7); | ||
201 | } | ||
202 | } | ||
203 | for (y = 0; y < LCD_HEIGHT; y++) | ||
204 | { | ||
205 | lcd_write_command(LCD_CURSOR(0, y)); | ||
206 | lcd_write_data(lcd_charbuffer[y], LCD_WIDTH); | ||
207 | } | ||
208 | if (lcd_cursor.visible) | ||
209 | { | ||
210 | lcd_write_command_e(LCD_CURSOR(lcd_cursor.x, lcd_cursor.y), | ||
211 | lcd_cursor.hw_char); | ||
212 | } | ||
213 | } | ||
diff --git a/firmware/target/sh/archos/player/power-player.c b/firmware/target/sh/archos/player/power-player.c deleted file mode 100644 index 33f5959021..0000000000 --- a/firmware/target/sh/archos/player/power-player.c +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include <stdbool.h> | ||
24 | #include "kernel.h" | ||
25 | #include "system.h" | ||
26 | #include "power.h" | ||
27 | #include "usb.h" | ||
28 | |||
29 | void power_init(void) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | unsigned int power_input_status(void) | ||
34 | { | ||
35 | /* Player */ | ||
36 | return ((PADR & 1) == 0) ? | ||
37 | POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE; | ||
38 | } | ||
39 | |||
40 | void ide_power_enable(bool on) | ||
41 | { | ||
42 | bool touched = false; | ||
43 | |||
44 | if(on) | ||
45 | { | ||
46 | or_b(0x10, &PBDRL); | ||
47 | touched = true; | ||
48 | } | ||
49 | #ifdef HAVE_ATA_POWER_OFF | ||
50 | if(!on) | ||
51 | { | ||
52 | and_b(~0x10, &PBDRL); | ||
53 | touched = true; | ||
54 | } | ||
55 | #endif /* HAVE_ATA_POWER_OFF */ | ||
56 | |||
57 | /* late port preparation, else problems with read/modify/write | ||
58 | of other bits on same port, while input and floating high */ | ||
59 | if (touched) | ||
60 | { | ||
61 | or_b(0x10, &PBIORL); /* PB4 is an output */ | ||
62 | PBCR2 &= ~0x0300; /* GPIO for PB4 */ | ||
63 | } | ||
64 | } | ||
65 | |||
66 | |||
67 | bool ide_powered(void) | ||
68 | { | ||
69 | /* This is not correct for very old players, since these are unable to | ||
70 | * control hd power. However, driving the pin doesn't hurt, because it | ||
71 | * is not connected anywhere */ | ||
72 | if ((PBCR2 & 0x0300) || !(PBIORL & 0x10)) /* not configured for output */ | ||
73 | return false; /* would be floating low, disk off */ | ||
74 | else | ||
75 | return (PBDRL & 0x10) != 0; | ||
76 | } | ||
77 | |||
78 | void power_off(void) | ||
79 | { | ||
80 | disable_irq(); | ||
81 | and_b(~0x08, &PADRH); | ||
82 | or_b(0x08, &PAIORH); | ||
83 | while(1); | ||
84 | } | ||
diff --git a/firmware/target/sh/archos/player/powermgmt-player.c b/firmware/target/sh/archos/player/powermgmt-player.c deleted file mode 100644 index 8aa03d88a5..0000000000 --- a/firmware/target/sh/archos/player/powermgmt-player.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "adc.h" | ||
25 | #include "powermgmt.h" | ||
26 | |||
27 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
28 | { | ||
29 | 4750 | ||
30 | }; | ||
31 | |||
32 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
33 | { | ||
34 | 4400 | ||
35 | }; | ||
36 | |||
37 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
38 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
39 | { | ||
40 | /* original values were taken directly after charging, but it should show | ||
41 | 100% after turning off the device for some hours, too */ | ||
42 | { 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 } | ||
43 | /* orig. values: ...,5280,5600 */ | ||
44 | }; | ||
45 | |||
46 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
47 | const unsigned short percent_to_volt_charge[11] = | ||
48 | { | ||
49 | /* values guessed, see | ||
50 | http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone | ||
51 | measures voltages over a charging cycle */ | ||
52 | 4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */ | ||
53 | }; | ||
54 | |||
55 | #define BATTERY_SCALE_FACTOR 6703 | ||
56 | /* full-scale ADC readout (2^10) in millivolt */ | ||
57 | |||
58 | /* Returns battery voltage from ADC [millivolts] */ | ||
59 | int _battery_voltage(void) | ||
60 | { | ||
61 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | ||
62 | } | ||
63 | |||
64 | |||
diff --git a/firmware/target/sh/archos/player/usb-player.c b/firmware/target/sh/archos/player/usb-player.c deleted file mode 100644 index 76f2a2dcdd..0000000000 --- a/firmware/target/sh/archos/player/usb-player.c +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include <stdbool.h> | ||
23 | #include "cpu.h" | ||
24 | #include "system.h" | ||
25 | #include "usb.h" | ||
26 | |||
27 | int usb_detect(void) | ||
28 | { | ||
29 | return (PADR & 0x8000) ? USB_EXTRACTED : USB_INSERTED; | ||
30 | } | ||
31 | |||
32 | void usb_enable(bool on) | ||
33 | { | ||
34 | if(on) | ||
35 | and_b(~0x04, &PADRH); | ||
36 | else | ||
37 | or_b(0x04, &PADRH); | ||
38 | } | ||
39 | |||
40 | void usb_init_device(void) | ||
41 | { | ||
42 | or_b(0x04, &PADRH); | ||
43 | or_b(0x04, &PAIORH); | ||
44 | } | ||
diff --git a/firmware/target/sh/archos/recorder/adc-target.h b/firmware/target/sh/archos/recorder/adc-target.h deleted file mode 100644 index 06c48a5021..0000000000 --- a/firmware/target/sh/archos/recorder/adc-target.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef _ADC_TARGET_H_ | ||
22 | #define _ADC_TARGET_H_ | ||
23 | |||
24 | #define NUM_ADC_CHANNELS 8 | ||
25 | |||
26 | /* normal JBR channel assignment */ | ||
27 | #define ADC_BATTERY 0 /* Battery voltage always reads 0x3FF due to | ||
28 | silly scaling */ | ||
29 | #define ADC_CHARGE_REGULATOR 1 /* Regulator reference voltage, should read | ||
30 | about 0x1c0 when charging, else 0x3FF */ | ||
31 | #define ADC_USB_POWER 2 /* USB, reads 0x3FF when USB is inserted */ | ||
32 | #define ADC_BUTTON_ROW1 4 /* Used for scanning the keys, different | ||
33 | voltages for different keys */ | ||
34 | #define ADC_BUTTON_ROW2 5 /* Used for scanning the keys, different | ||
35 | voltages for different keys */ | ||
36 | #define ADC_UNREG_POWER 6 /* Battery voltage with a better scaling */ | ||
37 | #define ADC_EXT_POWER 7 /* The external power voltage, 0v or 2.7v */ | ||
38 | |||
39 | #define EXT_SCALE_FACTOR 14800 | ||
40 | |||
41 | #endif /* _ADC_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/recorder/backlight-target.h b/firmware/target/sh/archos/recorder/backlight-target.h deleted file mode 100644 index c3dd395eca..0000000000 --- a/firmware/target/sh/archos/recorder/backlight-target.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef BACKLIGHT_TARGET_H | ||
22 | #define BACKLIGHT_TARGET_H | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "rtc.h" | ||
26 | |||
27 | #define backlight_hw_init() true | ||
28 | |||
29 | static inline void backlight_hw_on(void) | ||
30 | { | ||
31 | rtc_write(0x13, 0x10); /* 32 kHz square wave */ | ||
32 | rtc_write(0x0a, rtc_read(0x0a) | 0x40); /* Enable square wave */ | ||
33 | } | ||
34 | |||
35 | static inline void backlight_hw_off(void) | ||
36 | { | ||
37 | /* While on, backlight is flashing at 32 kHz. If the square wave output | ||
38 | is disabled while the backlight is lit, it will become constantly lit, | ||
39 | (brighter) and slowly fade. This resets the square wave counter and | ||
40 | results in the unlit state */ | ||
41 | unsigned char rtc_0a = rtc_read(0x0a) & ~0x40; | ||
42 | rtc_write(0x0a, rtc_0a); /* Disable square wave */ | ||
43 | rtc_write(0x13, 0xF0); /* 1 Hz square wave */ | ||
44 | rtc_write(0x0a, rtc_0a | 0x40); /* Enable square wave */ | ||
45 | |||
46 | /* When the square wave output is disabled in the unlit state, | ||
47 | the backlight stays off */ | ||
48 | rtc_write(0x0a, rtc_0a); | ||
49 | } | ||
50 | |||
51 | #endif | ||
diff --git a/firmware/target/sh/archos/recorder/button-recorder.c b/firmware/target/sh/archos/recorder/button-recorder.c deleted file mode 100644 index 5e5e67487d..0000000000 --- a/firmware/target/sh/archos/recorder/button-recorder.c +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include "button.h" | ||
25 | #include "backlight.h" | ||
26 | #include "adc.h" | ||
27 | |||
28 | /* | ||
29 | Recorder hardware button hookup | ||
30 | =============================== | ||
31 | |||
32 | F1, F2, F3, UP: connected to AN4 through a resistor network | ||
33 | DOWN, PLAY, LEFT, RIGHT: likewise connected to AN5 | ||
34 | |||
35 | The voltage on AN4/ AN5 depends on which keys (or key combo) is pressed | ||
36 | |||
37 | ON: PB8, low active | ||
38 | OFF: PB4, low active | ||
39 | */ | ||
40 | |||
41 | void button_init_device(void) | ||
42 | { | ||
43 | /* Set PB4 and PB8 as input pins */ | ||
44 | PBCR1 &= 0xfffc; /* PB8MD = 00 */ | ||
45 | PBCR2 &= 0xfcff; /* PB4MD = 00 */ | ||
46 | PBIOR &= ~0x0110; /* Inputs */ | ||
47 | } | ||
48 | |||
49 | int button_read_device(void) | ||
50 | { | ||
51 | int btn = BUTTON_NONE; | ||
52 | int data; | ||
53 | static int off_button_count = 0; | ||
54 | |||
55 | /* check F1..F3 and UP */ | ||
56 | data = adc_read(ADC_BUTTON_ROW1); | ||
57 | if (data >= 250) | ||
58 | { | ||
59 | if (data >= 700) | ||
60 | if (data >= 900) | ||
61 | btn = BUTTON_F3; | ||
62 | else | ||
63 | btn = BUTTON_UP; | ||
64 | else | ||
65 | if (data >= 500) | ||
66 | btn = BUTTON_F2; | ||
67 | else | ||
68 | btn = BUTTON_F1; | ||
69 | } | ||
70 | |||
71 | /* Some units have mushy keypads, so pressing UP also activates | ||
72 | the Left/Right buttons. Let's combat that by skipping the AN5 | ||
73 | checks when UP is pressed. */ | ||
74 | if(!(btn & BUTTON_UP)) | ||
75 | { | ||
76 | /* check DOWN, PLAY, LEFT, RIGHT */ | ||
77 | data = adc_read(ADC_BUTTON_ROW2); | ||
78 | if (data >= 250) | ||
79 | { | ||
80 | if (data >= 700) | ||
81 | if (data >= 900) | ||
82 | btn |= BUTTON_DOWN; | ||
83 | else | ||
84 | btn |= BUTTON_PLAY; | ||
85 | else | ||
86 | if (data >= 500) | ||
87 | btn |= BUTTON_LEFT; | ||
88 | else | ||
89 | btn |= BUTTON_RIGHT; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | /* check port B pins for ON and OFF */ | ||
94 | data = PBDR; | ||
95 | if ((data & 0x0100) == 0) | ||
96 | btn |= BUTTON_ON; | ||
97 | |||
98 | if ((data & 0x0010) == 0) | ||
99 | { | ||
100 | /* When the batteries are low, the low-battery shutdown logic causes | ||
101 | * spurious OFF events due to voltage fluctuation on some units. | ||
102 | * Only accept OFF when read several times in sequence. */ | ||
103 | if (++off_button_count > 3) | ||
104 | btn |= BUTTON_OFF; | ||
105 | } | ||
106 | else | ||
107 | off_button_count = 0; | ||
108 | |||
109 | return btn; | ||
110 | } | ||
diff --git a/firmware/target/sh/archos/recorder/button-target.h b/firmware/target/sh/archos/recorder/button-target.h deleted file mode 100644 index f387fafe10..0000000000 --- a/firmware/target/sh/archos/recorder/button-target.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef _BUTTON_TARGET_H_ | ||
23 | #define _BUTTON_TARGET_H_ | ||
24 | |||
25 | #define HAS_SERIAL_REMOTE | ||
26 | |||
27 | /* Main unit's buttons */ | ||
28 | #define BUTTON_ON 0x00000001 | ||
29 | #define BUTTON_OFF 0x00000002 | ||
30 | |||
31 | #define BUTTON_LEFT 0x00000004 | ||
32 | #define BUTTON_RIGHT 0x00000008 | ||
33 | #define BUTTON_UP 0x00000010 | ||
34 | #define BUTTON_DOWN 0x00000020 | ||
35 | |||
36 | #define BUTTON_PLAY 0x00000040 | ||
37 | |||
38 | #define BUTTON_F1 0x00000080 | ||
39 | #define BUTTON_F2 0x00000100 | ||
40 | #define BUTTON_F3 0x00000200 | ||
41 | |||
42 | #define BUTTON_MAIN (BUTTON_ON|BUTTON_OFF|BUTTON_LEFT|BUTTON_RIGHT\ | ||
43 | |BUTTON_UP|BUTTON_DOWN|BUTTON_PLAY\ | ||
44 | |BUTTON_F1|BUTTON_F2|BUTTON_F3) | ||
45 | |||
46 | /* Remote control's buttons */ | ||
47 | #define BUTTON_RC_PLAY 0x00100000 | ||
48 | #define BUTTON_RC_STOP 0x00080000 | ||
49 | |||
50 | #define BUTTON_RC_LEFT 0x00040000 | ||
51 | #define BUTTON_RC_RIGHT 0x00020000 | ||
52 | #define BUTTON_RC_VOL_UP 0x00010000 | ||
53 | #define BUTTON_RC_VOL_DOWN 0x00008000 | ||
54 | |||
55 | #define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\ | ||
56 | |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\ | ||
57 | |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN) | ||
58 | |||
59 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/sh/archos/recorder/power-recorder.c b/firmware/target/sh/archos/recorder/power-recorder.c deleted file mode 100644 index 48cfdc1e17..0000000000 --- a/firmware/target/sh/archos/recorder/power-recorder.c +++ /dev/null | |||
@@ -1,107 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include "cpu.h" | ||
23 | #include <stdbool.h> | ||
24 | #include "adc.h" | ||
25 | #include "kernel.h" | ||
26 | #include "system.h" | ||
27 | #include "power.h" | ||
28 | #include "powermgmt-target.h" | ||
29 | #include "usb.h" | ||
30 | |||
31 | static bool charger_on; | ||
32 | |||
33 | void power_init(void) | ||
34 | { | ||
35 | PBCR2 &= ~0x0c00; /* GPIO for PB5 */ | ||
36 | or_b(0x20, &PBIORL); /* Set charging control bit to output */ | ||
37 | charger_enable(false); /* Default to charger OFF */ | ||
38 | } | ||
39 | |||
40 | unsigned int power_input_status(void) | ||
41 | { | ||
42 | /* Recorder */ | ||
43 | return (adc_read(ADC_EXT_POWER) > 0x100) ? | ||
44 | POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE; | ||
45 | } | ||
46 | |||
47 | void charger_enable(bool on) | ||
48 | { | ||
49 | if(on) | ||
50 | { | ||
51 | and_b(~0x20, &PBDRL); | ||
52 | } | ||
53 | else | ||
54 | { | ||
55 | or_b(0x20, &PBDRL); | ||
56 | } | ||
57 | |||
58 | charger_on = on; | ||
59 | } | ||
60 | |||
61 | bool charger_enabled(void) | ||
62 | { | ||
63 | return charger_on; | ||
64 | } | ||
65 | |||
66 | void ide_power_enable(bool on) | ||
67 | { | ||
68 | bool touched = false; | ||
69 | |||
70 | if(on) | ||
71 | { | ||
72 | or_b(0x20, &PADRL); | ||
73 | touched = true; | ||
74 | } | ||
75 | #ifdef HAVE_ATA_POWER_OFF | ||
76 | if(!on) | ||
77 | { | ||
78 | and_b(~0x20, &PADRL); | ||
79 | touched = true; | ||
80 | } | ||
81 | #endif /* HAVE_ATA_POWER_OFF */ | ||
82 | |||
83 | /* late port preparation, else problems with read/modify/write | ||
84 | of other bits on same port, while input and floating high */ | ||
85 | if (touched) | ||
86 | { | ||
87 | or_b(0x20, &PAIORL); /* PA5 is an output */ | ||
88 | PACR2 &= 0xFBFF; /* GPIO for PA5 */ | ||
89 | } | ||
90 | } | ||
91 | |||
92 | |||
93 | bool ide_powered(void) | ||
94 | { | ||
95 | if ((PACR2 & 0x0400) || !(PAIORL & 0x20)) /* not configured for output */ | ||
96 | return true; /* would be floating high, disk on */ | ||
97 | else | ||
98 | return (PADRL & 0x20) != 0; | ||
99 | } | ||
100 | |||
101 | void power_off(void) | ||
102 | { | ||
103 | disable_irq(); | ||
104 | and_b(~0x10, &PBDRL); | ||
105 | or_b(0x10, &PBIORL); | ||
106 | while(1); | ||
107 | } | ||
diff --git a/firmware/target/sh/archos/recorder/powermgmt-recorder.c b/firmware/target/sh/archos/recorder/powermgmt-recorder.c deleted file mode 100644 index ca6067a4cc..0000000000 --- a/firmware/target/sh/archos/recorder/powermgmt-recorder.c +++ /dev/null | |||
@@ -1,501 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include "config.h" | ||
23 | #include "system.h" | ||
24 | #include <stdio.h> | ||
25 | #include "debug.h" | ||
26 | #include "storage.h" | ||
27 | #include "adc.h" | ||
28 | #include "power.h" | ||
29 | #include "powermgmt.h" | ||
30 | |||
31 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
32 | { | ||
33 | 4750 | ||
34 | }; | ||
35 | |||
36 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
37 | { | ||
38 | 4400 | ||
39 | }; | ||
40 | |||
41 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
42 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
43 | { | ||
44 | /* original values were taken directly after charging, but it should show | ||
45 | 100% after turning off the device for some hours, too */ | ||
46 | { 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 } | ||
47 | /* orig. values: ...,5280,5600 */ | ||
48 | }; | ||
49 | |||
50 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
51 | const unsigned short percent_to_volt_charge[11] = | ||
52 | { | ||
53 | /* values guessed, see | ||
54 | http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone | ||
55 | measures voltages over a charging cycle */ | ||
56 | 4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */ | ||
57 | }; | ||
58 | |||
59 | #define BATTERY_SCALE_FACTOR 6620 | ||
60 | /* full-scale ADC readout (2^10) in millivolt */ | ||
61 | |||
62 | /* Returns battery voltage from ADC [millivolts] */ | ||
63 | int _battery_voltage(void) | ||
64 | { | ||
65 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | ||
66 | } | ||
67 | |||
68 | void powermgmt_init_target(void) | ||
69 | { | ||
70 | } | ||
71 | |||
72 | /** Charger control **/ | ||
73 | #ifdef CHARGING_DEBUG_FILE | ||
74 | #include "file.h" | ||
75 | #define DEBUG_FILE_NAME "/powermgmt.csv" | ||
76 | #define DEBUG_MESSAGE_LEN 133 | ||
77 | static char debug_message[DEBUG_MESSAGE_LEN]; | ||
78 | static int fd = -1; /* write debug information to this file */ | ||
79 | static int wrcount = 0; | ||
80 | #endif /* CHARGING_DEBUG_FILE */ | ||
81 | |||
82 | /* | ||
83 | * For a complete description of the charging algorithm read | ||
84 | * docs/CHARGING_ALGORITHM. | ||
85 | */ | ||
86 | int long_delta; /* long term delta battery voltage */ | ||
87 | int short_delta; /* short term delta battery voltage */ | ||
88 | static bool disk_activity_last_cycle = false; /* flag set to aid charger time | ||
89 | * calculation */ | ||
90 | char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in | ||
91 | debug menu */ | ||
92 | /* percentage at which charging | ||
93 | starts */ | ||
94 | int powermgmt_last_cycle_startstop_min = 0; /* how many minutes ago was the | ||
95 | charging started or | ||
96 | stopped? */ | ||
97 | int powermgmt_last_cycle_level = 0; /* which level had the | ||
98 | batteries at this time? */ | ||
99 | int trickle_sec = 0; /* how many seconds should the | ||
100 | charger be enabled per | ||
101 | minute for trickle | ||
102 | charging? */ | ||
103 | int pid_p = 0; /* PID proportional term */ | ||
104 | int pid_i = 0; /* PID integral term */ | ||
105 | |||
106 | static unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle | ||
107 | * voltage level */ | ||
108 | static int charge_max_time_idle = 0; /* max. charging duration, calculated at | ||
109 | * beginning of charging */ | ||
110 | static int charge_max_time_now = 0; /* max. charging duration including | ||
111 | * hdd activity */ | ||
112 | static int minutes_disk_activity = 0; /* count minutes of hdd use during | ||
113 | * charging */ | ||
114 | static int last_disk_activity = CHARGE_END_LONGD + 1; /* last hdd use x mins ago */ | ||
115 | |||
116 | #ifdef CHARGING_DEBUG_FILE | ||
117 | static void debug_file_close(void) | ||
118 | { | ||
119 | if (fd >= 0) { | ||
120 | close(fd); | ||
121 | fd = -1; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static void debug_file_log(void) | ||
126 | { | ||
127 | if (usb_inserted()) { | ||
128 | /* It is probably too late to close the file but we can try... */ | ||
129 | debug_file_close(); | ||
130 | } | ||
131 | else if (fd < 0) { | ||
132 | fd = open(DEBUG_FILE_NAME, O_WRONLY | O_APPEND | O_CREAT, 0666); | ||
133 | |||
134 | if (fd >= 0) { | ||
135 | snprintf(debug_message, DEBUG_MESSAGE_LEN, | ||
136 | "cycle_min, bat_millivolts, bat_percent, chgr_state" | ||
137 | " ,charge_state, pid_p, pid_i, trickle_sec\n"); | ||
138 | write(fd, debug_message, strlen(debug_message)); | ||
139 | wrcount = 99; /* force a flush */ | ||
140 | } | ||
141 | } | ||
142 | else { | ||
143 | snprintf(debug_message, DEBUG_MESSAGE_LEN, | ||
144 | "%d, %d, %d, %d, %d, %d, %d, %d\n", | ||
145 | powermgmt_last_cycle_startstop_min, battery_voltage(), | ||
146 | battery_level(), charger_input_state, charge_state, | ||
147 | pid_p, pid_i, trickle_sec); | ||
148 | write(fd, debug_message, strlen(debug_message)); | ||
149 | wrcount++; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | static void debug_file_sync(void) | ||
154 | { | ||
155 | /* | ||
156 | * If we have a lot of pending writes or if the disk is spining, | ||
157 | * fsync the debug log file. | ||
158 | */ | ||
159 | if (wrcount > 10 || (wrcount > 0 && storage_disk_is_active())) { | ||
160 | if (fd >= 0) | ||
161 | fsync(fd); | ||
162 | |||
163 | wrcount = 0; | ||
164 | } | ||
165 | } | ||
166 | #else /* !CHARGING_DEBUG_FILE */ | ||
167 | #define debug_file_close() | ||
168 | #define debug_file_log() | ||
169 | #define debug_file_sync() | ||
170 | #endif /* CHARGING_DEBUG_FILE */ | ||
171 | |||
172 | /* | ||
173 | * Do tasks that should be done every step. | ||
174 | */ | ||
175 | static void do_frequent_tasks(void) | ||
176 | { | ||
177 | if (storage_disk_is_active()) { | ||
178 | /* flag hdd use for charging calculation */ | ||
179 | disk_activity_last_cycle = true; | ||
180 | } | ||
181 | |||
182 | debug_file_sync(); | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * The charger was just plugged in. If the battery level is | ||
187 | * nearly charged, just trickle. If the battery is low, start | ||
188 | * a full charge cycle. If the battery level is in between, | ||
189 | * top-off and then trickle. | ||
190 | */ | ||
191 | static void charger_plugged(void) | ||
192 | { | ||
193 | int battery_percent = battery_level(); | ||
194 | |||
195 | pid_p = 0; | ||
196 | pid_i = 0; | ||
197 | powermgmt_last_cycle_level = battery_percent; | ||
198 | powermgmt_last_cycle_startstop_min = 0; | ||
199 | |||
200 | snprintf(power_message, POWER_MESSAGE_LEN, "Charger plugged in"); | ||
201 | |||
202 | if (battery_percent > START_TOPOFF_CHG) { | ||
203 | |||
204 | if (battery_percent >= START_TRICKLE_CHG) { | ||
205 | charge_state = TRICKLE; | ||
206 | target_voltage = TRICKLE_VOLTAGE; | ||
207 | } | ||
208 | else { | ||
209 | charge_state = TOPOFF; | ||
210 | target_voltage = TOPOFF_VOLTAGE; | ||
211 | } | ||
212 | } | ||
213 | else { | ||
214 | /* | ||
215 | * Start the charger full strength | ||
216 | */ | ||
217 | int i = CHARGE_MAX_MIN_1500 * get_battery_capacity() / 1500; | ||
218 | charge_max_time_idle = i * (100 + 35 - battery_percent) / 100; | ||
219 | |||
220 | if (charge_max_time_idle > i) | ||
221 | charge_max_time_idle = i; | ||
222 | |||
223 | charge_max_time_now = charge_max_time_idle; | ||
224 | |||
225 | snprintf(power_message, POWER_MESSAGE_LEN, | ||
226 | "ChgAt %d%% max %dm", battery_percent, | ||
227 | charge_max_time_now); | ||
228 | |||
229 | /* | ||
230 | * Enable the charger after the max time calc is done, | ||
231 | * because battery_level depends on if the charger is | ||
232 | * on. | ||
233 | */ | ||
234 | DEBUGF("power: charger inserted and battery" | ||
235 | " not full, charging\n"); | ||
236 | trickle_sec = 60; | ||
237 | long_delta = short_delta = 999999; | ||
238 | charge_state = CHARGING; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * The charger was just unplugged. | ||
244 | */ | ||
245 | static void charger_unplugged(void) | ||
246 | { | ||
247 | DEBUGF("power: charger disconnected, disabling\n"); | ||
248 | |||
249 | charger_enable(false); | ||
250 | powermgmt_last_cycle_level = battery_level(); | ||
251 | powermgmt_last_cycle_startstop_min = 0; | ||
252 | trickle_sec = 0; | ||
253 | pid_p = 0; | ||
254 | pid_i = 0; | ||
255 | charge_state = DISCHARGING; | ||
256 | snprintf(power_message, POWER_MESSAGE_LEN, "Charger: discharge"); | ||
257 | } | ||
258 | |||
259 | static void charging_step(void) | ||
260 | { | ||
261 | int i; | ||
262 | |||
263 | /* alter charge time max length with extra disk use */ | ||
264 | if (disk_activity_last_cycle) { | ||
265 | minutes_disk_activity++; | ||
266 | charge_max_time_now = charge_max_time_idle + | ||
267 | minutes_disk_activity*2 / 5; | ||
268 | disk_activity_last_cycle = false; | ||
269 | last_disk_activity = 0; | ||
270 | } | ||
271 | else { | ||
272 | last_disk_activity++; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Check the delta voltage over the last X minutes so we can do | ||
277 | * our end-of-charge logic based on the battery level change | ||
278 | * (no longer use minimum time as logic for charge end has 50 | ||
279 | * minutes minimum charge built in). | ||
280 | */ | ||
281 | if (powermgmt_last_cycle_startstop_min > CHARGE_END_SHORTD) { | ||
282 | short_delta = power_history[0] - | ||
283 | power_history[CHARGE_END_SHORTD - 1]; | ||
284 | } | ||
285 | |||
286 | if (powermgmt_last_cycle_startstop_min > CHARGE_END_LONGD) { | ||
287 | /* | ||
288 | * Scan the history: the points where measurement is taken need to | ||
289 | * be fairly static. Check prior to short delta 'area'. Also only | ||
290 | * check first and last 10 cycles (delta in middle OK). | ||
291 | */ | ||
292 | long_delta = power_history[0] - | ||
293 | power_history[CHARGE_END_LONGD - 1]; | ||
294 | |||
295 | for (i = CHARGE_END_SHORTD; i < CHARGE_END_SHORTD + 10; i++) | ||
296 | { | ||
297 | if ((power_history[i] - power_history[i+1]) > 50 || | ||
298 | (power_history[i] - power_history[i+1]) < -50) { | ||
299 | long_delta = 777777; | ||
300 | break; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | for (i = CHARGE_END_LONGD - 11; i < CHARGE_END_LONGD - 1 ; i++) | ||
305 | { | ||
306 | if ((power_history[i] - power_history[i+1]) > 50 || | ||
307 | (power_history[i] - power_history[i+1]) < -50) { | ||
308 | long_delta = 888888; | ||
309 | break; | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | |||
314 | snprintf(power_message, POWER_MESSAGE_LEN, | ||
315 | "Chg %dm, max %dm", powermgmt_last_cycle_startstop_min, | ||
316 | charge_max_time_now); | ||
317 | |||
318 | /* | ||
319 | * End of charge criteria (any qualify): | ||
320 | * 1) Charged a long time | ||
321 | * 2) DeltaV went negative for a short time ( & long delta static) | ||
322 | * 3) DeltaV was negative over a longer period (no disk use only) | ||
323 | * | ||
324 | * Note: short_delta and long_delta are millivolts | ||
325 | */ | ||
326 | if (powermgmt_last_cycle_startstop_min >= charge_max_time_now || | ||
327 | (short_delta <= -50 && long_delta < 50) || | ||
328 | (long_delta < -20 && last_disk_activity > CHARGE_END_LONGD)) { | ||
329 | |||
330 | int battery_percent = battery_level(); | ||
331 | |||
332 | if (powermgmt_last_cycle_startstop_min > charge_max_time_now) { | ||
333 | DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, " | ||
334 | "enough!\n"); | ||
335 | /* | ||
336 | * Have charged too long and deltaV detection did not | ||
337 | * work! | ||
338 | */ | ||
339 | snprintf(power_message, POWER_MESSAGE_LEN, | ||
340 | "Chg tmout %d min", charge_max_time_now); | ||
341 | /* | ||
342 | * Switch to trickle charging. We skip the top-off | ||
343 | * since we've effectively done the top-off operation | ||
344 | * already since we charged for the maximum full | ||
345 | * charge time. | ||
346 | */ | ||
347 | powermgmt_last_cycle_level = battery_percent; | ||
348 | powermgmt_last_cycle_startstop_min = 0; | ||
349 | charge_state = TRICKLE; | ||
350 | |||
351 | /* | ||
352 | * Set trickle charge target to a relative voltage instead | ||
353 | * of an arbitrary value - the fully charged voltage may | ||
354 | * vary according to ambient temp, battery condition etc. | ||
355 | * Trickle target is -0.15v from full voltage acheived. | ||
356 | * Topup target is -0.05v from full voltage. | ||
357 | */ | ||
358 | target_voltage = power_history[0] - 150; | ||
359 | |||
360 | } | ||
361 | else { | ||
362 | if(short_delta <= -5) { | ||
363 | DEBUGF("power: short-term negative" | ||
364 | " delta, enough!\n"); | ||
365 | snprintf(power_message, POWER_MESSAGE_LEN, | ||
366 | "end negd %d %dmin", short_delta, | ||
367 | powermgmt_last_cycle_startstop_min); | ||
368 | target_voltage = power_history[CHARGE_END_SHORTD - 1] - 50; | ||
369 | } | ||
370 | else { | ||
371 | DEBUGF("power: long-term small " | ||
372 | "positive delta, enough!\n"); | ||
373 | snprintf(power_message, POWER_MESSAGE_LEN, | ||
374 | "end lowd %d %dmin", long_delta, | ||
375 | powermgmt_last_cycle_startstop_min); | ||
376 | target_voltage = power_history[CHARGE_END_LONGD - 1] - 50; | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * Switch to top-off charging. | ||
381 | */ | ||
382 | powermgmt_last_cycle_level = battery_percent; | ||
383 | powermgmt_last_cycle_startstop_min = 0; | ||
384 | charge_state = TOPOFF; | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | |||
389 | static void topoff_trickle_step(void) | ||
390 | { | ||
391 | unsigned int millivolts; | ||
392 | |||
393 | /* | ||
394 | *Time to switch from topoff to trickle? | ||
395 | */ | ||
396 | if (charge_state == TOPOFF && | ||
397 | powermgmt_last_cycle_startstop_min > TOPOFF_MAX_MIN) { | ||
398 | |||
399 | powermgmt_last_cycle_level = battery_level(); | ||
400 | powermgmt_last_cycle_startstop_min = 0; | ||
401 | charge_state = TRICKLE; | ||
402 | target_voltage = target_voltage - 100; | ||
403 | } | ||
404 | /* | ||
405 | * Adjust trickle charge time (proportional and integral terms). | ||
406 | * Note: I considered setting the level higher if the USB is | ||
407 | * plugged in, but it doesn't appear to be necessary and will | ||
408 | * generate more heat [gvb]. | ||
409 | */ | ||
410 | millivolts = battery_voltage(); | ||
411 | |||
412 | pid_p = ((signed)target_voltage - (signed)millivolts) / 5; | ||
413 | if (pid_p <= PID_DEADZONE && pid_p >= -PID_DEADZONE) | ||
414 | pid_p = 0; | ||
415 | |||
416 | if ((unsigned)millivolts < target_voltage) { | ||
417 | if (pid_i < 60) | ||
418 | pid_i++; /* limit so it doesn't "wind up" */ | ||
419 | } | ||
420 | else { | ||
421 | if (pid_i > 0) | ||
422 | pid_i--; /* limit so it doesn't "wind up" */ | ||
423 | } | ||
424 | |||
425 | trickle_sec = pid_p + pid_i; | ||
426 | |||
427 | if (trickle_sec > 60) | ||
428 | trickle_sec = 60; | ||
429 | |||
430 | if (trickle_sec < 0) | ||
431 | trickle_sec = 0; | ||
432 | } | ||
433 | |||
434 | void charging_algorithm_step(void) | ||
435 | { | ||
436 | static int pwm_counter = 0; /* PWM total cycle in steps */ | ||
437 | static int pwm_duty = 0; /* PWM duty cycle in steps */ | ||
438 | |||
439 | switch (charger_input_state) | ||
440 | { | ||
441 | case CHARGER_PLUGGED: | ||
442 | charger_plugged(); | ||
443 | break; | ||
444 | |||
445 | case CHARGER_UNPLUGGED: | ||
446 | charger_unplugged(); | ||
447 | break; | ||
448 | |||
449 | case CHARGER: | ||
450 | case NO_CHARGER: | ||
451 | do_frequent_tasks(); | ||
452 | |||
453 | if (pwm_counter > 0) { | ||
454 | if (pwm_duty > 0 && --pwm_duty <= 0) | ||
455 | charger_enable(false); /* Duty cycle expired */ | ||
456 | |||
457 | if (--pwm_counter > 0) | ||
458 | return; | ||
459 | |||
460 | /* PWM cycle is complete */ | ||
461 | powermgmt_last_cycle_startstop_min++; | ||
462 | debug_file_log(); | ||
463 | } | ||
464 | break; | ||
465 | } | ||
466 | |||
467 | switch (charge_state) | ||
468 | { | ||
469 | case CHARGING: | ||
470 | charging_step(); | ||
471 | break; | ||
472 | |||
473 | case TOPOFF: | ||
474 | case TRICKLE: | ||
475 | topoff_trickle_step(); | ||
476 | break; | ||
477 | |||
478 | case DISCHARGING: | ||
479 | default: | ||
480 | break; | ||
481 | } | ||
482 | |||
483 | /* If 100%, ensure pwm_on never expires and briefly disables the | ||
484 | * charger. */ | ||
485 | pwm_duty = (trickle_sec < 60) ? trickle_sec*2 : 0; | ||
486 | pwm_counter = 60*2; | ||
487 | charger_enable(trickle_sec > 0); | ||
488 | } | ||
489 | |||
490 | void charging_algorithm_close(void) | ||
491 | { | ||
492 | #ifdef CHARGING_DEBUG_FILE | ||
493 | debug_file_close(); | ||
494 | #endif /* CHARGING_DEBUG_FILE */ | ||
495 | } | ||
496 | |||
497 | /* Returns true if the unit is charging the batteries. */ | ||
498 | bool charging_state(void) | ||
499 | { | ||
500 | return charge_state == CHARGING; | ||
501 | } | ||
diff --git a/firmware/target/sh/archos/recorder/powermgmt-target.h b/firmware/target/sh/archos/recorder/powermgmt-target.h deleted file mode 100644 index 6b68d05bd4..0000000000 --- a/firmware/target/sh/archos/recorder/powermgmt-target.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #ifndef POWERMGMT_TARGET_H | ||
23 | #define POWERMGMT_TARGET_H | ||
24 | |||
25 | /* | ||
26 | * Define CHARGING_DEBUG_FILE to create a csv (spreadsheet) with battery | ||
27 | * information in it (one sample per minute/connect/disconnect). | ||
28 | * | ||
29 | * This is only for very low level debug. | ||
30 | */ | ||
31 | #undef CHARGING_DEBUG_FILE | ||
32 | |||
33 | |||
34 | /* stop when N minutes have passed with avg delta being < -0.05 V */ | ||
35 | #define CHARGE_END_SHORTD 6 | ||
36 | /* stop when N minutes have passed with avg delta being < -0.02 V */ | ||
37 | #define CHARGE_END_LONGD 50 | ||
38 | |||
39 | /* Battery % to start at top-off */ | ||
40 | #define START_TOPOFF_CHG 85 | ||
41 | /* Battery % to start at trickle */ | ||
42 | #define START_TRICKLE_CHG 95 | ||
43 | /* power thread status message */ | ||
44 | #define POWER_MESSAGE_LEN 32 | ||
45 | /* minutes: maximum charging time for 1500 mAh batteries | ||
46 | * actual max time depends also on BATTERY_CAPACITY! */ | ||
47 | #define CHARGE_MAX_MIN_1500 450 | ||
48 | /* minutes: minimum charging time */ | ||
49 | #define CHARGE_MIN_MIN 10 | ||
50 | /* After charging, go to top off charge. How long should top off charge be? */ | ||
51 | #define TOPOFF_MAX_MIN 90 | ||
52 | /* which voltage is best? (millivolts) */ | ||
53 | #define TOPOFF_VOLTAGE 5650 | ||
54 | /* After top off charge, go to trickle harge. How long should trickle | ||
55 | * charge be? */ | ||
56 | #define TRICKLE_MAX_MIN 720 /* 12 hrs */ | ||
57 | /* which voltage is best? (millivolts) */ | ||
58 | #define TRICKLE_VOLTAGE 5450 | ||
59 | /* initial trickle_sec for topoff */ | ||
60 | #define START_TOPOFF_SEC 25 | ||
61 | /* initial trickle_sec for trickle */ | ||
62 | #define START_TRICKLE_SEC 15 | ||
63 | |||
64 | #define PID_DEADZONE 4 /* PID proportional deadzone */ | ||
65 | |||
66 | extern char power_message[POWER_MESSAGE_LEN]; | ||
67 | |||
68 | extern int long_delta; /* long term delta battery voltage */ | ||
69 | extern int short_delta; /* short term delta battery voltage */ | ||
70 | |||
71 | extern int powermgmt_last_cycle_startstop_min; /* how many minutes ago was | ||
72 | the charging started or | ||
73 | stopped? */ | ||
74 | extern int powermgmt_last_cycle_level; /* which level had the batteries | ||
75 | at this time? */ | ||
76 | |||
77 | extern int pid_p; /* PID proportional term */ | ||
78 | extern int pid_i; /* PID integral term */ | ||
79 | extern int trickle_sec; /* how many seconds should the | ||
80 | charger be enabled per | ||
81 | minute for trickle | ||
82 | charging? */ | ||
83 | void charger_enable(bool on); | ||
84 | bool charger_enabled(void); | ||
85 | |||
86 | /* Battery filter lengths in samples */ | ||
87 | #define BATT_AVE_SAMPLES 32 | ||
88 | |||
89 | #endif /* POWERMGMT_TARGET_H */ | ||
diff --git a/firmware/target/sh/archos/recorder/usb-recorder.c b/firmware/target/sh/archos/recorder/usb-recorder.c deleted file mode 100644 index f8b462b802..0000000000 --- a/firmware/target/sh/archos/recorder/usb-recorder.c +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "config.h" | ||
22 | #include <stdbool.h> | ||
23 | #include "adc.h" | ||
24 | #include "cpu.h" | ||
25 | #include "hwcompat.h" | ||
26 | #include "system.h" | ||
27 | #include "usb.h" | ||
28 | |||
29 | int usb_detect(void) | ||
30 | { | ||
31 | return (adc_read(ADC_USB_POWER) > 500) ? USB_INSERTED : USB_EXTRACTED; | ||
32 | } | ||
33 | |||
34 | void usb_enable(bool on) | ||
35 | { | ||
36 | if(HW_MASK & USB_ACTIVE_HIGH) | ||
37 | on = !on; | ||
38 | |||
39 | if(on) | ||
40 | and_b(~0x04, &PADRH); /* enable USB */ | ||
41 | else | ||
42 | or_b(0x04, &PADRH); | ||
43 | } | ||
44 | |||
45 | void usb_init_device(void) | ||
46 | { | ||
47 | usb_enable(false); | ||
48 | or_b(0x04, &PAIORH); | ||
49 | } | ||
diff --git a/firmware/target/sh/archos/timer-archos.c b/firmware/target/sh/archos/timer-archos.c deleted file mode 100644 index 98a3afb4b6..0000000000 --- a/firmware/target/sh/archos/timer-archos.c +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Jens Arnold | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "cpu.h" | ||
23 | #include "system.h" | ||
24 | #include "timer.h" | ||
25 | |||
26 | void IMIA4(void) __attribute__((interrupt_handler)); | ||
27 | void IMIA4(void) | ||
28 | { | ||
29 | if (pfn_timer != NULL) | ||
30 | pfn_timer(); | ||
31 | and_b(~0x01, &TSR4); /* clear the interrupt */ | ||
32 | } | ||
33 | |||
34 | bool timer_set(long cycles, bool start) | ||
35 | { | ||
36 | int phi = 0; /* bits for the prescaler */ | ||
37 | int prescale = 1; | ||
38 | |||
39 | while (cycles > 0x10000) | ||
40 | { /* work out the smallest prescaler that makes it fit */ | ||
41 | phi++; | ||
42 | prescale <<= 1; | ||
43 | cycles >>= 1; | ||
44 | } | ||
45 | |||
46 | if (prescale > 8) | ||
47 | return false; | ||
48 | |||
49 | if (start) | ||
50 | { | ||
51 | if (pfn_unregister != NULL) | ||
52 | { | ||
53 | pfn_unregister(); | ||
54 | pfn_unregister = NULL; | ||
55 | } | ||
56 | |||
57 | and_b(~0x10, &TSTR); /* Stop the timer 4 */ | ||
58 | and_b(~0x10, &TSNC); /* No synchronization */ | ||
59 | and_b(~0x10, &TMDR); /* Operate normally */ | ||
60 | |||
61 | TIER4 = 0xF9; /* Enable GRA match interrupt */ | ||
62 | } | ||
63 | |||
64 | TCR4 = 0x20 | phi; /* clear at GRA match, set prescaler */ | ||
65 | GRA4 = (unsigned short)(cycles - 1); | ||
66 | if (start || (TCNT4 >= GRA4)) | ||
67 | TCNT4 = 0; | ||
68 | and_b(~0x01, &TSR4); /* clear an eventual interrupt */ | ||
69 | |||
70 | return true; | ||
71 | } | ||
72 | |||
73 | bool timer_start(void) | ||
74 | { | ||
75 | IPRD = (IPRD & 0xFF0F) | 1 << 4; /* interrupt priority */ | ||
76 | or_b(0x10, &TSTR); /* start timer 4 */ | ||
77 | return true; | ||
78 | } | ||
79 | |||
80 | void timer_stop(void) | ||
81 | { | ||
82 | and_b(~0x10, &TSTR); /* stop the timer 4 */ | ||
83 | IPRD = (IPRD & 0xFF0F); /* disable interrupt */ | ||
84 | } | ||
diff --git a/firmware/target/sh/archos/uart-archos.c b/firmware/target/sh/archos/uart-archos.c deleted file mode 100644 index d17678f812..0000000000 --- a/firmware/target/sh/archos/uart-archos.c +++ /dev/null | |||
@@ -1,167 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Alan Korr & Nick Robinson | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdio.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <stdarg.h> | ||
24 | |||
25 | #include "config.h" | ||
26 | #include "button.h" | ||
27 | #include "cpu.h" | ||
28 | #include "system.h" | ||
29 | #include "kernel.h" | ||
30 | #include "serial.h" | ||
31 | |||
32 | /* FIX: this doesn't work on iRiver or iPod yet */ | ||
33 | /* iFP7xx has no remote */ | ||
34 | |||
35 | /* Received byte identifiers */ | ||
36 | #define PLAY 0xC1 | ||
37 | #define STOP 0xC2 | ||
38 | #define PREV 0xC4 | ||
39 | #define NEXT 0xC8 | ||
40 | #define VOLUP 0xD0 | ||
41 | #define VOLDN 0xE0 | ||
42 | |||
43 | void serial_setup (void) | ||
44 | { | ||
45 | /* Set PB10 function to serial Rx */ | ||
46 | PBCR1 = (PBCR1 & 0xffcf) | 0x0020; | ||
47 | |||
48 | SMR1 = 0x00; | ||
49 | SCR1 = 0; | ||
50 | BRR1 = (FREQ/(32*9600))-1; | ||
51 | and_b(0, &SSR1); /* The status bits must be read before they are cleared, | ||
52 | so we do an AND operation */ | ||
53 | |||
54 | /* Let the hardware settle. The serial port needs to wait "at least | ||
55 | the interval required to transmit or receive one bit" before it | ||
56 | can be used. */ | ||
57 | sleep(1); | ||
58 | |||
59 | SCR1 = 0x10; /* Enable the receiver, no interrupt */ | ||
60 | } | ||
61 | |||
62 | int tx_rdy(void) | ||
63 | { | ||
64 | /* a dummy */ | ||
65 | return 1; | ||
66 | } | ||
67 | |||
68 | static int rx_rdy(void) | ||
69 | { | ||
70 | if(SSR1 & SCI_RDRF) | ||
71 | return 1; | ||
72 | else | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | void tx_writec(unsigned char c) | ||
77 | { | ||
78 | /* a dummy */ | ||
79 | (void)c; | ||
80 | } | ||
81 | |||
82 | static unsigned char rx_readc(void) | ||
83 | { | ||
84 | char tmp; | ||
85 | /* Read byte and clear the Rx Full bit */ | ||
86 | tmp = RDR1; | ||
87 | and_b(~SCI_RDRF, &SSR1); | ||
88 | return tmp; | ||
89 | } | ||
90 | |||
91 | |||
92 | /* This function returns the received remote control code only if it is | ||
93 | received without errors before or after the reception. | ||
94 | It therefore returns the received code on the second call after the | ||
95 | code has been received. */ | ||
96 | int remote_control_rx(void) | ||
97 | { | ||
98 | static int last_valid_button = BUTTON_NONE; | ||
99 | static int last_was_error = false; | ||
100 | int btn; | ||
101 | int ret = BUTTON_NONE; | ||
102 | |||
103 | /* Errors? Just clear'em. The receiver stops if we don't */ | ||
104 | if(SSR1 & (SCI_ORER | SCI_FER | SCI_PER)) { | ||
105 | and_b(~(SCI_ORER | SCI_FER | SCI_PER), &SSR1); | ||
106 | last_valid_button = BUTTON_NONE; | ||
107 | last_was_error = true; | ||
108 | return BUTTON_NONE; | ||
109 | } | ||
110 | |||
111 | if(rx_rdy()) { | ||
112 | btn = rx_readc(); | ||
113 | |||
114 | if(last_was_error) | ||
115 | { | ||
116 | last_valid_button = BUTTON_NONE; | ||
117 | ret = BUTTON_NONE; | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | switch (btn) | ||
122 | { | ||
123 | case STOP: | ||
124 | last_valid_button = BUTTON_RC_STOP; | ||
125 | break; | ||
126 | |||
127 | case PLAY: | ||
128 | last_valid_button = BUTTON_RC_PLAY; | ||
129 | break; | ||
130 | |||
131 | case VOLUP: | ||
132 | last_valid_button = BUTTON_RC_VOL_UP; | ||
133 | break; | ||
134 | |||
135 | case VOLDN: | ||
136 | last_valid_button = BUTTON_RC_VOL_DOWN; | ||
137 | break; | ||
138 | |||
139 | case PREV: | ||
140 | last_valid_button = BUTTON_RC_LEFT; | ||
141 | break; | ||
142 | |||
143 | case NEXT: | ||
144 | last_valid_button = BUTTON_RC_RIGHT; | ||
145 | break; | ||
146 | |||
147 | default: | ||
148 | last_valid_button = BUTTON_NONE; | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | /* This means that a valid remote control character was received | ||
156 | the last time we were called, with no receiver errors either before | ||
157 | or after. Then we can assume that there really is a remote control | ||
158 | attached, and return the button code. */ | ||
159 | ret = last_valid_button; | ||
160 | last_valid_button = BUTTON_NONE; | ||
161 | } | ||
162 | |||
163 | last_was_error = false; | ||
164 | |||
165 | return ret; | ||
166 | } | ||
167 | |||