diff options
Diffstat (limited to 'bootloader')
-rw-r--r-- | bootloader/main.c | 523 |
1 files changed, 364 insertions, 159 deletions
diff --git a/bootloader/main.c b/bootloader/main.c index 0253a624df..01ee46c4f5 100644 --- a/bootloader/main.c +++ b/bootloader/main.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "cpu.h" | 25 | #include "cpu.h" |
26 | #include "system.h" | 26 | #include "system.h" |
27 | #include "lcd.h" | 27 | #include "lcd.h" |
28 | #include "lcd-remote.h" | ||
28 | #include "kernel.h" | 29 | #include "kernel.h" |
29 | #include "thread.h" | 30 | #include "thread.h" |
30 | #include "ata.h" | 31 | #include "ata.h" |
@@ -33,6 +34,7 @@ | |||
33 | #include "font.h" | 34 | #include "font.h" |
34 | #include "adc.h" | 35 | #include "adc.h" |
35 | #include "backlight.h" | 36 | #include "backlight.h" |
37 | #include "backlight-target.h" | ||
36 | #include "button.h" | 38 | #include "button.h" |
37 | #include "panic.h" | 39 | #include "panic.h" |
38 | #include "power.h" | 40 | #include "power.h" |
@@ -46,7 +48,13 @@ | |||
46 | 48 | ||
47 | #define DRAM_START 0x31000000 | 49 | #define DRAM_START 0x31000000 |
48 | 50 | ||
51 | |||
52 | static bool recovery_mode = false; | ||
53 | |||
49 | int line = 0; | 54 | int line = 0; |
55 | #ifdef HAVE_REMOTE_LCD | ||
56 | int remote_line = 0; | ||
57 | #endif | ||
50 | 58 | ||
51 | int usb_screen(void) | 59 | int usb_screen(void) |
52 | { | 60 | { |
@@ -57,6 +65,16 @@ char version[] = APPSVERSION; | |||
57 | 65 | ||
58 | char printfbuf[256]; | 66 | char printfbuf[256]; |
59 | 67 | ||
68 | void reset_screen(void) | ||
69 | { | ||
70 | lcd_clear_display(); | ||
71 | line = 0; | ||
72 | #ifdef HAVE_REMOTE_LCD | ||
73 | lcd_remote_clear_display(); | ||
74 | remote_line = 0; | ||
75 | #endif | ||
76 | } | ||
77 | |||
60 | void printf(const char *format, ...) | 78 | void printf(const char *format, ...) |
61 | { | 79 | { |
62 | int len; | 80 | int len; |
@@ -72,14 +90,25 @@ void printf(const char *format, ...) | |||
72 | lcd_update(); | 90 | lcd_update(); |
73 | if(line >= 16) | 91 | if(line >= 16) |
74 | line = 0; | 92 | line = 0; |
93 | #ifdef HAVE_REMOTE_LCD | ||
94 | lcd_remote_puts(0, remote_line++, ptr); | ||
95 | lcd_remote_update(); | ||
96 | if(remote_line >= 8) | ||
97 | remote_line = 0; | ||
98 | #endif | ||
75 | } | 99 | } |
76 | 100 | ||
77 | void start_iriver_fw(void) | 101 | /* Reset the cookie for the crt0 crash check */ |
102 | inline void __reset_cookie(void) | ||
78 | { | 103 | { |
79 | asm(" move.w #0x2700,%sr"); | ||
80 | /* Reset the cookie for the crt0 crash check */ | ||
81 | asm(" move.l #0,%d0"); | 104 | asm(" move.l #0,%d0"); |
82 | asm(" move.l %d0,0x10017ffc"); | 105 | asm(" move.l %d0,0x10017ffc"); |
106 | } | ||
107 | |||
108 | void start_iriver_fw(void) | ||
109 | { | ||
110 | asm(" move.w #0x2700,%sr"); | ||
111 | __reset_cookie(); | ||
83 | asm(" movec.l %d0,%vbr"); | 112 | asm(" movec.l %d0,%vbr"); |
84 | asm(" move.l 0,%sp"); | 113 | asm(" move.l 0,%sp"); |
85 | asm(" lea.l 8,%a0"); | 114 | asm(" lea.l 8,%a0"); |
@@ -108,7 +137,6 @@ int load_firmware(void) | |||
108 | len = filesize(fd) - 8; | 137 | len = filesize(fd) - 8; |
109 | 138 | ||
110 | printf("Length: %x", len); | 139 | printf("Length: %x", len); |
111 | lcd_update(); | ||
112 | 140 | ||
113 | lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); | 141 | lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); |
114 | 142 | ||
@@ -117,7 +145,6 @@ int load_firmware(void) | |||
117 | return -2; | 145 | return -2; |
118 | 146 | ||
119 | printf("Checksum: %x", chksum); | 147 | printf("Checksum: %x", chksum); |
120 | lcd_update(); | ||
121 | 148 | ||
122 | rc = read(fd, model, 4); | 149 | rc = read(fd, model, 4); |
123 | if(rc < 4) | 150 | if(rc < 4) |
@@ -143,7 +170,6 @@ int load_firmware(void) | |||
143 | } | 170 | } |
144 | 171 | ||
145 | printf("Sum: %x", sum); | 172 | printf("Sum: %x", sum); |
146 | lcd_update(); | ||
147 | 173 | ||
148 | if(sum != chksum) | 174 | if(sum != chksum) |
149 | return -5; | 175 | return -5; |
@@ -151,35 +177,286 @@ int load_firmware(void) | |||
151 | return 0; | 177 | return 0; |
152 | } | 178 | } |
153 | 179 | ||
154 | int load_flashed_rockbox(void) | 180 | void start_firmware(void) |
181 | { | ||
182 | asm(" move.w #0x2700,%sr"); | ||
183 | __reset_cookie(); | ||
184 | asm(" move.l %0,%%d0" :: "i"(DRAM_START)); | ||
185 | asm(" movec.l %d0,%vbr"); | ||
186 | asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START)); | ||
187 | asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4))); | ||
188 | asm(" jmp (%a0)"); | ||
189 | } | ||
190 | |||
191 | #ifdef IRIVER_H100_SERIES | ||
192 | void start_flashed_romimage(void) | ||
193 | { | ||
194 | uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY; | ||
195 | int *reset_vector; | ||
196 | |||
197 | if (!detect_flashed_romimage()) | ||
198 | return ; | ||
199 | |||
200 | reset_vector = (int *)(&src[sizeof(struct flash_header)+4]); | ||
201 | |||
202 | asm(" move.w #0x2700,%sr"); | ||
203 | __reset_cookie(); | ||
204 | |||
205 | asm(" move.l %0,%%d0" :: "i"(DRAM_START)); | ||
206 | asm(" movec.l %d0,%vbr"); | ||
207 | asm(" move.l %0,%%sp" :: "m"(reset_vector[0])); | ||
208 | asm(" move.l %0,%%a0" :: "m"(reset_vector[1])); | ||
209 | asm(" jmp (%a0)"); | ||
210 | |||
211 | /* Failure */ | ||
212 | power_off(); | ||
213 | } | ||
214 | |||
215 | void start_flashed_ramimage(void) | ||
155 | { | 216 | { |
156 | struct flash_header hdr; | 217 | struct flash_header hdr; |
157 | unsigned char *buf = (unsigned char *)DRAM_START; | 218 | unsigned char *buf = (unsigned char *)DRAM_START; |
158 | uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; | 219 | uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY; |
159 | 220 | ||
221 | if (!detect_flashed_ramimage()) | ||
222 | return; | ||
223 | |||
224 | /* Load firmware from flash */ | ||
160 | cpu_boost(true); | 225 | cpu_boost(true); |
161 | memcpy(&hdr, src, sizeof(struct flash_header)); | 226 | memcpy(&hdr, src, sizeof(struct flash_header)); |
162 | src += sizeof(struct flash_header); | 227 | src += sizeof(struct flash_header); |
163 | memcpy(buf, src, hdr.length); | 228 | memcpy(buf, src, hdr.length); |
164 | cpu_boost(false); | 229 | cpu_boost(false); |
230 | |||
231 | start_firmware(); | ||
165 | 232 | ||
166 | return 0; | 233 | /* Failure */ |
234 | power_off(); | ||
167 | } | 235 | } |
236 | #endif /* IRIVER_H100_SERIES */ | ||
168 | 237 | ||
238 | void shutdown(void) | ||
239 | { | ||
240 | printf("Shutting down..."); | ||
241 | #ifdef HAVE_EEPROM_SETTINGS | ||
242 | /* Reset the rockbox crash check. */ | ||
243 | firmware_settings.bl_version = 0; | ||
244 | eeprom_settings_store(); | ||
245 | #endif | ||
246 | |||
247 | /* We need to gracefully spin down the disk to prevent clicks. */ | ||
248 | if (ide_powered()) | ||
249 | { | ||
250 | /* Make sure ATA has been initialized. */ | ||
251 | ata_init(); | ||
252 | |||
253 | /* And put the disk into sleep immediately. */ | ||
254 | ata_sleepnow(); | ||
255 | } | ||
169 | 256 | ||
170 | void start_firmware(void) | 257 | sleep(HZ*2); |
258 | |||
259 | /* Backlight OFF */ | ||
260 | __backlight_off(); | ||
261 | #ifdef HAVE_REMOTE_LCD | ||
262 | __remote_backlight_off(); | ||
263 | #endif | ||
264 | |||
265 | __reset_cookie(); | ||
266 | power_off(); | ||
267 | } | ||
268 | |||
269 | /* Print the battery voltage (and a warning message). */ | ||
270 | void check_battery(void) | ||
171 | { | 271 | { |
172 | asm(" move.w #0x2700,%sr"); | 272 | int adc_battery, battery_voltage, batt_int, batt_frac; |
173 | /* Reset the cookie for the crt0 crash check */ | 273 | |
174 | asm(" move.l #0,%d0"); | 274 | adc_battery = adc_read(ADC_BATTERY); |
175 | asm(" move.l %d0,0x10017ffc"); | 275 | |
176 | asm(" move.l %0,%%d0" :: "i"(DRAM_START)); | 276 | battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000; |
177 | asm(" movec.l %d0,%vbr"); | 277 | batt_int = battery_voltage / 100; |
178 | asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START)); | 278 | batt_frac = battery_voltage % 100; |
179 | asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4))); | 279 | |
180 | asm(" jmp (%a0)"); | 280 | printf("Batt: %d.%02dV", batt_int, batt_frac); |
281 | |||
282 | if (battery_voltage <= 310) | ||
283 | { | ||
284 | printf("WARNING! BATTERY LOW!!"); | ||
285 | sleep(HZ*2); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | #ifdef HAVE_EEPROM_SETTINGS | ||
290 | void initialize_eeprom(void) | ||
291 | { | ||
292 | if (detect_original_firmware()) | ||
293 | return ; | ||
294 | |||
295 | if (!eeprom_settings_init()) | ||
296 | { | ||
297 | recovery_mode = true; | ||
298 | return ; | ||
299 | } | ||
300 | |||
301 | /* If bootloader version has not been reset, disk might | ||
302 | * not be intact. */ | ||
303 | if (firmware_settings.bl_version || !firmware_settings.disk_clean) | ||
304 | { | ||
305 | firmware_settings.disk_clean = false; | ||
306 | recovery_mode = true; | ||
307 | } | ||
308 | |||
309 | firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER; | ||
310 | eeprom_settings_store(); | ||
181 | } | 311 | } |
182 | 312 | ||
313 | void try_flashboot(void) | ||
314 | { | ||
315 | if (!firmware_settings.initialized) | ||
316 | return ; | ||
317 | |||
318 | switch (firmware_settings.bootmethod) | ||
319 | { | ||
320 | case BOOT_DISK: | ||
321 | return; | ||
322 | |||
323 | case BOOT_ROM: | ||
324 | start_flashed_romimage(); | ||
325 | recovery_mode = true; | ||
326 | break; | ||
327 | |||
328 | case BOOT_RAM: | ||
329 | start_flashed_ramimage(); | ||
330 | recovery_mode = true; | ||
331 | break; | ||
332 | |||
333 | default: | ||
334 | recovery_mode = true; | ||
335 | return; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static const char *options[] = { | ||
340 | "Boot from disk", | ||
341 | "Boot RAM image", | ||
342 | "Boot ROM image", | ||
343 | "Shutdown" | ||
344 | }; | ||
345 | |||
346 | #define FAILSAFE_OPTIONS 4 | ||
347 | void failsafe_menu(void) | ||
348 | { | ||
349 | int timeout = 15; | ||
350 | int option = 3; | ||
351 | int button; | ||
352 | int defopt = -1; | ||
353 | char buf[32]; | ||
354 | int i; | ||
355 | |||
356 | reset_screen(); | ||
357 | printf("Bootloader %s", version); | ||
358 | check_battery(); | ||
359 | printf("========================="); | ||
360 | line += FAILSAFE_OPTIONS; | ||
361 | printf(""); | ||
362 | printf(" [NAVI] to confirm."); | ||
363 | printf(" [REC] to set as default."); | ||
364 | printf(""); | ||
365 | |||
366 | if (firmware_settings.initialized) | ||
367 | { | ||
368 | defopt = firmware_settings.bootmethod; | ||
369 | if (defopt < 0 || defopt >= FAILSAFE_OPTIONS) | ||
370 | defopt = option; | ||
371 | } | ||
372 | |||
373 | while (timeout > 0) | ||
374 | { | ||
375 | /* Draw the menu. */ | ||
376 | line = 3; | ||
377 | for (i = 0; i < FAILSAFE_OPTIONS; i++) | ||
378 | { | ||
379 | char *def = "[DEF]"; | ||
380 | char *arrow = "->"; | ||
381 | |||
382 | if (i != defopt) | ||
383 | def = ""; | ||
384 | if (i != option) | ||
385 | arrow = " "; | ||
386 | |||
387 | printf("%s %s %s", arrow, options[i], def); | ||
388 | } | ||
389 | |||
390 | snprintf(buf, sizeof(buf), "Time left: %ds", timeout); | ||
391 | lcd_puts(0, 10, buf); | ||
392 | lcd_update(); | ||
393 | button = button_get_w_tmo(HZ); | ||
394 | |||
395 | if (button == BUTTON_NONE) | ||
396 | { | ||
397 | timeout--; | ||
398 | continue ; | ||
399 | } | ||
400 | |||
401 | timeout = 15; | ||
402 | /* Ignore the ON/PLAY -button because it can cause trouble | ||
403 | with the RTC alarm mod. */ | ||
404 | switch (button & ~(BUTTON_ON)) | ||
405 | { | ||
406 | case BUTTON_UP: | ||
407 | case BUTTON_RC_REW: | ||
408 | if (option > 0) | ||
409 | option--; | ||
410 | break ; | ||
411 | |||
412 | case BUTTON_DOWN: | ||
413 | case BUTTON_RC_FF: | ||
414 | if (option < FAILSAFE_OPTIONS-1) | ||
415 | option++; | ||
416 | break ; | ||
417 | |||
418 | case BUTTON_SELECT: | ||
419 | case BUTTON_RC_ON: | ||
420 | timeout = 0; | ||
421 | break ; | ||
422 | |||
423 | case BUTTON_REC: | ||
424 | case BUTTON_RC_REC: | ||
425 | if (firmware_settings.initialized) | ||
426 | { | ||
427 | firmware_settings.bootmethod = option; | ||
428 | eeprom_settings_store(); | ||
429 | defopt = option; | ||
430 | } | ||
431 | break ; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | lcd_puts(0, 10, "Executing command..."); | ||
436 | lcd_update(); | ||
437 | sleep(HZ); | ||
438 | reset_screen(); | ||
439 | |||
440 | switch (option) | ||
441 | { | ||
442 | case BOOT_DISK: | ||
443 | return ; | ||
444 | |||
445 | case BOOT_RAM: | ||
446 | start_flashed_ramimage(); | ||
447 | printf("Image not found"); | ||
448 | break; | ||
449 | |||
450 | case BOOT_ROM: | ||
451 | start_flashed_romimage(); | ||
452 | printf("Image not found"); | ||
453 | break; | ||
454 | } | ||
455 | |||
456 | shutdown(); | ||
457 | } | ||
458 | #endif | ||
459 | |||
183 | void main(void) | 460 | void main(void) |
184 | { | 461 | { |
185 | int i; | 462 | int i; |
@@ -187,8 +464,8 @@ void main(void) | |||
187 | bool rc_on_button = false; | 464 | bool rc_on_button = false; |
188 | bool on_button = false; | 465 | bool on_button = false; |
189 | bool rec_button = false; | 466 | bool rec_button = false; |
467 | bool hold_status = false; | ||
190 | int data; | 468 | int data; |
191 | int adc_battery, battery_voltage, batt_int, batt_frac; | ||
192 | 469 | ||
193 | #ifdef IAUDIO_X5 | 470 | #ifdef IAUDIO_X5 |
194 | (void)rc_on_button; | 471 | (void)rc_on_button; |
@@ -205,6 +482,9 @@ void main(void) | |||
205 | 482 | ||
206 | set_irq_level(0); | 483 | set_irq_level(0); |
207 | lcd_init(); | 484 | lcd_init(); |
485 | #ifdef HAVE_REMOTE_LCD | ||
486 | lcd_remote_init(); | ||
487 | #endif | ||
208 | backlight_init(); | 488 | backlight_init(); |
209 | font_init(); | 489 | font_init(); |
210 | adc_init(); | 490 | adc_init(); |
@@ -212,7 +492,6 @@ void main(void) | |||
212 | 492 | ||
213 | printf("Rockbox boot loader"); | 493 | printf("Rockbox boot loader"); |
214 | printf("Version %s", version); | 494 | printf("Version %s", version); |
215 | lcd_update(); | ||
216 | 495 | ||
217 | adc_battery = adc_read(ADC_BATTERY); | 496 | adc_battery = adc_read(ADC_BATTERY); |
218 | 497 | ||
@@ -221,7 +500,6 @@ void main(void) | |||
221 | batt_frac = battery_voltage % 100; | 500 | batt_frac = battery_voltage % 100; |
222 | 501 | ||
223 | printf("Batt: %d.%02dV", batt_int, batt_frac); | 502 | printf("Batt: %d.%02dV", batt_int, batt_frac); |
224 | lcd_update(); | ||
225 | 503 | ||
226 | rc = ata_init(); | 504 | rc = ata_init(); |
227 | if(rc) | 505 | if(rc) |
@@ -242,10 +520,8 @@ void main(void) | |||
242 | } | 520 | } |
243 | 521 | ||
244 | printf("Loading firmware"); | 522 | printf("Loading firmware"); |
245 | lcd_update(); | ||
246 | i = load_firmware(); | 523 | i = load_firmware(); |
247 | printf("Result: %d", i); | 524 | printf("Result: %d", i); |
248 | lcd_update(); | ||
249 | 525 | ||
250 | if(i == 0) | 526 | if(i == 0) |
251 | start_firmware(); | 527 | start_firmware(); |
@@ -275,32 +551,18 @@ void main(void) | |||
275 | 551 | ||
276 | /* Turn off if neither ON button is pressed */ | 552 | /* Turn off if neither ON button is pressed */ |
277 | if(!(on_button || rc_on_button || usb_detect())) | 553 | if(!(on_button || rc_on_button || usb_detect())) |
554 | { | ||
555 | __reset_cookie(); | ||
278 | power_off(); | 556 | power_off(); |
557 | } | ||
279 | 558 | ||
280 | /* Backlight ON */ | 559 | /* Start with the main backlight OFF. */ |
281 | or_l(0x00020000, &GPIO1_ENABLE); | 560 | __backlight_init(); |
282 | or_l(0x00020000, &GPIO1_FUNCTION); | 561 | __backlight_off(); |
283 | and_l(~0x00020000, &GPIO1_OUT); | 562 | |
284 | |||
285 | /* Remote backlight ON */ | 563 | /* Remote backlight ON */ |
286 | #ifdef HAVE_REMOTE_LCD | 564 | #ifdef HAVE_REMOTE_LCD |
287 | #ifdef IRIVER_H300_SERIES | 565 | __remote_backlight_on(); |
288 | or_l(0x00000002, &GPIO1_ENABLE); | ||
289 | and_l(~0x00000002, &GPIO1_OUT); | ||
290 | #else | ||
291 | or_l(0x00000800, &GPIO_ENABLE); | ||
292 | or_l(0x00000800, &GPIO_FUNCTION); | ||
293 | and_l(~0x00000800, &GPIO_OUT); | ||
294 | #endif | ||
295 | #endif | ||
296 | |||
297 | /* Power on the hard drive early, to speed up the loading. | ||
298 | Some H300 don't like this, so we only do it for the H100 */ | ||
299 | #ifndef IRIVER_H300_SERIES | ||
300 | if(!((on_button && button_hold()) || | ||
301 | (rc_on_button && remote_button_hold()))) { | ||
302 | ide_power_enable(true); | ||
303 | } | ||
304 | #endif | 566 | #endif |
305 | 567 | ||
306 | system_init(); | 568 | system_init(); |
@@ -313,134 +575,86 @@ void main(void) | |||
313 | coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); | 575 | coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); |
314 | #endif | 576 | #endif |
315 | #endif | 577 | #endif |
578 | set_irq_level(0); | ||
579 | |||
580 | #ifdef HAVE_EEPROM_SETTINGS | ||
581 | initialize_eeprom(); | ||
582 | #endif | ||
583 | |||
584 | adc_init(); | ||
585 | button_init(); | ||
586 | |||
587 | if ((on_button && button_hold()) || | ||
588 | (rc_on_button && remote_button_hold())) | ||
589 | { | ||
590 | hold_status = true; | ||
591 | } | ||
592 | |||
593 | /* Power on the hard drive early, to speed up the loading. | ||
594 | Some H300 don't like this, so we only do it for the H100 */ | ||
595 | #ifndef IRIVER_H300_SERIES | ||
596 | if (!hold_status && !recovery_mode) | ||
597 | { | ||
598 | ide_power_enable(true); | ||
599 | } | ||
600 | |||
601 | if (!hold_status && !usb_detect() && !recovery_mode) | ||
602 | try_flashboot(); | ||
603 | #endif | ||
316 | 604 | ||
605 | backlight_init(); | ||
317 | #ifdef HAVE_UDA1380 | 606 | #ifdef HAVE_UDA1380 |
318 | audiohw_reset(); | 607 | audiohw_reset(); |
319 | #endif | 608 | #endif |
320 | 609 | ||
321 | backlight_init(); | ||
322 | set_irq_level(0); | ||
323 | lcd_init(); | 610 | lcd_init(); |
611 | #ifdef HAVE_REMOTE_LCD | ||
612 | lcd_remote_init(); | ||
613 | #endif | ||
324 | font_init(); | 614 | font_init(); |
325 | adc_init(); | ||
326 | button_init(); | ||
327 | 615 | ||
328 | lcd_setfont(FONT_SYSFIXED); | 616 | lcd_setfont(FONT_SYSFIXED); |
329 | 617 | ||
330 | printf("Rockbox boot loader"); | 618 | printf("Rockbox boot loader"); |
331 | printf("Version %s", version); | 619 | printf("Version %s", version); |
332 | lcd_update(); | ||
333 | 620 | ||
334 | sleep(HZ/50); /* Allow the button driver to check the buttons */ | 621 | sleep(HZ/50); /* Allow the button driver to check the buttons */ |
335 | rec_button = ((button_status() & BUTTON_REC) == BUTTON_REC) | 622 | rec_button = ((button_status() & BUTTON_REC) == BUTTON_REC) |
336 | || ((button_status() & BUTTON_RC_REC) == BUTTON_RC_REC); | 623 | || ((button_status() & BUTTON_RC_REC) == BUTTON_RC_REC); |
337 | 624 | ||
625 | check_battery(); | ||
626 | |||
338 | /* Don't start if the Hold button is active on the device you | 627 | /* Don't start if the Hold button is active on the device you |
339 | are starting with */ | 628 | are starting with */ |
340 | if (!usb_detect() && ((on_button && button_hold()) || | 629 | if (!usb_detect() && (hold_status || recovery_mode)) |
341 | (rc_on_button && remote_button_hold()))) | ||
342 | { | ||
343 | printf("HOLD switch on, power off..."); | ||
344 | lcd_update(); | ||
345 | sleep(HZ*2); | ||
346 | |||
347 | /* Backlight OFF */ | ||
348 | #ifdef HAVE_REMOTE_LCD | ||
349 | #ifdef IRIVER_H300_SERIES | ||
350 | or_l(0x00000002, &GPIO1_OUT); | ||
351 | #else | ||
352 | or_l(0x00000800, &GPIO_OUT); | ||
353 | #endif | ||
354 | #endif | ||
355 | /* Reset the cookie for the crt0 crash check */ | ||
356 | asm(" move.l #0,%d0"); | ||
357 | asm(" move.l %d0,0x10017ffc"); | ||
358 | power_off(); | ||
359 | } | ||
360 | |||
361 | #ifdef HAVE_EEPROM_SETTINGS | ||
362 | firmware_settings.initialized = false; | ||
363 | #endif | ||
364 | if (detect_flashed_rockbox()) | ||
365 | { | 630 | { |
366 | bool load_from_flash; | 631 | if (detect_original_firmware()) |
367 | |||
368 | load_from_flash = !rec_button; | ||
369 | #ifdef HAVE_EEPROM_SETTINGS | ||
370 | if (eeprom_settings_init()) | ||
371 | { | 632 | { |
372 | /* If bootloader version has not been reset, disk might | 633 | printf("Hold switch on"); |
373 | * not be intact. */ | 634 | shutdown(); |
374 | if (firmware_settings.bl_version) | ||
375 | firmware_settings.disk_clean = false; | ||
376 | |||
377 | firmware_settings.bl_version = 7; | ||
378 | /* Invert the record button if we want to load from disk | ||
379 | * by default. */ | ||
380 | if (firmware_settings.boot_disk) | ||
381 | load_from_flash = rec_button; | ||
382 | } | 635 | } |
636 | |||
637 | #ifdef IRIVER_H100_SERIES | ||
638 | failsafe_menu(); | ||
383 | #endif | 639 | #endif |
384 | |||
385 | if (load_from_flash) | ||
386 | { | ||
387 | /* Load firmware from flash */ | ||
388 | i = load_flashed_rockbox(); | ||
389 | printf("Result: %d", i); | ||
390 | lcd_update(); | ||
391 | if (i == 0) | ||
392 | { | ||
393 | #ifdef HAVE_EEPROM_SETTINGS | ||
394 | eeprom_settings_store(); | ||
395 | #endif | ||
396 | start_firmware(); | ||
397 | printf("Fatal: Corrupted firmware"); | ||
398 | printf("Hold down REC on next boot"); | ||
399 | lcd_update(); | ||
400 | sleep(HZ*2); | ||
401 | power_off(); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | printf("Loading from disk..."); | ||
406 | lcd_update(); | ||
407 | } | 640 | } |
408 | else | 641 | |
642 | /* Holding REC while starting runs the original firmware */ | ||
643 | if (detect_original_firmware() && rec_button) | ||
409 | { | 644 | { |
410 | /* Holding REC while starting runs the original firmware */ | 645 | printf("Starting original firmware..."); |
411 | if (rec_button) | 646 | start_iriver_fw(); |
412 | { | ||
413 | printf("Starting original firmware..."); | ||
414 | lcd_update(); | ||
415 | start_iriver_fw(); | ||
416 | } | ||
417 | } | 647 | } |
418 | 648 | ||
419 | usb_init(); | 649 | usb_init(); |
420 | 650 | ||
421 | adc_battery = adc_read(ADC_BATTERY); | ||
422 | |||
423 | battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000; | ||
424 | batt_int = battery_voltage / 100; | ||
425 | batt_frac = battery_voltage % 100; | ||
426 | |||
427 | printf("Batt: %d.%02dV", batt_int, batt_frac); | ||
428 | lcd_update(); | ||
429 | |||
430 | if(battery_voltage <= 300) { | ||
431 | printf("WARNING! BATTERY LOW!!"); | ||
432 | lcd_update(); | ||
433 | sleep(HZ*2); | ||
434 | } | ||
435 | |||
436 | rc = ata_init(); | 651 | rc = ata_init(); |
437 | if(rc) | 652 | if(rc) |
438 | { | 653 | { |
439 | lcd_clear_display(); | 654 | reset_screen(); |
440 | printf("ATA error: %d", rc); | 655 | printf("ATA error: %d", rc); |
441 | printf("Insert USB cable and press"); | 656 | printf("Insert USB cable and press"); |
442 | printf("a button"); | 657 | printf("a button"); |
443 | lcd_update(); | ||
444 | while(!(button_get(true) & BUTTON_REL)); | 658 | while(!(button_get(true) & BUTTON_REL)); |
445 | } | 659 | } |
446 | 660 | ||
@@ -450,7 +664,7 @@ void main(void) | |||
450 | const char msg[] = "Bootloader USB mode"; | 664 | const char msg[] = "Bootloader USB mode"; |
451 | int w, h; | 665 | int w, h; |
452 | font_getstringsize(msg, &w, &h, FONT_SYSFIXED); | 666 | font_getstringsize(msg, &w, &h, FONT_SYSFIXED); |
453 | lcd_clear_display(); | 667 | reset_screen(); |
454 | lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, msg); | 668 | lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, msg); |
455 | lcd_update(); | 669 | lcd_update(); |
456 | 670 | ||
@@ -469,21 +683,24 @@ void main(void) | |||
469 | ata_enable(false); | 683 | ata_enable(false); |
470 | usb_enable(true); | 684 | usb_enable(true); |
471 | cpu_idle_mode(true); | 685 | cpu_idle_mode(true); |
472 | while(usb_detect()) | 686 | while (usb_detect()) |
473 | { | 687 | { |
688 | /* Print the battery status. */ | ||
689 | line = 0; | ||
690 | check_battery(); | ||
691 | |||
474 | ata_spin(); /* Prevent the drive from spinning down */ | 692 | ata_spin(); /* Prevent the drive from spinning down */ |
475 | sleep(HZ); | 693 | sleep(HZ); |
476 | 694 | ||
477 | /* Backlight OFF */ | 695 | /* Backlight OFF */ |
478 | or_l(0x00020000, &GPIO1_OUT); | 696 | __backlight_off(); |
479 | } | 697 | } |
480 | 698 | ||
481 | cpu_idle_mode(false); | 699 | cpu_idle_mode(false); |
482 | usb_enable(false); | 700 | usb_enable(false); |
483 | ata_init(); /* Reinitialize ATA and continue booting */ | 701 | ata_init(); /* Reinitialize ATA and continue booting */ |
484 | 702 | ||
485 | lcd_clear_display(); | 703 | reset_screen(); |
486 | line = 0; | ||
487 | lcd_update(); | 704 | lcd_update(); |
488 | } | 705 | } |
489 | 706 | ||
@@ -492,34 +709,22 @@ void main(void) | |||
492 | rc = disk_mount_all(); | 709 | rc = disk_mount_all(); |
493 | if (rc<=0) | 710 | if (rc<=0) |
494 | { | 711 | { |
495 | lcd_clear_display(); | 712 | reset_screen(); |
496 | printf("No partition found"); | 713 | printf("No partition found"); |
497 | lcd_update(); | ||
498 | while(button_get(true) != SYS_USB_CONNECTED) {}; | 714 | while(button_get(true) != SYS_USB_CONNECTED) {}; |
499 | } | 715 | } |
500 | 716 | ||
501 | printf("Loading firmware"); | 717 | printf("Loading firmware"); |
502 | lcd_update(); | ||
503 | i = load_firmware(); | 718 | i = load_firmware(); |
504 | printf("Result: %d", i); | 719 | printf("Result: %d", i); |
505 | lcd_update(); | ||
506 | |||
507 | #ifdef HAVE_EEPROM_SETTINGS | ||
508 | if (firmware_settings.initialized) | ||
509 | eeprom_settings_store(); | ||
510 | #endif | ||
511 | 720 | ||
512 | if (i == 0) | 721 | if (i == 0) |
513 | start_firmware(); | 722 | start_firmware(); |
514 | 723 | ||
515 | if (detect_flashed_rockbox()) | 724 | if (!detect_original_firmware()) |
516 | { | 725 | { |
517 | printf("No firmware found on disk"); | 726 | printf("No firmware found on disk"); |
518 | printf("Powering off..."); | 727 | shutdown(); |
519 | lcd_update(); | ||
520 | ata_sleep(); | ||
521 | sleep(HZ*4); | ||
522 | power_off(); | ||
523 | } | 728 | } |
524 | else | 729 | else |
525 | start_iriver_fw(); | 730 | start_iriver_fw(); |