summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-01-02 13:09:08 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-01-02 20:11:03 +0000
commit83c23983841fd363a5a2c0e5cbd194110025226c (patch)
tree84fc753c07d29b9e8edc68d9d77665be885cc6dd
parentaf872b54ec3f8f7ad6ec111e4fe80dd2c7ac9946 (diff)
downloadrockbox-83c23983841fd363a5a2c0e5cbd194110025226c.tar.gz
rockbox-83c23983841fd363a5a2c0e5cbd194110025226c.zip
x1000: Fix USB connection problems in bootloader
This problem actually had nothing to do with USB boot; it's because the cable is plugged in when the USB mode menu item is selected. The USB thread detected the select button press and went into charge-only mode (as it usually does when you hold down a key in Rockbox). This is fixed by having the USB thread ignore most keys in the bootloader. USB connect events are delivered via the button queue, and there were also cases where the connection could be missed if the event happened within another UI screen. This should also be fixed. Change-Id: I077d705a6ac845c8713219eee45d26aa6addfa61
-rw-r--r--bootloader/x1000.c54
-rw-r--r--firmware/export/config/erosqnative.h5
-rw-r--r--firmware/export/config/fiiom3k.h5
-rw-r--r--firmware/export/config/shanlingq1.h5
4 files changed, 41 insertions, 28 deletions
diff --git a/bootloader/x1000.c b/bootloader/x1000.c
index a7c7692ac8..675a1c1840 100644
--- a/bootloader/x1000.c
+++ b/bootloader/x1000.c
@@ -152,6 +152,10 @@ bool lcd_inited = false;
152bool usb_inited = false; 152bool usb_inited = false;
153bool disk_inited = false; 153bool disk_inited = false;
154 154
155/* Set to true if a SYS_USB_CONNECTED event is seen
156 * Set to false if a SYS_USB_DISCONNECTED event is seen */
157bool is_usb_connected = false;
158
155/* Jump to loaded binary */ 159/* Jump to loaded binary */
156void exec(void* dst, const void* src, size_t bytes) 160void exec(void* dst, const void* src, size_t bytes)
157 __attribute__((noinline, noreturn, section(".icode"))); 161 __attribute__((noinline, noreturn, section(".icode")));
@@ -207,6 +211,17 @@ void splash(long delay, const char* msg)
207 splash2(delay, msg, NULL); 211 splash2(delay, msg, NULL);
208} 212}
209 213
214int get_button(int timeout)
215{
216 int btn = button_get_w_tmo(timeout);
217 if(btn == SYS_USB_CONNECTED)
218 is_usb_connected = true;
219 else if(btn == SYS_USB_DISCONNECTED)
220 is_usb_connected = false;
221
222 return btn;
223}
224
210void init_lcd(void) 225void init_lcd(void)
211{ 226{
212 if(lcd_inited) 227 if(lcd_inited)
@@ -226,20 +241,6 @@ void init_lcd(void)
226 lcd_inited = true; 241 lcd_inited = true;
227} 242}
228 243
229/* TODO: This does not work properly after a USB boot.
230 *
231 * The USB core is not properly reset by just re-initializing it, and I can't
232 * figure out how to make it work. Setting the DWC_DCTL.SDIS bit will force a
233 * disconnect (the usb-designware driver does this already as part of its init
234 * but it doesn't seem to cause a disconnect).
235 *
236 * But the host still doesn't detect us properly when we reconnect. Linux gives
237 * messages "usb 1-3: config 1 has no interfaces?" in dmesg and no mass storage
238 * interfaces show up.
239 *
240 * Re-plugging the cable seems to reset everything to a working state and there
241 * are no issues, but that's annoying.
242 */
243void init_usb(void) 244void init_usb(void)
244{ 245{
245 if(usb_inited) 246 if(usb_inited)
@@ -255,10 +256,9 @@ int init_disk(void)
255 if(disk_inited) 256 if(disk_inited)
256 return 0; 257 return 0;
257 258
258 button_clear_queue();
259 while(!storage_present(IF_MD(0))) { 259 while(!storage_present(IF_MD(0))) {
260 splash2(0, "Insert SD card", "Press " BL_QUIT_NAME " for recovery"); 260 splash2(0, "Insert SD card", "Press " BL_QUIT_NAME " for recovery");
261 if(button_get_w_tmo(HZ/4) == BL_QUIT) 261 if(get_button(HZ/4) == BL_QUIT)
262 return -1; 262 return -1;
263 } 263 }
264 264
@@ -320,8 +320,7 @@ void recovery_menu(void)
320 lcd_update(); 320 lcd_update();
321 321
322 /* handle input */ 322 /* handle input */
323 button_clear_queue(); 323 switch(get_button(TIMEOUT_BLOCK)) {
324 switch(button_get(true)) {
325 case BL_SELECT: { 324 case BL_SELECT: {
326 if(recovery_items[selection].action) 325 if(recovery_items[selection].action)
327 recovery_items[selection].action(); 326 recovery_items[selection].action();
@@ -376,19 +375,19 @@ void boot_rockbox(void)
376void usb_mode(void) 375void usb_mode(void)
377{ 376{
378 init_usb(); 377 init_usb();
379 splash2(0, "Waiting for USB", "Press " BL_QUIT_NAME " to go back");
380 378
381 while(1) { 379 if(!is_usb_connected)
382 int btn = button_get(true); 380 splash2(0, "Waiting for USB", "Press " BL_QUIT_NAME " to go back");
383 if(btn == SYS_USB_CONNECTED) 381
384 break; 382 while(!is_usb_connected)
385 else if(btn == BL_QUIT) 383 if(get_button(TIMEOUT_BLOCK) == BL_QUIT)
386 return; 384 return;
387 }
388 385
389 splash(0, "USB mode"); 386 splash(0, "USB mode");
390 usb_acknowledge(SYS_USB_CONNECTED_ACK); 387 usb_acknowledge(SYS_USB_CONNECTED_ACK);
391 while(button_get(true) != SYS_USB_DISCONNECTED); 388
389 while(is_usb_connected)
390 get_button(TIMEOUT_BLOCK);
392 391
393 splash(3*HZ, "USB disconnected"); 392 splash(3*HZ, "USB disconnected");
394} 393}
@@ -444,8 +443,7 @@ void bootloader_action(int which)
444 const char* msg2 = "Press " BL_QUIT_NAME " to continue"; 443 const char* msg2 = "Press " BL_QUIT_NAME " to continue";
445 splash2(0, msg1, msg2); 444 splash2(0, msg1, msg2);
446 445
447 button_clear_queue(); 446 while(get_button(TIMEOUT_BLOCK) != BL_QUIT);
448 while(button_get(true) != BL_QUIT);
449} 447}
450 448
451void bootloader_install(void) 449void bootloader_install(void)
diff --git a/firmware/export/config/erosqnative.h b/firmware/export/config/erosqnative.h
index 17a2b250f2..a76e8f6426 100644
--- a/firmware/export/config/erosqnative.h
+++ b/firmware/export/config/erosqnative.h
@@ -122,6 +122,11 @@
122#define USB_WRITE_BUFFER_SIZE (128 * 1024) 122#define USB_WRITE_BUFFER_SIZE (128 * 1024)
123#endif 123#endif
124 124
125#ifdef BOOTLOADER
126/* Ignore on any key can cause surprising USB issues in the bootloader */
127# define USBPOWER_BTN_IGNORE (~(BUTTON_PREV|BUTTON_NEXT))
128#endif
129
125/* Rockbox capabilities */ 130/* Rockbox capabilities */
126#define HAVE_VOLUME_IN_LIST 131#define HAVE_VOLUME_IN_LIST
127#define HAVE_FAT16SUPPORT 132#define HAVE_FAT16SUPPORT
diff --git a/firmware/export/config/fiiom3k.h b/firmware/export/config/fiiom3k.h
index 558ff41dd7..45c2150208 100644
--- a/firmware/export/config/fiiom3k.h
+++ b/firmware/export/config/fiiom3k.h
@@ -123,6 +123,11 @@
123#define USB_WRITE_BUFFER_SIZE (128 * 1024) 123#define USB_WRITE_BUFFER_SIZE (128 * 1024)
124#endif 124#endif
125 125
126#ifdef BOOTLOADER
127/* Ignore on any key can cause surprising USB issues in the bootloader */
128# define USBPOWER_BTN_IGNORE (~(BUTTON_VOL_UP|BUTTON_VOL_DOWN))
129#endif
130
126/* Rockbox capabilities */ 131/* Rockbox capabilities */
127#define HAVE_FAT16SUPPORT 132#define HAVE_FAT16SUPPORT
128#define HAVE_ALBUMART 133#define HAVE_ALBUMART
diff --git a/firmware/export/config/shanlingq1.h b/firmware/export/config/shanlingq1.h
index 18786e9a4b..1355c1824e 100644
--- a/firmware/export/config/shanlingq1.h
+++ b/firmware/export/config/shanlingq1.h
@@ -113,6 +113,11 @@
113#define USB_WRITE_BUFFER_SIZE (128 * 1024) 113#define USB_WRITE_BUFFER_SIZE (128 * 1024)
114#endif 114#endif
115 115
116#ifdef BOOTLOADER
117/* Ignore on any key can cause surprising USB issues in the bootloader */
118# define USBPOWER_BTN_IGNORE (~(BUTTON_PREV|BUTTON_NEXT))
119#endif
120
116/* Rockbox capabilities */ 121/* Rockbox capabilities */
117#define HAVE_FAT16SUPPORT 122#define HAVE_FAT16SUPPORT
118#define HAVE_ALBUMART 123#define HAVE_ALBUMART