1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "backlight.h"
38 extern int show_logo(void);
39 extern void power_off(void);
41 static void show_splash(int timeout
, const char *msg
)
44 lcd_putsxy( (LCD_WIDTH
- (SYSFONT_WIDTH
* strlen(msg
))) / 2,
45 (LCD_HEIGHT
- SYSFONT_HEIGHT
) / 2, msg
);
51 static void usb_mode(void)
57 usb_start_monitoring();
59 /* Wait for threads to connect */
60 show_splash(HZ
/2, "Waiting for USB");
64 button
= button_get_w_tmo(HZ
/2);
66 if (button
== SYS_USB_CONNECTED
)
70 if (button
== SYS_USB_CONNECTED
)
72 /* Got the message - wait for disconnect */
73 show_splash(0, "Bootloader USB mode");
75 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
79 button
= button_get(true);
80 if (button
== SYS_USB_DISCONNECTED
)
82 usb_acknowledge(SYS_USB_DISCONNECTED_ACK
);
89 static int boot_of(void)
91 int fd
, rc
, len
, i
, checksum
= 0;
92 void (*kernel_entry
)(int, void*, void*);
94 printf("Mounting disk...");
95 rc
= disk_mount_all();
97 error(EDISK
, rc
, true);
99 /* TODO: get this from the NAND flash instead of SD */
100 fd
= open("/ccpmp.bin", O_RDONLY
);
102 return EFILE_NOT_FOUND
;
104 lseek(fd
, 4, SEEK_SET
);
105 rc
= read(fd
, (char*)&len
, 4); /* CPU is LE */
107 return EREAD_IMAGE_FAILED
;
110 printf("Reading %d bytes...", len
);
112 lseek(fd
, 0, SEEK_SET
);
113 rc
= read(fd
, (void*)0x80004000, len
);
115 return EREAD_IMAGE_FAILED
;
120 checksum
+= ((unsigned char*)0x80004000)[i
];
122 *((unsigned int*)0x80004000) = checksum
;
124 printf("Starting the OF...");
126 /* OF requires all clocks on */
130 __dcache_writeback_all();
131 __icache_invalidate_all();
133 for(i
=8000; i
>0; i
--)
134 asm volatile("nop\n");
136 kernel_entry
= (void*) 0x80004008;
137 kernel_entry(0, "Jan 10 2008", "15:34:42"); /* Reversed from the SPL */
139 return 0; /* Shouldn't happen */
142 static int boot_rockbox(void)
145 void (*kernel_entry
)(void);
147 printf("Mounting disk...");
148 rc
= disk_mount_all();
150 error(EDISK
,rc
, true);
152 printf("Loading firmware...");
153 rc
= load_firmware((unsigned char *)CONFIG_SDRAM_START
, BOOTFILE
, 0x400000);
158 printf("Starting Rockbox...");
159 adc_close(); /* Disable SADC, seems to fix the re-init Rockbox does */
162 kernel_entry
= (void*) CONFIG_SDRAM_START
;
165 return 0; /* Shouldn't happen */
169 static void reset_configuration(void)
173 rc
= disk_mount_all();
175 error(EDISK
,rc
, true);
177 if(rename(ROCKBOX_DIR
"/config.cfg", ROCKBOX_DIR
"/config.old") == 0)
178 show_splash(HZ
/2, "Configuration reset successfully!");
180 show_splash(HZ
/2, "Couldn't reset configuration!");
183 #define RECT_X (LCD_WIDTH/8)
184 #define RECT_Y(i) (LCD_HEIGHT/20 + LCD_HEIGHT/10*i + RECT_HEIGHT*i)
185 #define RECT_WIDTH (LCD_WIDTH*3/4)
186 #define RECT_HEIGHT (LCD_HEIGHT/ARRAYLEN(strings) - LCD_HEIGHT/10)
187 #define TEXT_X(i) (RECT_X + RECT_WIDTH/2 - strlen(strings[i])*SYSFONT_WIDTH/2)
188 #define TEXT_Y(i) (RECT_Y(i) + RECT_HEIGHT/2 - SYSFONT_HEIGHT/2)
189 static int boot_menu(void)
191 const char* strings
[] = {"Boot Rockbox", "Boot OF", "USB mode", "Reset Rockbox configuration"};
192 int button
, touch
, poweroff_repeat
= 0;
200 for(i
=0; i
<ARRAYLEN(strings
); i
++)
202 lcd_drawrect(RECT_X
, RECT_Y(i
), RECT_WIDTH
, RECT_HEIGHT
);
203 lcd_putsxy(TEXT_X(i
), TEXT_Y(i
), strings
[i
]);
209 button
= button_get_w_tmo(HZ
/4);
210 if(button
& BUTTON_TOUCHSCREEN
)
212 touch
= button_get_data();
213 unsigned int x
= touch
& 0xFFFF, y
= touch
>> 16;
215 for(i
=0; i
<ARRAYLEN(strings
); i
++)
217 if(x
> RECT_X
&& x
< RECT_X
+RECT_WIDTH
&&
218 y
> RECT_Y(i
) && y
< RECT_Y(i
)+RECT_HEIGHT
)
239 reset_configuration();
246 else if(button
& BUTTON_POWER
)
248 if(poweroff_repeat
++ > 8)
259 #ifdef HAVE_TOUCHSCREEN
266 lcd_setfont(FONT_SYSFIXED
);
274 error(EATA
, rc
, true);
276 /* Don't mount the disks yet, there could be file system/partition errors
277 which are fixable in USB mode */
279 #ifdef HAVE_TOUCHSCREEN
280 rc
= button_read_device(&dummy
);
282 rc
= button_read_device();
289 if(rc
& BUTTON_VOL_UP
||
299 printf(MODEL_NAME
" Rockbox Bootloader");
300 printf("Version " RBVERSION
);
302 #ifdef HAS_BUTTON_HOLD
310 printf("Error: %s", strerror(rc
));