Fix remote screen check in graphic equalizer, so that it can be used on logf-enabled...
[Rockbox.git] / firmware / rolo.c
blobe977f7489fbea6416856f7e56c46f56af3b7552e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Randy D. Wood
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include "lcd.h"
22 #include "lcd-remote.h"
23 #include "kernel.h"
24 #include "sprintf.h"
25 #include "button.h"
26 #include "file.h"
27 #include "audio.h"
28 #include "system.h"
29 #include "i2c.h"
30 #include "string.h"
31 #include "buffer.h"
33 #if (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) && \
34 (CONFIG_CPU != PP5002) && !defined(IRIVER_H10) && \
35 !defined(IRIVER_H10_5GB) && (CONFIG_CPU != S3C2440)
36 /* FIX: this doesn't work on Gmini, iFP, 3rd Gen ipods, or H10 yet */
38 #define IRQ0_EDGE_TRIGGER 0x80
40 static void rolo_error(const char *text)
42 lcd_clear_display();
43 lcd_puts(0, 0, "ROLO error:");
44 lcd_puts_scroll(0, 1, text);
45 lcd_update();
46 button_get(true);
47 button_get(true);
48 button_get(true);
49 lcd_stop_scroll();
52 #if CONFIG_CPU == SH7034
53 /* these are in assembler file "descramble.S" */
54 extern unsigned short descramble(const unsigned char* source,
55 unsigned char* dest, int length);
56 extern void rolo_restart(const unsigned char* source, unsigned char* dest,
57 int length);
58 #else
59 void rolo_restart(const unsigned char* source, unsigned char* dest,
60 long length) __attribute__ ((section (".icode")));
61 void rolo_restart(const unsigned char* source, unsigned char* dest,
62 long length)
64 long i;
65 unsigned char* localdest = dest;
66 #if (CONFIG_CPU==PP5020)
67 unsigned long* memmapregs = (unsigned long*)0xf000f000;
68 #endif
70 for(i = 0;i < length;i++)
71 *localdest++ = *source++;
73 #if defined(CPU_COLDFIRE)
74 asm (
75 "movec.l %0,%%vbr \n"
76 "move.l (%0)+,%%sp \n"
77 "move.l (%0),%0 \n"
78 "jmp (%0) \n"
79 : : "a"(dest)
81 #elif (CONFIG_CPU==PP5020)
82 /* Copy a further 8KB of data to try and ensure the cache is flushed */
83 for(i = length; i < length+8192; i++)
84 *localdest++ = *source++;
86 /* Disable cache */
87 outl(0x0, 0x6000C000);
89 /* Reset the memory mapping registers to zero */
90 for (i=0;i<8;i++)
91 memmapregs[i]=0;
93 asm volatile(
94 "mov r0, #0x10000000 \n"
95 "mov pc, r0 \n"
97 #endif
99 #endif
101 /* This is assigned in the linker control file */
102 extern unsigned long loadaddress;
104 /***************************************************************************
106 * Name: rolo_load_app(char *filename,int scrambled)
107 * Filename must be a fully defined filename including the path and extension
109 ***************************************************************************/
110 int rolo_load(const char* filename)
112 int fd;
113 long length;
114 #if defined(CPU_COLDFIRE) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
115 int i;
116 unsigned long checksum,file_checksum;
117 #else
118 long file_length;
119 unsigned short checksum,file_checksum;
120 #endif
121 unsigned char* ramstart = (void*)&loadaddress;
123 lcd_clear_display();
124 lcd_puts(0, 0, "ROLO...");
125 lcd_puts(0, 1, "Loading");
126 lcd_update();
127 #ifdef HAVE_REMOTE_LCD
128 lcd_remote_clear_display();
129 lcd_remote_puts(0, 0, "ROLO...");
130 lcd_remote_puts(0, 1, "Loading");
131 lcd_remote_update();
132 #endif
134 audio_stop();
136 fd = open(filename, O_RDONLY);
137 if(-1 == fd) {
138 rolo_error("File not found");
139 return -1;
142 length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA;
144 #if defined(CPU_COLDFIRE) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
145 /* Read and save checksum */
146 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
147 if (read(fd, &file_checksum, 4) != 4) {
148 rolo_error("Error Reading checksum");
149 return -1;
152 /* Rockbox checksums are big-endian */
153 file_checksum = betoh32(file_checksum);
155 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
157 if (read(fd, audiobuf, length) != length) {
158 rolo_error("Error Reading File");
159 return -1;
162 checksum = MODEL_NUMBER;
164 for(i = 0;i < length;i++) {
165 checksum += audiobuf[i];
168 /* Verify checksum against file header */
169 if (checksum != file_checksum) {
170 rolo_error("Checksum Error");
171 return -1;
174 lcd_puts(0, 1, "Executing");
175 lcd_update();
176 #ifdef HAVE_REMOTE_LCD
177 lcd_remote_puts(0, 1, "Executing");
178 lcd_remote_update();
179 #endif
181 set_irq_level(HIGHEST_IRQ_LEVEL);
182 #elif CONFIG_CPU == SH7034
183 /* Read file length from header and compare to real file length */
184 lseek(fd, FIRMWARE_OFFSET_FILE_LENGTH, SEEK_SET);
185 if(read(fd, &file_length, 4) != 4) {
186 rolo_error("Error Reading File Length");
187 return -1;
189 if (length != file_length) {
190 rolo_error("File length mismatch");
191 return -1;
194 /* Read and save checksum */
195 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
196 if (read(fd, &file_checksum, 2) != 2) {
197 rolo_error("Error Reading checksum");
198 return -1;
200 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
202 /* verify that file can be read and descrambled */
203 if ((audiobuf + (2*length)+4) >= audiobufend) {
204 rolo_error("Not enough room to load file");
205 return -1;
208 if (read(fd, &audiobuf[length], length) != (int)length) {
209 rolo_error("Error Reading File");
210 return -1;
213 lcd_puts(0, 1, "Descramble");
214 lcd_update();
216 checksum = descramble(audiobuf + length, audiobuf, length);
218 /* Verify checksum against file header */
219 if (checksum != file_checksum) {
220 rolo_error("Checksum Error");
221 return -1;
224 lcd_puts(0, 1, "Executing ");
225 lcd_update();
227 set_irq_level(HIGHEST_IRQ_LEVEL);
229 /* Calling these 2 initialization routines was necessary to get the
230 the origional Archos version of the firmware to load and execute. */
231 system_init(); /* Initialize system for restart */
232 i2c_init(); /* Init i2c bus - it seems like a good idea */
233 ICR = IRQ0_EDGE_TRIGGER; /* Make IRQ0 edge triggered */
234 TSTR = 0xE0; /* disable all timers */
235 /* model-specific de-init, needed when flashed */
236 /* Especially the Archos software is picky about this */
237 #if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \
238 defined(ARCHOS_FMRECORDER)
239 PAIOR = 0x0FA0;
240 #endif
241 #endif
242 rolo_restart(audiobuf, ramstart, length);
244 return 0; /* this is never reached */
246 #else /* (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) */
247 int rolo_load(const char* filename)
249 /* dummy */
250 (void)filename;
251 return 0;
254 #endif /* (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) */