summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-07-01 19:32:54 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-07-01 19:32:54 +0000
commit0ee7d85d12a6f9c61e59233d730a1ea5b1d7a8b3 (patch)
tree3417f8bcf96b50f1771f454adec53e4af75210d2
parent3c1d26b01a19b9d1b330fe10d325dc9536281ef4 (diff)
More robust, debounced USB detection
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1286 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/usb.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/firmware/usb.c b/firmware/usb.c
index c353815c98..7516cebd6b 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -36,12 +36,25 @@
#ifndef SIMULATOR
+/* Messages from usb_tick */
#define USB_INSERTED 1
#define USB_EXTRACTED 2
+/* Thread states */
+#define EXTRACTING 1
+#define EXTRACTED 2
+#define INSERTED 3
+#define INSERTING 4
+
+/* The ADC tick reads one channel per tick, and we want to check 3 successive
+ readings on the USB voltage channel. This doesn't apply to the Player, but
+ debouncing the USB detection port won't hurt us either. */
+#define NUM_POLL_READINGS (NUM_ADC_CHANNELS * 3)
+static int countdown;
+
static int usb_state;
-static char usb_stack[0x100];
+static char usb_stack[0x200];
static struct event_queue usb_queue;
static bool last_usb_status;
static bool usb_monitor_enabled;
@@ -100,7 +113,7 @@ static void usb_thread(void)
struct event ev;
waiting_for_ack = false;
-
+
while(1)
{
queue_wait(&usb_queue, &ev);
@@ -109,7 +122,8 @@ static void usb_thread(void)
case USB_INSERTED:
/* Tell all threads that they have to back off the ATA.
We subtract one for our own thread. */
- num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1;
+ num_acks_to_expect =
+ queue_broadcast(SYS_USB_CONNECTED, NULL) - 1;
waiting_for_ack = true;
DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
num_acks_to_expect);
@@ -121,12 +135,7 @@ static void usb_thread(void)
num_acks_to_expect--;
if(num_acks_to_expect == 0)
{
- /* This is where we are supposed to be cool and keep
- the Rockbox firmware running while the USB is enabled,
- maybe even play some games and stuff. However, the
- current firmware isn't quite ready for this yet.
- Let's just chicken out and reboot. */
- DEBUGF("All threads have acknowledged. Continuing...\n");
+ DEBUGF("All threads have acknowledged the connect.\n");
#ifdef USB_REALLY_BRAVE
usb_slave_mode(true);
usb_state = USB_INSERTED;
@@ -137,7 +146,8 @@ static void usb_thread(void)
}
else
{
- DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect);
+ DEBUGF("usb: got ack, %d to go...\n",
+ num_acks_to_expect);
}
}
break;
@@ -167,11 +177,13 @@ static void usb_thread(void)
num_acks_to_expect--;
if(num_acks_to_expect == 0)
{
- DEBUGF("All threads have acknowledged. We're in business.\n");
+ DEBUGF("All threads have acknowledged. "
+ "We're in business.\n");
}
else
{
- DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect);
+ DEBUGF("usb: got ack, %d to go...\n",
+ num_acks_to_expect);
}
}
break;
@@ -186,8 +198,7 @@ static void usb_tick(void)
if(usb_monitor_enabled)
{
#ifdef ARCHOS_RECORDER
- /* If AN2 reads more than about 500, the USB is inserted */
- current_status = (adc_read(2) > 500);
+ current_status = (adc_read(ADC_USB_POWER) > 500)?true:false;
#else
current_status = (PADR & 0x8000)?false:true;
#endif
@@ -196,10 +207,23 @@ static void usb_tick(void)
if(current_status != last_usb_status)
{
last_usb_status = current_status;
- if(current_status)
- queue_post(&usb_queue, USB_INSERTED, NULL);
- else
- queue_post(&usb_queue, USB_EXTRACTED, NULL);
+ countdown = NUM_POLL_READINGS;
+ }
+ else
+ {
+ /* Count down until it gets negative */
+ if(countdown >= 0)
+ countdown--;
+
+ /* Report to the thread if we have had 3 identical status
+ readings in a row */
+ if(countdown == 0)
+ {
+ if(current_status)
+ queue_post(&usb_queue, USB_INSERTED, NULL);
+ else
+ queue_post(&usb_queue, USB_EXTRACTED, NULL);
+ }
}
}
}
@@ -213,6 +237,7 @@ void usb_init(void)
{
usb_state = USB_EXTRACTED;
usb_monitor_enabled = false;
+ countdown = -1;
usb_enable(false);