diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/usb.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/firmware/usb.c b/firmware/usb.c index c4d07c5533..32f4902c7c 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -65,6 +65,9 @@ | |||
65 | #define USB_FULL_INIT | 65 | #define USB_FULL_INIT |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | /* USB detect debouncing interval (200ms taken from the usb polling code) */ | ||
69 | #define USB_DEBOUNCE_TIME (200*HZ/1000) | ||
70 | |||
68 | bool do_screendump_instead_of_usb = false; | 71 | bool do_screendump_instead_of_usb = false; |
69 | 72 | ||
70 | #if !defined(SIMULATOR) && !defined(USB_NONE) | 73 | #if !defined(SIMULATOR) && !defined(USB_NONE) |
@@ -580,8 +583,33 @@ void usb_charger_update(void) | |||
580 | #endif | 583 | #endif |
581 | 584 | ||
582 | #ifdef USB_STATUS_BY_EVENT | 585 | #ifdef USB_STATUS_BY_EVENT |
586 | static int usb_status_tmo_callback(struct timeout* tmo) | ||
587 | { | ||
588 | if(usb_monitor_enabled) | ||
589 | { | ||
590 | int current_status = usb_detect(); | ||
591 | int* last_status = (int*)tmo->data; | ||
592 | |||
593 | if(current_status != *last_status) | ||
594 | { | ||
595 | /* Signal changed during the timeout; wait longer */ | ||
596 | *last_status = current_status; | ||
597 | return USB_DEBOUNCE_TIME; | ||
598 | } | ||
599 | |||
600 | /* Signal is stable, post the event. The thread will deal with | ||
601 | * any spurious transitions (like inserted -> inserted). */ | ||
602 | queue_post(&usb_queue, current_status, 0); | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
583 | void usb_status_event(int current_status) | 608 | void usb_status_event(int current_status) |
584 | { | 609 | { |
610 | static struct timeout tmo; | ||
611 | static int last_status = USB_EXTRACTED; | ||
612 | |||
585 | /* Caller isn't expected to filter for changes in status. | 613 | /* Caller isn't expected to filter for changes in status. |
586 | * current_status: | 614 | * current_status: |
587 | * USB_INSERTED, USB_EXTRACTED | 615 | * USB_INSERTED, USB_EXTRACTED |
@@ -589,8 +617,9 @@ void usb_status_event(int current_status) | |||
589 | if(usb_monitor_enabled) | 617 | if(usb_monitor_enabled) |
590 | { | 618 | { |
591 | int oldstatus = disable_irq_save(); /* Dual-use function */ | 619 | int oldstatus = disable_irq_save(); /* Dual-use function */ |
592 | queue_remove_from_head(&usb_queue, current_status); | 620 | last_status = current_status; |
593 | queue_post(&usb_queue, current_status, 0); | 621 | timeout_register(&tmo, usb_status_tmo_callback, USB_DEBOUNCE_TIME, |
622 | (intptr_t)&last_status); | ||
594 | restore_irq(oldstatus); | 623 | restore_irq(oldstatus); |
595 | } | 624 | } |
596 | } | 625 | } |
@@ -626,7 +655,6 @@ void usb_firewire_connect_event(void) | |||
626 | 655 | ||
627 | static void usb_tick(void) | 656 | static void usb_tick(void) |
628 | { | 657 | { |
629 | #define NUM_POLL_READINGS (HZ/5) | ||
630 | static int usb_countdown = -1; | 658 | static int usb_countdown = -1; |
631 | static int last_usb_status = USB_EXTRACTED; | 659 | static int last_usb_status = USB_EXTRACTED; |
632 | #ifdef USB_FIREWIRE_HANDLING | 660 | #ifdef USB_FIREWIRE_HANDLING |
@@ -641,7 +669,7 @@ static void usb_tick(void) | |||
641 | if(current_firewire_status != last_firewire_status) | 669 | if(current_firewire_status != last_firewire_status) |
642 | { | 670 | { |
643 | last_firewire_status = current_firewire_status; | 671 | last_firewire_status = current_firewire_status; |
644 | firewire_countdown = NUM_POLL_READINGS; | 672 | firewire_countdown = USB_DEBOUNCE_TIME; |
645 | } | 673 | } |
646 | else | 674 | else |
647 | { | 675 | { |
@@ -649,8 +677,7 @@ static void usb_tick(void) | |||
649 | if(firewire_countdown >= 0) | 677 | if(firewire_countdown >= 0) |
650 | firewire_countdown--; | 678 | firewire_countdown--; |
651 | 679 | ||
652 | /* Report to the thread if we have had 3 identical status | 680 | /* Report status when the signal has been stable long enough */ |
653 | readings in a row */ | ||
654 | if(firewire_countdown == 0) | 681 | if(firewire_countdown == 0) |
655 | { | 682 | { |
656 | queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); | 683 | queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); |
@@ -664,7 +691,7 @@ static void usb_tick(void) | |||
664 | if(current_status != last_usb_status) | 691 | if(current_status != last_usb_status) |
665 | { | 692 | { |
666 | last_usb_status = current_status; | 693 | last_usb_status = current_status; |
667 | usb_countdown = NUM_POLL_READINGS; | 694 | usb_countdown = USB_DEBOUNCE_TIME; |
668 | } | 695 | } |
669 | else | 696 | else |
670 | { | 697 | { |
@@ -672,8 +699,7 @@ static void usb_tick(void) | |||
672 | if(usb_countdown >= 0) | 699 | if(usb_countdown >= 0) |
673 | usb_countdown--; | 700 | usb_countdown--; |
674 | 701 | ||
675 | /* Report to the thread if we have had 3 identical status | 702 | /* Report status when the signal has been stable long enough */ |
676 | readings in a row */ | ||
677 | if(usb_countdown == 0) | 703 | if(usb_countdown == 0) |
678 | { | 704 | { |
679 | queue_post(&usb_queue, current_status, 0); | 705 | queue_post(&usb_queue, current_status, 0); |