summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2010-05-04 11:16:17 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2010-05-04 11:16:17 +0000
commit69fa42d905340b7f7656495345b403076d243b38 (patch)
tree88ff6c0e1674b70a69dd04de86e59a14289c98cb
parentbccdcf2003fde999a96fe15c8ca7caed7be94956 (diff)
downloadrockbox-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.c272
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 */
58extern int line; 63extern int line;
59static const char *bootmenu_options[] = { 64static const char *bootmenu_options[] = {
@@ -75,24 +80,24 @@ int usb_screen(void)
75 80
76char version[] = APPSVERSION; 81char version[] = APPSVERSION;
77 82
78bool _charger_inserted(void) 83static 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
83bool _battery_full(void) 88static 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 */
89inline void __reset_cookie(void) 94static 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
95void start_rockbox(void) 100static 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
107void start_mpio_firmware(void) 112static 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
116void __reset(void) 121static 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
126void __shutdown(void) 131static 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). */
154void check_battery(void) 159static 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
174void lcd_putstring_centered(const char *string) 179static 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
181void bootmenu(void) 186static 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
225static 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
305void main(void) 312void 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