summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-05-26 10:25:50 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-09-25 06:49:11 -0400
commite75a3fb8c7ea947b54bde5567eb17c54124bb5b6 (patch)
tree055001c859cf6349eeecb2894809c275da0d4737 /firmware
parente4aec7d648de2553653b378518b5e90f29aeeac3 (diff)
downloadrockbox-e75a3fb8c7ea947b54bde5567eb17c54124bb5b6.tar.gz
rockbox-e75a3fb8c7ea947b54bde5567eb17c54124bb5b6.zip
usb: add debounce interval for USB status by event
This makes status by event debounce status changes over a 200ms period, which is what polling was already using. This is helpful on targets where events are excessively noisy and generate a lot of transitions during insertion and extraction. Change-Id: I0eae2cca93aaa865e33c94a1318c27e91c7f7c4b
Diffstat (limited to 'firmware')
-rw-r--r--firmware/usb.c44
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
68bool do_screendump_instead_of_usb = false; 71bool 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
586static 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
583void usb_status_event(int current_status) 608void 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
627static void usb_tick(void) 656static 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);