diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-01-02 13:09:08 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-01-02 20:11:03 +0000 |
commit | 83c23983841fd363a5a2c0e5cbd194110025226c (patch) | |
tree | 84fc753c07d29b9e8edc68d9d77665be885cc6dd | |
parent | af872b54ec3f8f7ad6ec111e4fe80dd2c7ac9946 (diff) | |
download | rockbox-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.c | 54 | ||||
-rw-r--r-- | firmware/export/config/erosqnative.h | 5 | ||||
-rw-r--r-- | firmware/export/config/fiiom3k.h | 5 | ||||
-rw-r--r-- | firmware/export/config/shanlingq1.h | 5 |
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; | |||
152 | bool usb_inited = false; | 152 | bool usb_inited = false; |
153 | bool disk_inited = false; | 153 | bool 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 */ | ||
157 | bool is_usb_connected = false; | ||
158 | |||
155 | /* Jump to loaded binary */ | 159 | /* Jump to loaded binary */ |
156 | void exec(void* dst, const void* src, size_t bytes) | 160 | void 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 | ||
214 | int 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 | |||
210 | void init_lcd(void) | 225 | void 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 | */ | ||
243 | void init_usb(void) | 244 | void 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) | |||
376 | void usb_mode(void) | 375 | void 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 | ||
451 | void bootloader_install(void) | 449 | void 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 |