diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-15 08:19:30 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-15 08:19:30 +0000 |
commit | 3a1127785b9f29e526b2ab845efe0a313699c459 (patch) | |
tree | c16f2071dcdd1f1388b0216643a8f4a979023b9f /bootloader/main-pp.c | |
parent | 53db95417dc919a50e55b6f6b1f9852e1bdf8816 (diff) |
Bootloader USB mode for PP502x. Enable only on GoGear SA9200 for the time being. Add HAVE_BOOTLOADER_USB_MODE to config if BOOTLOADER is defined to enable it. Clean up some kernel stuff a little to support it. Mess up a bunch of other stuff (hopefully not too badly).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29053 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'bootloader/main-pp.c')
-rw-r--r-- | bootloader/main-pp.c | 155 |
1 files changed, 129 insertions, 26 deletions
diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c index d8ef64cdd0..3670a7dc97 100644 --- a/bootloader/main-pp.c +++ b/bootloader/main-pp.c @@ -48,6 +48,7 @@ #include "usb.h" #include "usb_drv.h" #endif +#include "usb-target.h" #if defined(SAMSUNG_YH925) /* this function (in lcd-yh925.c) resets the screen orientation for the OF * for use with dualbooting */ @@ -451,8 +452,104 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo, return EOK; } +#endif /* (CONFIG_STORAGE & STORAGE_SD) */ + +#ifdef HAVE_BOOTLOADER_USB_MODE +/* Return USB_HANDLED if session took place else return USB_EXTRACTED */ +static int handle_usb(int connect_timeout) +{ + static struct event_queue q SHAREDBSS_ATTR; + struct queue_event ev; + int usb = USB_EXTRACTED; + long end_tick = 0; + + if (!usb_plugged()) + return USB_EXTRACTED; + + queue_init(&q, true); + usb_init(); + usb_start_monitoring(); + + /* Switch to verbose mode if not in it so that the status updates + * are shown */ + + /* TODO: Should we forgo any messages except the connect? It might be a + * charger, not a USB host. */ + verbose = true; + + printf("USB: Connecting"); + + if (connect_timeout != TIMEOUT_BLOCK) + end_tick = current_tick + connect_timeout; + + while (1) + { + /* Sleep no longer than 1/2s */ + queue_wait_w_tmo(&q, &ev, HZ/2); + + if (ev.id == SYS_USB_CONNECTED) + { + /* Got the message - wait for disconnect */ + printf("Bootloader USB mode"); + + usb = USB_HANDLED; + usb_acknowledge(SYS_USB_CONNECTED_ACK); + usb_wait_for_disconnect(&q); + break; + } + + if (connect_timeout != TIMEOUT_BLOCK && + TIME_AFTER(current_tick, end_tick)) + { + /* Timed out waiting for the connect */ + printf("USB: Timed out"); + break; + } + + if (!usb_plugged()) + break; /* Cable pulled */ + } + + usb_close(); + queue_delete(&q); + + return usb; +} +#else /* !HAVE_BOOTLOADER_USB_MODE */ + +#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \ + || defined (SANSA_VIEW) +/* Ignore cable state */ +static int handle_usb(int connect_timeout) +{ + return USB_EXTRACTED; + (void)connect_timeout; +} +#else +/* Return USB_INSERTED if cable present */ +static int handle_usb(int connect_timeout) +{ + int usb_retry = 0; + int usb = USB_EXTRACTED; + + usb_init(); + while (usb_drv_powered() && usb_retry < 5 && usb != USB_INSERTED) + { + usb_retry++; + sleep(HZ/4); + usb = usb_detect(); + } + + if (usb != USB_INSERTED) + usb = USB_EXTRACTED; + + return usb; + (void)connect_timeout; +} #endif +#endif /* HAVE_BOOTLOADER_USB_MODE */ + void* main(void) { int i; @@ -460,29 +557,33 @@ void* main(void) int rc; int num_partitions; struct partinfo* pinfo; -#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \ - || defined (SANSA_VIEW) -#if !defined(USE_ROCKBOX_USB) - int usb_retry = 0; -#endif - bool usb = false; -#else +#if !(CONFIG_STORAGE & STORAGE_SD) char buf[256]; unsigned short* identify_info; #endif + int usb = USB_EXTRACTED; chksum_crc32gentab (); system_init(); kernel_init(); +#ifdef HAVE_BOOTLOADER_USB_MODE + /* loader must service interrupts */ + enable_interrupt(IRQ_FIQ_STATUS); +#endif + lcd_init(); font_init(); show_logo(); adc_init(); +#ifdef HAVE_BOOTLOADER_USB_MODE + button_init_device(); +#else button_init(); +#endif #if defined(SANSA_E200) || defined(PHILIPS_SA9200) i2c_init(); _backlight_on(); @@ -506,20 +607,6 @@ void* main(void) verbose = true; } -#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) -#if !defined(USE_ROCKBOX_USB) - usb_init(); - while (usb_drv_powered() && usb_retry < 5 && !usb) - { - usb_retry++; - sleep(HZ/4); - usb = (usb_detect() == USB_INSERTED); - } - if (usb) - btn |= BOOTLOADER_BOOT_OF; -#endif /* USE_ROCKBOX_USB */ -#endif - lcd_setfont(FONT_SYSFIXED); printf("Rockbox boot loader"); @@ -560,6 +647,15 @@ void* main(void) i, pinfo->type, pinfo->size / 2048); } + /* Now that storage is initialized, check for USB connection */ + if ((btn & BOOTLOADER_BOOT_OF) == 0) + { + usb_pin_init(); + usb = handle_usb(HZ*2); + if (usb == USB_INSERTED) + btn |= BOOTLOADER_BOOT_OF; + } + /* Try loading Rockbox, if that fails, fall back to the OF */ if((btn & BOOTLOADER_BOOT_OF) == 0) { @@ -576,7 +672,7 @@ void* main(void) sleep(5*HZ); } else - return (void*)loadbuffer; + goto main_exit; } if(btn & BOOTLOADER_BOOT_OF) @@ -601,7 +697,7 @@ void* main(void) printf("Can't load from partition"); printf(strerror(rc)); } else { - return (void*)loadbuffer; + goto main_exit; } } else { printf("No hidden partition found."); @@ -615,7 +711,7 @@ void* main(void) printf("Can't load /System/OF.ebn"); printf(strerror(rc)); } else { - return (void*)loadbuffer; + goto main_exit; } #endif @@ -628,7 +724,7 @@ void* main(void) #if defined(SAMSUNG_YH925) lcd_reset(); #endif - return (void*)loadbuffer; + goto main_exit; } printf("Trying /System/OF.bin"); @@ -640,10 +736,17 @@ void* main(void) #if defined(SAMSUNG_YH925) lcd_reset(); #endif - return (void*)loadbuffer; + goto main_exit; } error(0, 0, true); } + +main_exit: +#ifdef HAVE_BOOTLOADER_USB_MODE + storage_close(); + system_prepare_fw_start(); +#endif + return (void*)loadbuffer; } |