diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-21 07:05:51 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-21 07:05:51 +0000 |
commit | 863c03f2ae08e8fa431f3d40a167605fae726a15 (patch) | |
tree | 830881f5ed41b98ee4cdf502b32264ad89a40206 | |
parent | 523036251550b69ed3f204b1e1f21478cfc48174 (diff) | |
download | rockbox-863c03f2ae08e8fa431f3d40a167605fae726a15.tar.gz rockbox-863c03f2ae08e8fa431f3d40a167605fae726a15.zip |
Gigabeat S: Renovate bootloader a bit to show splash, implement verbose, shutdown on low battery, handle hold-switch-on and wait only so long for USB if a USB charger is inserted at boot instead of being connected to a host. 'Bootloader USB mode' display is just part of normal printf stream now. Move interrupt stacks into .bss area so they aren't loaded (for firmware too).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29099 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | bootloader/SOURCES | 1 | ||||
-rw-r--r-- | bootloader/common.c | 3 | ||||
-rw-r--r-- | bootloader/gigabeat-s.c | 155 | ||||
-rw-r--r-- | firmware/target/arm/imx31/crt0.S | 10 |
4 files changed, 90 insertions, 79 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES index d16c51690e..c56acb25ba 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES | |||
@@ -8,6 +8,7 @@ ipod.c | |||
8 | gigabeat.c | 8 | gigabeat.c |
9 | #elif defined(GIGABEAT_S) | 9 | #elif defined(GIGABEAT_S) |
10 | gigabeat-s.c | 10 | gigabeat-s.c |
11 | show_logo.c | ||
11 | ../firmware/target/arm/imx31/mmu-imx31.c | 12 | ../firmware/target/arm/imx31/mmu-imx31.c |
12 | #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \ | 13 | #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \ |
13 | defined(SANSA_E200) || defined(SANSA_C200) || \ | 14 | defined(SANSA_E200) || defined(SANSA_C200) || \ |
diff --git a/bootloader/common.c b/bootloader/common.c index 8c587edf51..8fb7cdef36 100644 --- a/bootloader/common.c +++ b/bootloader/common.c | |||
@@ -45,7 +45,8 @@ | |||
45 | || defined(SAMSUNG_YH925) || defined(SAMSUNG_YH920) \ | 45 | || defined(SAMSUNG_YH925) || defined(SAMSUNG_YH920) \ |
46 | || defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \ | 46 | || defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \ |
47 | || defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \ | 47 | || defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \ |
48 | || defined(ONDA_VX747) || defined(PBELL_VIBE500) | 48 | || defined(ONDA_VX747) || defined(PBELL_VIBE500) \ |
49 | || defined(TOSHIBA_GIGABEAT_S) | ||
49 | bool verbose = false; | 50 | bool verbose = false; |
50 | #else | 51 | #else |
51 | bool verbose = true; | 52 | bool verbose = true; |
diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c index 77887f5d4b..06f675644c 100644 --- a/bootloader/gigabeat-s.c +++ b/bootloader/gigabeat-s.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "dir.h" | 30 | #include "dir.h" |
31 | #include "disk.h" | 31 | #include "disk.h" |
32 | #include "common.h" | 32 | #include "common.h" |
33 | #include "power.h" | ||
33 | #include "backlight.h" | 34 | #include "backlight.h" |
34 | #include "usb.h" | 35 | #include "usb.h" |
35 | #include "button.h" | 36 | #include "button.h" |
@@ -38,6 +39,9 @@ | |||
38 | #include "usb-target.h" | 39 | #include "usb-target.h" |
39 | #include "version.h" | 40 | #include "version.h" |
40 | 41 | ||
42 | /* Show the Rockbox logo - in show_logo.c */ | ||
43 | extern int show_logo(void); | ||
44 | |||
41 | #define TAR_CHUNK 512 | 45 | #define TAR_CHUNK 512 |
42 | #define TAR_HEADER_SIZE 157 | 46 | #define TAR_HEADER_SIZE 157 |
43 | 47 | ||
@@ -51,67 +55,44 @@ static void * const load_buf = 0x00000000; | |||
51 | static const size_t load_buf_size = 0x20000000 - 0x100000; | 55 | static const size_t load_buf_size = 0x20000000 - 0x100000; |
52 | static const void * const start_addr = 0x00000000; | 56 | static const void * const start_addr = 0x00000000; |
53 | 57 | ||
54 | static void show_splash(int timeout, const char *msg) | 58 | /* Show a message + "Shutting down...", then power off the device */ |
59 | static void display_message_and_power_off(int timeout, const char *msg) | ||
55 | { | 60 | { |
56 | backlight_on(); | 61 | verbose = true; |
57 | reset_screen(); | 62 | printf(msg); |
58 | lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, | 63 | printf("Shutting down..."); |
59 | (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); | ||
60 | lcd_update(); | ||
61 | |||
62 | sleep(timeout); | 64 | sleep(timeout); |
65 | power_off(); | ||
63 | } | 66 | } |
64 | 67 | ||
65 | static bool pause_if_button_pressed(bool pre_usb) | 68 | static void check_battery_safe(void) |
66 | { | 69 | { |
67 | while (1) | 70 | if (battery_level_safe()) |
68 | { | 71 | return; |
69 | int button = button_read_device(); | ||
70 | |||
71 | if (pre_usb && !usb_plugged()) | ||
72 | return false; | ||
73 | |||
74 | /* Exit if no button or only select buttons that have other | ||
75 | * functions */ | ||
76 | switch (button) | ||
77 | { | ||
78 | case USB_BL_INSTALL_MODE_BTN: | ||
79 | if (!pre_usb) | ||
80 | break; /* Only before USB detect */ | ||
81 | case BUTTON_MENU: /* Settings reset */ | ||
82 | case BUTTON_NONE: /* Nothing pressed */ | ||
83 | return true; | ||
84 | } | ||
85 | |||
86 | sleep(HZ/5); | ||
87 | 72 | ||
88 | /* If the disk powers off, the firmware will lock at startup */ | 73 | display_message_and_power_off(HZ, "Battery low"); |
89 | storage_spin(); | ||
90 | } | ||
91 | } | 74 | } |
92 | 75 | ||
93 | /* TODO: Handle charging while connected */ | 76 | /* TODO: Handle charging while connected */ |
94 | static void handle_usb(void) | 77 | static void handle_usb(int connect_timeout) |
95 | { | 78 | { |
79 | long end_tick = 0; | ||
96 | int button; | 80 | int button; |
97 | 81 | ||
98 | /* Check if plugged and pause to look at messages. If the cable was pulled | ||
99 | * while waiting, proceed as if it never was plugged. */ | ||
100 | if (!usb_plugged() || !pause_if_button_pressed(true)) | ||
101 | return; | ||
102 | |||
103 | /** Enter USB mode **/ | ||
104 | |||
105 | /* We need full button and backlight handling now */ | 82 | /* We need full button and backlight handling now */ |
106 | backlight_init(); | 83 | backlight_init(); |
107 | button_init(); | 84 | button_init(); |
85 | backlight_on(); | ||
108 | 86 | ||
109 | /* Start the USB driver */ | 87 | /* Start the USB driver */ |
110 | usb_init(); | 88 | usb_init(); |
111 | usb_start_monitoring(); | 89 | usb_start_monitoring(); |
112 | 90 | ||
113 | /* Wait for threads to connect or cable is pulled */ | 91 | /* Wait for threads to connect or cable is pulled */ |
114 | show_splash(HZ/2, "Waiting for USB"); | 92 | printf("USB: Connecting"); |
93 | |||
94 | if (connect_timeout != TIMEOUT_BLOCK) | ||
95 | end_tick = current_tick + connect_timeout; | ||
115 | 96 | ||
116 | while (1) | 97 | while (1) |
117 | { | 98 | { |
@@ -120,35 +101,47 @@ static void handle_usb(void) | |||
120 | if (button == SYS_USB_CONNECTED) | 101 | if (button == SYS_USB_CONNECTED) |
121 | break; /* Hit */ | 102 | break; /* Hit */ |
122 | 103 | ||
104 | if (connect_timeout != TIMEOUT_BLOCK && | ||
105 | TIME_AFTER(current_tick, end_tick)) | ||
106 | { | ||
107 | /* Timed out waiting for the connect - will happen when connected | ||
108 | * to a charger through the USB port */ | ||
109 | printf("USB: Timed out"); | ||
110 | break; | ||
111 | } | ||
112 | |||
123 | if (!usb_plugged()) | 113 | if (!usb_plugged()) |
124 | break; /* Cable pulled */ | 114 | break; /* Cable pulled */ |
125 | } | 115 | } |
126 | 116 | ||
127 | if (button == SYS_USB_CONNECTED) | 117 | if (button == SYS_USB_CONNECTED) |
128 | { | 118 | { |
119 | /* Switch to verbose mode if not in it so that the status updates | ||
120 | * are shown */ | ||
121 | verbose = true; | ||
129 | /* Got the message - wait for disconnect */ | 122 | /* Got the message - wait for disconnect */ |
130 | show_splash(0, "Bootloader USB mode"); | 123 | printf("Bootloader USB mode"); |
131 | 124 | ||
132 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 125 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
133 | 126 | ||
134 | while (1) | 127 | while (1) |
135 | { | 128 | { |
136 | button = button_get(true); | 129 | button = button_get_w_tmo(HZ/2); |
137 | if (button == SYS_USB_DISCONNECTED) | 130 | if (button == SYS_USB_DISCONNECTED) |
138 | break; | 131 | break; |
132 | |||
133 | check_battery_safe(); | ||
139 | } | 134 | } |
135 | |||
136 | backlight_on(); | ||
137 | /* Sleep a little to let the backlight ramp up */ | ||
138 | sleep(HZ*5/4); | ||
140 | } | 139 | } |
141 | 140 | ||
142 | /* Put drivers initialized for USB connection into a known state */ | 141 | /* Put drivers initialized for USB connection into a known state */ |
143 | backlight_on(); | ||
144 | usb_close(); | 142 | usb_close(); |
145 | button_close(); | 143 | button_close(); |
146 | backlight_close(); | 144 | backlight_close(); |
147 | |||
148 | /* Sleep a little to let the backlight ramp up */ | ||
149 | sleep(HZ*5/4); | ||
150 | |||
151 | reset_screen(); | ||
152 | } | 145 | } |
153 | 146 | ||
154 | static void untar(int tar_fd) | 147 | static void untar(int tar_fd) |
@@ -265,6 +258,7 @@ static void handle_untar(void) | |||
265 | model[4] = 0; | 258 | model[4] = 0; |
266 | if (strcmp(model, "gigs") == 0) | 259 | if (strcmp(model, "gigs") == 0) |
267 | { | 260 | { |
261 | verbose = true; | ||
268 | printf("Found rockbox binary. Moving..."); | 262 | printf("Found rockbox binary. Moving..."); |
269 | close(fd); | 263 | close(fd); |
270 | remove( BOOTDIR "/" BOOTFILE); | 264 | remove( BOOTDIR "/" BOOTFILE); |
@@ -283,6 +277,7 @@ static void handle_untar(void) | |||
283 | tarstring[5] = 0; | 277 | tarstring[5] = 0; |
284 | if (strcmp(tarstring, "ustar") == 0) | 278 | if (strcmp(tarstring, "ustar") == 0) |
285 | { | 279 | { |
280 | verbose = true; | ||
286 | printf("Found tar file. Unarchiving..."); | 281 | printf("Found tar file. Unarchiving..."); |
287 | lseek(fd, 0, SEEK_SET); | 282 | lseek(fd, 0, SEEK_SET); |
288 | untar(fd); | 283 | untar(fd); |
@@ -300,14 +295,27 @@ static void handle_untar(void) | |||
300 | /* Try to load the firmware and run it */ | 295 | /* Try to load the firmware and run it */ |
301 | static void NORETURN_ATTR handle_firmware_load(void) | 296 | static void NORETURN_ATTR handle_firmware_load(void) |
302 | { | 297 | { |
303 | int rc = load_firmware(load_buf, BOOTFILE, | 298 | int rc = load_firmware(load_buf, BOOTFILE, load_buf_size); |
304 | load_buf_size); | ||
305 | 299 | ||
306 | if(rc < 0) | 300 | if(rc < 0) |
307 | error(EBOOTFILE, rc, true); | 301 | error(EBOOTFILE, rc, true); |
308 | 302 | ||
309 | /* Pause to look at messages */ | 303 | /* Pause to look at messages */ |
310 | pause_if_button_pressed(false); | 304 | while (1) |
305 | { | ||
306 | int button = button_read_device(); | ||
307 | |||
308 | /* Ignore settings reset */ | ||
309 | if (button == BUTTON_NONE || button == BUTTON_MENU) | ||
310 | break; | ||
311 | |||
312 | sleep(HZ/5); | ||
313 | |||
314 | check_battery_safe(); | ||
315 | |||
316 | /* If the disk powers off, the firmware will lock at startup */ | ||
317 | storage_spin(); | ||
318 | } | ||
311 | 319 | ||
312 | /* Put drivers into a known state */ | 320 | /* Put drivers into a known state */ |
313 | button_close_device(); | 321 | button_close_device(); |
@@ -316,7 +324,7 @@ static void NORETURN_ATTR handle_firmware_load(void) | |||
316 | 324 | ||
317 | if (rc == EOK) | 325 | if (rc == EOK) |
318 | { | 326 | { |
319 | cpucache_invalidate(); | 327 | cpucache_commit_discard(); |
320 | asm volatile ("bx %0": : "r"(start_addr)); | 328 | asm volatile ("bx %0": : "r"(start_addr)); |
321 | } | 329 | } |
322 | 330 | ||
@@ -325,58 +333,55 @@ static void NORETURN_ATTR handle_firmware_load(void) | |||
325 | core_idle(); | 333 | core_idle(); |
326 | } | 334 | } |
327 | 335 | ||
328 | static void check_battery(void) | ||
329 | { | ||
330 | int batt = battery_adc_voltage(); | ||
331 | printf("Battery: %d.%03d V", batt / 1000, batt % 1000); | ||
332 | /* TODO: warn on low battery or shut down */ | ||
333 | } | ||
334 | |||
335 | void main(void) | 336 | void main(void) |
336 | { | 337 | { |
337 | int rc; | 338 | int rc; |
338 | 339 | int batt; | |
339 | /* Flush and invalidate all caches (because vectors were written) */ | ||
340 | cpucache_invalidate(); | ||
341 | 340 | ||
342 | system_init(); | 341 | system_init(); |
343 | kernel_init(); | 342 | kernel_init(); |
344 | 343 | ||
345 | enable_interrupt(IRQ_FIQ_STATUS); | 344 | enable_interrupt(IRQ_FIQ_STATUS); |
346 | 345 | ||
347 | lcd_init_device(); | 346 | /* Keep button_device_init early to delay calls to button_read_device */ |
347 | button_init_device(); | ||
348 | |||
349 | lcd_init(); | ||
350 | font_init(); | ||
351 | show_logo(); | ||
348 | lcd_clear_display(); | 352 | lcd_clear_display(); |
349 | 353 | ||
354 | if (button_hold()) | ||
355 | display_message_and_power_off(HZ, "Hold switch on"); | ||
356 | |||
357 | if (button_read_device() != BUTTON_NONE) | ||
358 | verbose = true; | ||
359 | |||
350 | printf("Gigabeat S Rockbox Bootloader"); | 360 | printf("Gigabeat S Rockbox Bootloader"); |
351 | printf("Version " RBVERSION); | 361 | printf("Version " RBVERSION); |
352 | 362 | ||
353 | /* Initialize KPP so we can poll the button states */ | ||
354 | button_init_device(); | ||
355 | |||
356 | adc_init(); | 363 | adc_init(); |
357 | 364 | batt = battery_adc_voltage(); | |
358 | check_battery(); | 365 | printf("Battery: %d.%03d V", batt / 1000, batt % 1000); |
366 | check_battery_safe(); | ||
359 | 367 | ||
360 | rc = storage_init(); | 368 | rc = storage_init(); |
361 | if(rc) | 369 | if(rc) |
362 | { | ||
363 | reset_screen(); | ||
364 | error(EATA, rc, true); | 370 | error(EATA, rc, true); |
365 | } | ||
366 | 371 | ||
367 | disk_init(); | 372 | disk_init(); |
368 | 373 | ||
369 | rc = disk_mount_all(); | 374 | rc = disk_mount_all(); |
370 | if (rc<=0) | 375 | if (rc <= 0) |
371 | { | ||
372 | error(EDISK, rc, true); | 376 | error(EDISK, rc, true); |
373 | } | ||
374 | 377 | ||
375 | printf("Init complete"); | 378 | printf("Init complete"); |
376 | 379 | ||
377 | /* Do USB first since a tar or binary could be added to the MTP directory | 380 | /* Do USB first since a tar or binary could be added to the MTP directory |
378 | * at the time and we can untar or move after unplugging. */ | 381 | * at the time and we can untar or move after unplugging. */ |
379 | handle_usb(); | 382 | if (usb_plugged()) |
383 | handle_usb(HZ*2); | ||
384 | |||
380 | handle_untar(); | 385 | handle_untar(); |
381 | handle_firmware_load(); /* No return */ | 386 | handle_firmware_load(); /* No return */ |
382 | } | 387 | } |
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S index 53e18c17df..776699da14 100644 --- a/firmware/target/arm/imx31/crt0.S +++ b/firmware/target/arm/imx31/crt0.S | |||
@@ -298,7 +298,7 @@ remap_end: | |||
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | /* Make memory coherent for devices */ | 300 | /* Make memory coherent for devices */ |
301 | bl clean_dcache | 301 | bl cpucache_commit_discard |
302 | 302 | ||
303 | bl main | 303 | bl main |
304 | 304 | ||
@@ -351,9 +351,13 @@ data_abort_handler: | |||
351 | b UIE | 351 | b UIE |
352 | 352 | ||
353 | /* 256 words of IRQ stack */ | 353 | /* 256 words of IRQ stack */ |
354 | .space 256*4 | 354 | .section .bss |
355 | .balign 32 | ||
356 | .space 256*4 | ||
355 | irq_stack: | 357 | irq_stack: |
356 | 358 | ||
357 | /* 256 words of FIQ stack */ | 359 | /* 256 words of FIQ stack */ |
358 | .space 256*4 | 360 | .section .bss |
361 | .balign 32 | ||
362 | .space 256*4 | ||
359 | fiq_stack: | 363 | fiq_stack: |