diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2010-05-04 11:16:17 +0000 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2010-05-04 11:16:17 +0000 |
commit | 69fa42d905340b7f7656495345b403076d243b38 (patch) | |
tree | 88ff6c0e1674b70a69dd04de86e59a14289c98cb | |
parent | bccdcf2003fde999a96fe15c8ca7caed7be94956 (diff) | |
download | rockbox-69fa42d905340b7f7656495345b403076d243b38.tar.gz rockbox-69fa42d905340b7f7656495345b403076d243b38.zip |
HD200 - rework bootloader logic
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25806 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | bootloader/mpio_hd200.c | 272 |
1 files changed, 131 insertions, 141 deletions
diff --git a/bootloader/mpio_hd200.c b/bootloader/mpio_hd200.c index 68152f3c2d..a031234b5a 100644 --- a/bootloader/mpio_hd200.c +++ b/bootloader/mpio_hd200.c | |||
@@ -54,6 +54,11 @@ | |||
54 | #define BOOTMENU_TIMEOUT (10*HZ) | 54 | #define BOOTMENU_TIMEOUT (10*HZ) |
55 | #define BOOTMENU_OPTIONS 3 | 55 | #define BOOTMENU_OPTIONS 3 |
56 | 56 | ||
57 | #define EVENT_NONE 0x00 | ||
58 | #define EVENT_ON 0x01 | ||
59 | #define EVENT_AC 0x02 | ||
60 | #define EVENT_USB 0x04 | ||
61 | |||
57 | /* From common.c */ | 62 | /* From common.c */ |
58 | extern int line; | 63 | extern int line; |
59 | static const char *bootmenu_options[] = { | 64 | static const char *bootmenu_options[] = { |
@@ -75,24 +80,24 @@ int usb_screen(void) | |||
75 | 80 | ||
76 | char version[] = APPSVERSION; | 81 | char version[] = APPSVERSION; |
77 | 82 | ||
78 | bool _charger_inserted(void) | 83 | static inline bool _charger_inserted(void) |
79 | { | 84 | { |
80 | return (GPIO1_READ & (1<<14)) ? false : true; | 85 | return (GPIO1_READ & (1<<14)) ? false : true; |
81 | } | 86 | } |
82 | 87 | ||
83 | bool _battery_full(void) | 88 | static inline bool _battery_full(void) |
84 | { | 89 | { |
85 | return (GPIO_READ & (1<<30)) ? true : false; | 90 | return (GPIO_READ & (1<<30)) ? true : false; |
86 | } | 91 | } |
87 | 92 | ||
88 | /* Reset the cookie for the crt0 crash check */ | 93 | /* Reset the cookie for the crt0 crash check */ |
89 | inline void __reset_cookie(void) | 94 | static inline void __reset_cookie(void) |
90 | { | 95 | { |
91 | asm(" move.l #0,%d0"); | 96 | asm(" move.l #0,%d0"); |
92 | asm(" move.l %d0,0x10017ffc"); | 97 | asm(" move.l %d0,0x10017ffc"); |
93 | } | 98 | } |
94 | 99 | ||
95 | void start_rockbox(void) | 100 | static void start_rockbox(void) |
96 | { | 101 | { |
97 | adc_close(); | 102 | adc_close(); |
98 | asm(" move.w #0x2700,%sr"); | 103 | asm(" move.w #0x2700,%sr"); |
@@ -104,7 +109,7 @@ void start_rockbox(void) | |||
104 | asm(" jmp (%a0)"); | 109 | asm(" jmp (%a0)"); |
105 | } | 110 | } |
106 | 111 | ||
107 | void start_mpio_firmware(void) | 112 | static void start_mpio_firmware(void) |
108 | { | 113 | { |
109 | asm(" move.w #0x2700,%sr"); | 114 | asm(" move.w #0x2700,%sr"); |
110 | __reset_cookie(); | 115 | __reset_cookie(); |
@@ -113,7 +118,7 @@ void start_mpio_firmware(void) | |||
113 | asm(" jmp 8"); | 118 | asm(" jmp 8"); |
114 | } | 119 | } |
115 | 120 | ||
116 | void __reset(void) | 121 | static void __reset(void) |
117 | { | 122 | { |
118 | asm(" move.w #0x2700,%sr"); | 123 | asm(" move.w #0x2700,%sr"); |
119 | __reset_cookie(); | 124 | __reset_cookie(); |
@@ -123,7 +128,7 @@ void __reset(void) | |||
123 | asm(" jmp (%a0)"); | 128 | asm(" jmp (%a0)"); |
124 | } | 129 | } |
125 | 130 | ||
126 | void __shutdown(void) | 131 | static void __shutdown(void) |
127 | { | 132 | { |
128 | /* We need to gracefully spin down the disk to prevent clicks. */ | 133 | /* We need to gracefully spin down the disk to prevent clicks. */ |
129 | if (ide_powered()) | 134 | if (ide_powered()) |
@@ -151,7 +156,7 @@ void __shutdown(void) | |||
151 | } | 156 | } |
152 | 157 | ||
153 | /* Print the battery voltage (and a warning message). */ | 158 | /* Print the battery voltage (and a warning message). */ |
154 | void check_battery(void) | 159 | static void check_battery(void) |
155 | { | 160 | { |
156 | 161 | ||
157 | int battery_voltage, batt_int, batt_frac; | 162 | int battery_voltage, batt_int, batt_frac; |
@@ -171,16 +176,54 @@ void check_battery(void) | |||
171 | } | 176 | } |
172 | 177 | ||
173 | 178 | ||
174 | void lcd_putstring_centered(const char *string) | 179 | static void lcd_putstring_centered(const char *string) |
175 | { | 180 | { |
176 | int w,h; | 181 | int w,h; |
177 | font_getstringsize(string, &w, &h, FONT_SYSFIXED); | 182 | font_getstringsize(string, &w, &h, FONT_SYSFIXED); |
178 | lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, string); | 183 | lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, string); |
179 | } | 184 | } |
180 | 185 | ||
181 | void bootmenu(void) | 186 | static void rb_boot(void) |
182 | { | 187 | { |
183 | int rc; | 188 | int rc; |
189 | |||
190 | rc = storage_init(); | ||
191 | if(rc) | ||
192 | { | ||
193 | printf("ATA error: %d", rc); | ||
194 | sleep(HZ*5); | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | disk_init(); | ||
199 | |||
200 | rc = disk_mount_all(); | ||
201 | if (rc<=0) | ||
202 | { | ||
203 | printf("No partition found"); | ||
204 | sleep(HZ*5); | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | printf("Loading firmware"); | ||
209 | |||
210 | rc = load_firmware((unsigned char *)DRAM_START, | ||
211 | BOOTFILE, MAX_LOADSIZE); | ||
212 | |||
213 | if (rc < EOK) | ||
214 | { | ||
215 | printf("Error!"); | ||
216 | printf("Can't load " BOOTFILE ": "); | ||
217 | printf("Result: %s", strerror(rc)); | ||
218 | sleep(HZ*5); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | start_rockbox(); | ||
223 | } | ||
224 | |||
225 | static void bootmenu(void) | ||
226 | { | ||
184 | enum option_t i; | 227 | enum option_t i; |
185 | enum option_t option = rockbox; | 228 | enum option_t option = rockbox; |
186 | int button; | 229 | int button; |
@@ -250,42 +293,7 @@ void bootmenu(void) | |||
250 | switch (option) | 293 | switch (option) |
251 | { | 294 | { |
252 | case rockbox: | 295 | case rockbox: |
253 | rc = storage_init(); | 296 | rb_boot(); |
254 | if(rc) | ||
255 | { | ||
256 | printf("ATA error: %d", rc); | ||
257 | sleep(HZ*5); | ||
258 | __shutdown(); | ||
259 | } | ||
260 | |||
261 | disk_init(); | ||
262 | |||
263 | rc = disk_mount_all(); | ||
264 | if (rc<=0) | ||
265 | { | ||
266 | printf("No partition found"); | ||
267 | sleep(HZ*5); | ||
268 | __shutdown(); | ||
269 | } | ||
270 | |||
271 | printf("Loading firmware"); | ||
272 | rc = load_firmware((unsigned char *)DRAM_START, | ||
273 | BOOTFILE, MAX_LOADSIZE); | ||
274 | printf("Result: %s", strerror(rc)); | ||
275 | |||
276 | if (rc < EOK) | ||
277 | { | ||
278 | printf("Error!"); | ||
279 | printf("Can't load " BOOTFILE ": "); | ||
280 | printf(strerror(rc)); | ||
281 | sleep(HZ*5); | ||
282 | __shutdown(); | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | start_rockbox(); | ||
287 | } | ||
288 | |||
289 | break; | 297 | break; |
290 | 298 | ||
291 | case mpio_firmware: | 299 | case mpio_firmware: |
@@ -293,13 +301,12 @@ void bootmenu(void) | |||
293 | break; | 301 | break; |
294 | 302 | ||
295 | default: | 303 | default: |
296 | __shutdown(); | 304 | return; |
297 | break; | 305 | break; |
298 | } | 306 | } |
299 | } | 307 | } |
300 | } | 308 | } |
301 | /* timeout */ | 309 | /* timeout */ |
302 | __shutdown(); | ||
303 | } | 310 | } |
304 | 311 | ||
305 | void main(void) | 312 | void main(void) |
@@ -308,24 +315,13 @@ void main(void) | |||
308 | const char usb_connect_msg[] = "Bootloader USB mode"; | 315 | const char usb_connect_msg[] = "Bootloader USB mode"; |
309 | const char charging_msg[] = "Charging..."; | 316 | const char charging_msg[] = "Charging..."; |
310 | const char complete_msg[] = "Charging complete"; | 317 | const char complete_msg[] = "Charging complete"; |
311 | const char hold_msg[] = "Hold switch on"; | ||
312 | const char shutdown_msg[] = "Shutting down..."; | ||
313 | 318 | ||
314 | /* helper variables for messages */ | 319 | /* helper variable for messages */ |
315 | bool blink_toggle = false; | 320 | bool blink_toggle = false; |
316 | const char *msg; | ||
317 | 321 | ||
318 | bool on_button = false; | ||
319 | int button; | 322 | int button; |
320 | 323 | unsigned int event = EVENT_NONE; | |
321 | /* We want to read the buttons as early as possible, before the user | 324 | unsigned int last_event = EVENT_NONE; |
322 | releases the ON button */ | ||
323 | |||
324 | or_l( ((1<<24)|(1<<4)), &GPIO1_FUNCTION); /* main Hold & Play */ | ||
325 | and_l( ~((1<<24)|(1<<4)), &GPIO1_ENABLE); /* HiZ */ | ||
326 | |||
327 | if (GPIO1_READ & (1<<24)) | ||
328 | on_button = true; | ||
329 | 325 | ||
330 | power_init(); | 326 | power_init(); |
331 | 327 | ||
@@ -338,118 +334,112 @@ void main(void) | |||
338 | enable_irq(); | 334 | enable_irq(); |
339 | lcd_init(); | 335 | lcd_init(); |
340 | 336 | ||
341 | backlight_init(); | 337 | /* only lowlevel functions no queue init */ |
338 | _backlight_init(); | ||
339 | _backlight_hw_on(); | ||
340 | |||
341 | /* setup font system*/ | ||
342 | font_init(); | 342 | font_init(); |
343 | lcd_setfont(FONT_SYSFIXED); | 343 | lcd_setfont(FONT_SYSFIXED); |
344 | 344 | ||
345 | /* buttons reading */ | ||
345 | adc_init(); | 346 | adc_init(); |
346 | button_init(); | 347 | button_init(); |
348 | |||
347 | usb_init(); | 349 | usb_init(); |
350 | cpu_idle_mode(true); | ||
348 | 351 | ||
349 | /* handle charging */ | 352 | /* Handle wakeup event. Possibilities are: |
350 | if( _charger_inserted()) | 353 | * ON button (PLAY) |
354 | * USB insert | ||
355 | * AC charger plug | ||
356 | */ | ||
357 | |||
358 | while(1) | ||
351 | { | 359 | { |
352 | or_l((1<<15),&GPIO_OUT); | 360 | /* read buttons */ |
361 | event = EVENT_NONE; | ||
362 | button = button_get_w_tmo(HZ); | ||
353 | 363 | ||
354 | cpu_idle_mode(true); | 364 | if ( button & BUTTON_PLAY ) |
365 | event |= EVENT_ON; | ||
366 | |||
367 | if ( usb_detect() == USB_INSERTED ) | ||
368 | event |= EVENT_USB; | ||
355 | 369 | ||
356 | while( _charger_inserted() && | 370 | if ( _charger_inserted() ) |
357 | usb_detect() != USB_INSERTED && | 371 | event |= EVENT_AC; |
358 | !on_button) | 372 | |
373 | reset_screen(); | ||
374 | switch (event) | ||
359 | { | 375 | { |
360 | button = button_get_w_tmo(HZ); | 376 | case EVENT_ON: |
377 | case (EVENT_ON | EVENT_AC): | ||
378 | /* hold is handled in button driver */ | ||
379 | cpu_idle_mode(false); | ||
380 | |||
381 | if (button == (BUTTON_PLAY|BUTTON_REC)) | ||
382 | bootmenu(); | ||
383 | else | ||
384 | rb_boot(); | ||
361 | 385 | ||
362 | switch(button) | ||
363 | { | ||
364 | case BUTTON_ON: | ||
365 | on_button = true; | ||
366 | reset_screen(); | ||
367 | break; | 386 | break; |
368 | 387 | ||
369 | case BUTTON_NONE: /* Timeout */ | 388 | case EVENT_AC: |
389 | /* turn on charging */ | ||
390 | if (!(last_event & EVENT_AC)) | ||
391 | or_l((1<<15),&GPIO_OUT); | ||
370 | 392 | ||
393 | /* USB unplug */ | ||
394 | if (last_event & EVENT_USB) | ||
395 | usb_enable(false); | ||
396 | |||
371 | if(!_battery_full()) | 397 | if(!_battery_full()) |
372 | { | 398 | { |
373 | /* To be replaced with a nice animation */ | 399 | if (blink_toggle) |
400 | lcd_putstring_centered(charging_msg); | ||
401 | |||
374 | blink_toggle = !blink_toggle; | 402 | blink_toggle = !blink_toggle; |
375 | msg = charging_msg; | ||
376 | } | 403 | } |
377 | else | 404 | else |
378 | { | 405 | { |
379 | blink_toggle = true; | 406 | lcd_putstring_centered(complete_msg); |
380 | msg = complete_msg; | ||
381 | } | 407 | } |
382 | |||
383 | reset_screen(); | ||
384 | if(blink_toggle) | ||
385 | lcd_putstring_centered(msg); | ||
386 | |||
387 | check_battery(); | 408 | check_battery(); |
388 | break; | 409 | break; |
389 | } | ||
390 | 410 | ||
391 | } | 411 | case EVENT_USB: |
392 | cpu_idle_mode(false); | 412 | case (EVENT_USB | EVENT_AC): |
393 | } | 413 | if (!(last_event & EVENT_AC)) |
414 | or_l((1<<15),&GPIO_OUT); | ||
394 | 415 | ||
395 | /* handle USB in bootloader */ | 416 | if (!(last_event & EVENT_USB)) |
396 | if (usb_detect() == USB_INSERTED) | 417 | { |
397 | { | 418 | /* init USB */ |
398 | ide_power_enable(true); | 419 | ide_power_enable(true); |
399 | sleep(HZ/20); | 420 | sleep(HZ/20); |
400 | usb_enable(true); | 421 | usb_enable(true); |
401 | cpu_idle_mode(true); | 422 | } |
402 | |||
403 | while (usb_detect() == USB_INSERTED) | ||
404 | { | ||
405 | line = 0; | ||
406 | |||
407 | reset_screen(); | ||
408 | |||
409 | if(blink_toggle) | ||
410 | { | ||
411 | lcd_putstring_centered(usb_connect_msg); | ||
412 | } | ||
413 | 423 | ||
414 | check_battery(); | 424 | line = 0; |
415 | blink_toggle = !blink_toggle; | ||
416 | 425 | ||
417 | storage_spin(); /* Prevent the drive from spinning down */ | 426 | if (blink_toggle) |
418 | sleep(HZ); | 427 | lcd_putstring_centered(usb_connect_msg); |
419 | } | ||
420 | 428 | ||
421 | cpu_idle_mode(false); | 429 | check_battery(); |
422 | usb_enable(false); | 430 | blink_toggle = !blink_toggle; |
423 | 431 | storage_spin(); | |
424 | sleep(HZ); | 432 | break; |
425 | reset_screen(); | ||
426 | lcd_update(); | ||
427 | } | ||
428 | 433 | ||
429 | /* handle ON button press */ | 434 | default: |
430 | if (on_button) | 435 | /* spurious wakeup */ |
431 | { | 436 | __shutdown(); |
432 | if (button_hold() && | 437 | break; |
433 | !_charger_inserted() && | ||
434 | usb_detect() != USB_INSERTED) | ||
435 | { | ||
436 | lcd_putstring_centered(hold_msg); | ||
437 | lcd_update(); | ||
438 | sleep(HZ*3); | ||
439 | __shutdown(); | ||
440 | } | 438 | } |
441 | |||
442 | } | ||
443 | else | ||
444 | { | ||
445 | lcd_putstring_centered(shutdown_msg); | ||
446 | lcd_update(); | 439 | lcd_update(); |
447 | sleep(HZ*3); | 440 | last_event = event; |
448 | __shutdown(); | ||
449 | } | 441 | } |
450 | 442 | ||
451 | |||
452 | bootmenu(); | ||
453 | } | 443 | } |
454 | 444 | ||
455 | /* These functions are present in the firmware library, but we reimplement | 445 | /* These functions are present in the firmware library, but we reimplement |