summaryrefslogtreecommitdiff
path: root/firmware/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usb.c')
-rw-r--r--firmware/usb.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/firmware/usb.c b/firmware/usb.c
index 918d9802a3..10a7ae1bff 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -34,11 +34,11 @@
34#include "disk.h" 34#include "disk.h"
35#include "panic.h" 35#include "panic.h"
36#include "lcd.h" 36#include "lcd.h"
37#include "usb-target.h"
37#include "usb.h" 38#include "usb.h"
38#include "button.h" 39#include "button.h"
39#include "sprintf.h" 40#include "sprintf.h"
40#include "string.h" 41#include "string.h"
41#include "usb-target.h"
42#ifdef HAVE_USBSTACK 42#ifdef HAVE_USBSTACK
43#include "usb_core.h" 43#include "usb_core.h"
44#endif 44#endif
@@ -129,11 +129,13 @@ static inline void usb_slave_mode(bool on)
129#ifdef HAVE_PRIORITY_SCHEDULING 129#ifdef HAVE_PRIORITY_SCHEDULING
130 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME); 130 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
131#endif 131#endif
132 usb_enable(true); 132 usb_attach();
133 } 133 }
134 else /* usb_state == USB_INSERTED (only!) */ 134 else /* usb_state == USB_INSERTED (only!) */
135 { 135 {
136#ifndef USB_DETECT_BY_DRV
136 usb_enable(false); 137 usb_enable(false);
138#endif
137#ifdef HAVE_PRIORITY_SCHEDULING 139#ifdef HAVE_PRIORITY_SCHEDULING
138 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM); 140 thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
139#endif 141#endif
@@ -234,6 +236,26 @@ static void usb_thread(void)
234 (struct usb_transfer_completion_event_data*)ev.data); 236 (struct usb_transfer_completion_event_data*)ev.data);
235 break; 237 break;
236#endif 238#endif
239#ifdef USB_DETECT_BY_DRV
240 /* In this case, these events the handle cable insertion USB
241 * driver determines INSERTED/EXTRACTED state. */
242 case USB_POWERED:
243 /* Set the state to USB_POWERED for now and enable the driver
244 * to detect a bus reset only. If a bus reset is detected,
245 * USB_INSERTED will be received. */
246 usb_state = USB_POWERED;
247 usb_enable(true);
248 break;
249
250 case USB_UNPOWERED:
251 usb_enable(false);
252 /* This part shouldn't be obligatory for anything that can
253 * reliably detect removal of the data lines. USB_EXTRACTED
254 * could be posted on that event while bus power remains
255 * available. */
256 queue_post(&usb_queue, USB_EXTRACTED, 0);
257 break;
258#endif /* USB_DETECT_BY_DRV */
237 case USB_INSERTED: 259 case USB_INSERTED:
238#ifdef HAVE_LCD_BITMAP 260#ifdef HAVE_LCD_BITMAP
239 if(do_screendump_instead_of_usb) 261 if(do_screendump_instead_of_usb)
@@ -244,14 +266,14 @@ static void usb_thread(void)
244 } 266 }
245#endif 267#endif
246#ifdef HAVE_USB_POWER 268#ifdef HAVE_USB_POWER
247 if (usb_power_button()) 269 if(usb_power_button())
248 { 270 {
249 /* Only charging is desired */ 271 /* Only charging is desired */
250 usb_state = USB_POWERED; 272 usb_state = USB_POWERED;
251#ifdef HAVE_USBSTACK 273#ifdef HAVE_USBSTACK
252 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); 274 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
253 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); 275 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
254 usb_enable(true); 276 usb_attach();
255#endif 277#endif
256 break; 278 break;
257 } 279 }
@@ -272,7 +294,7 @@ static void usb_thread(void)
272 294
273 if(!exclusive_storage_access) 295 if(!exclusive_storage_access)
274 { 296 {
275 usb_enable(true); 297 usb_attach();
276 break; 298 break;
277 } 299 }
278#endif /* HAVE_USBSTACK */ 300#endif /* HAVE_USBSTACK */
@@ -304,7 +326,7 @@ static void usb_thread(void)
304 usb_state = USB_EXTRACTED; 326 usb_state = USB_EXTRACTED;
305 break; /* Connected for screendump only */ 327 break; /* Connected for screendump only */
306 } 328 }
307#endif /* HAVE_LCD_BITMAP */ 329#endif
308#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ 330#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
309#ifdef HAVE_USB_POWER 331#ifdef HAVE_USB_POWER
310 if(usb_state == USB_POWERED) 332 if(usb_state == USB_POWERED)
@@ -312,7 +334,7 @@ static void usb_thread(void)
312 usb_state = USB_EXTRACTED; 334 usb_state = USB_EXTRACTED;
313 break; 335 break;
314 } 336 }
315#endif /* HAVE_USB_POWER */ 337#endif
316#endif /* HAVE_USBSTACK */ 338#endif /* HAVE_USBSTACK */
317 if(usb_state == USB_INSERTED) 339 if(usb_state == USB_INSERTED)
318 { 340 {
@@ -324,9 +346,11 @@ static void usb_thread(void)
324 346
325 usb_state = USB_EXTRACTED; 347 usb_state = USB_EXTRACTED;
326#ifdef HAVE_USBSTACK 348#ifdef HAVE_USBSTACK
327 if (!exclusive_storage_access) 349 if(!exclusive_storage_access)
328 { 350 {
351#ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */
329 usb_enable(false); 352 usb_enable(false);
353#endif
330 break; 354 break;
331 } 355 }
332 356
@@ -392,19 +416,34 @@ static void usb_thread(void)
392#ifdef USB_STATUS_BY_EVENT 416#ifdef USB_STATUS_BY_EVENT
393void usb_status_event(int current_status) 417void usb_status_event(int current_status)
394{ 418{
395 /* Status should be USB_INSERTED or USB_EXTRACTED. 419 /* Status should be USB_POWERED, USB_UNPOWERED, USB_INSERTED or
420 * USB_EXTRACTED.
396 * Caller isn't expected to filter for changes in status. */ 421 * Caller isn't expected to filter for changes in status. */
397 if (usb_monitor_enabled && last_usb_status != current_status) 422 if(usb_monitor_enabled)
398 { 423 {
399 last_usb_status = current_status; 424 int oldstatus = disable_irq_save(); /* Dual-use function */
400 queue_post(&usb_queue, current_status, 0); 425
426 if(last_usb_status != current_status)
427 {
428 last_usb_status = current_status;
429 queue_post(&usb_queue, current_status, 0);
430 }
431
432 restore_irq(oldstatus);
401 } 433 }
402} 434}
403 435
404void usb_start_monitoring(void) 436void usb_start_monitoring(void)
405{ 437{
438 int status = usb_detect();
439#ifdef USB_DETECT_BY_DRV
440 /* USB detection begins by USB_POWERED, not USB_INSERTED. If it is
441 * USB_EXTRACTED, then nothing changes and post will be skipped. */
442 if(USB_INSERTED == status)
443 status = USB_POWERED;
444#endif
406 usb_monitor_enabled = true; 445 usb_monitor_enabled = true;
407 usb_status_event(usb_detect()); 446 usb_status_event(status);
408} 447}
409#else /* !USB_STATUS_BY_EVENT */ 448#else /* !USB_STATUS_BY_EVENT */
410static void usb_tick(void) 449static void usb_tick(void)