summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
36 36
37#ifndef SIMULATOR 37#ifndef SIMULATOR
38 38
39/* Messages from usb_tick */
39#define USB_INSERTED 1 40#define USB_INSERTED 1
40#define USB_EXTRACTED 2 41#define USB_EXTRACTED 2
41 42
43/* Thread states */
44#define EXTRACTING 1
45#define EXTRACTED 2
46#define INSERTED 3
47#define INSERTING 4
48
49/* The ADC tick reads one channel per tick, and we want to check 3 successive
50 readings on the USB voltage channel. This doesn't apply to the Player, but
51 debouncing the USB detection port won't hurt us either. */
52#define NUM_POLL_READINGS (NUM_ADC_CHANNELS * 3)
53static int countdown;
54
42static int usb_state; 55static int usb_state;
43 56
44static char usb_stack[0x100]; 57static char usb_stack[0x200];
45static struct event_queue usb_queue; 58static struct event_queue usb_queue;
46static bool last_usb_status; 59static bool last_usb_status;
47static bool usb_monitor_enabled; 60static bool usb_monitor_enabled;
@@ -100,7 +113,7 @@ static void usb_thread(void)
100 struct event ev; 113 struct event ev;
101 114
102 waiting_for_ack = false; 115 waiting_for_ack = false;
103 116
104 while(1) 117 while(1)
105 { 118 {
106 queue_wait(&usb_queue, &ev); 119 queue_wait(&usb_queue, &ev);
@@ -109,7 +122,8 @@ static void usb_thread(void)
109 case USB_INSERTED: 122 case USB_INSERTED:
110 /* Tell all threads that they have to back off the ATA. 123 /* Tell all threads that they have to back off the ATA.
111 We subtract one for our own thread. */ 124 We subtract one for our own thread. */
112 num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; 125 num_acks_to_expect =
126 queue_broadcast(SYS_USB_CONNECTED, NULL) - 1;
113 waiting_for_ack = true; 127 waiting_for_ack = true;
114 DEBUGF("USB inserted. Waiting for ack from %d threads...\n", 128 DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
115 num_acks_to_expect); 129 num_acks_to_expect);
@@ -121,12 +135,7 @@ static void usb_thread(void)
121 num_acks_to_expect--; 135 num_acks_to_expect--;
122 if(num_acks_to_expect == 0) 136 if(num_acks_to_expect == 0)
123 { 137 {
124 /* This is where we are supposed to be cool and keep 138 DEBUGF("All threads have acknowledged the connect.\n");
125 the Rockbox firmware running while the USB is enabled,
126 maybe even play some games and stuff. However, the
127 current firmware isn't quite ready for this yet.
128 Let's just chicken out and reboot. */
129 DEBUGF("All threads have acknowledged. Continuing...\n");
130#ifdef USB_REALLY_BRAVE 139#ifdef USB_REALLY_BRAVE
131 usb_slave_mode(true); 140 usb_slave_mode(true);
132 usb_state = USB_INSERTED; 141 usb_state = USB_INSERTED;
@@ -137,7 +146,8 @@ static void usb_thread(void)
137 } 146 }
138 else 147 else
139 { 148 {
140 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); 149 DEBUGF("usb: got ack, %d to go...\n",
150 num_acks_to_expect);
141 } 151 }
142 } 152 }
143 break; 153 break;
@@ -167,11 +177,13 @@ static void usb_thread(void)
167 num_acks_to_expect--; 177 num_acks_to_expect--;
168 if(num_acks_to_expect == 0) 178 if(num_acks_to_expect == 0)
169 { 179 {
170 DEBUGF("All threads have acknowledged. We're in business.\n"); 180 DEBUGF("All threads have acknowledged. "
181 "We're in business.\n");
171 } 182 }
172 else 183 else
173 { 184 {
174 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); 185 DEBUGF("usb: got ack, %d to go...\n",
186 num_acks_to_expect);
175 } 187 }
176 } 188 }
177 break; 189 break;
@@ -186,8 +198,7 @@ static void usb_tick(void)
186 if(usb_monitor_enabled) 198 if(usb_monitor_enabled)
187 { 199 {
188#ifdef ARCHOS_RECORDER 200#ifdef ARCHOS_RECORDER
189 /* If AN2 reads more than about 500, the USB is inserted */ 201 current_status = (adc_read(ADC_USB_POWER) > 500)?true:false;
190 current_status = (adc_read(2) > 500);
191#else 202#else
192 current_status = (PADR & 0x8000)?false:true; 203 current_status = (PADR & 0x8000)?false:true;
193#endif 204#endif
@@ -196,10 +207,23 @@ static void usb_tick(void)
196 if(current_status != last_usb_status) 207 if(current_status != last_usb_status)
197 { 208 {
198 last_usb_status = current_status; 209 last_usb_status = current_status;
199 if(current_status) 210 countdown = NUM_POLL_READINGS;
200 queue_post(&usb_queue, USB_INSERTED, NULL); 211 }
201 else 212 else
202 queue_post(&usb_queue, USB_EXTRACTED, NULL); 213 {
214 /* Count down until it gets negative */
215 if(countdown >= 0)
216 countdown--;
217
218 /* Report to the thread if we have had 3 identical status
219 readings in a row */
220 if(countdown == 0)
221 {
222 if(current_status)
223 queue_post(&usb_queue, USB_INSERTED, NULL);
224 else
225 queue_post(&usb_queue, USB_EXTRACTED, NULL);
226 }
203 } 227 }
204 } 228 }
205} 229}
@@ -213,6 +237,7 @@ void usb_init(void)
213{ 237{
214 usb_state = USB_EXTRACTED; 238 usb_state = USB_EXTRACTED;
215 usb_monitor_enabled = false; 239 usb_monitor_enabled = false;
240 countdown = -1;
216 241
217 usb_enable(false); 242 usb_enable(false);
218 243