diff options
Diffstat (limited to 'firmware/usb.c')
-rw-r--r-- | firmware/usb.c | 210 |
1 files changed, 111 insertions, 99 deletions
diff --git a/firmware/usb.c b/firmware/usb.c index 763dd53e99..c748094396 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #define USB_INSERTED 1 | 38 | #define USB_INSERTED 1 |
39 | #define USB_EXTRACTED 2 | 39 | #define USB_EXTRACTED 2 |
40 | 40 | ||
41 | static int usb_state; | ||
42 | |||
41 | static char usb_stack[0x100]; | 43 | static char usb_stack[0x100]; |
42 | static struct event_queue usb_queue; | 44 | static struct event_queue usb_queue; |
43 | static bool last_usb_status; | 45 | static bool last_usb_status; |
@@ -63,30 +65,30 @@ static void usb_slave_mode(bool on) | |||
63 | 65 | ||
64 | if(on) | 66 | if(on) |
65 | { | 67 | { |
66 | DEBUGF("Entering USB slave mode\n"); | 68 | DEBUGF("Entering USB slave mode\n"); |
67 | ata_enable(false); | 69 | ata_enable(false); |
68 | usb_enable(true); | 70 | usb_enable(true); |
69 | } | 71 | } |
70 | else | 72 | else |
71 | { | 73 | { |
72 | DEBUGF("Leaving USB slave mode\n"); | 74 | DEBUGF("Leaving USB slave mode\n"); |
73 | 75 | ||
74 | /* Let the ISDx00 settle */ | 76 | /* Let the ISDx00 settle */ |
75 | sleep(HZ*1); | 77 | sleep(HZ*1); |
78 | |||
79 | usb_enable(false); | ||
76 | 80 | ||
77 | usb_enable(false); | 81 | rc = ata_init(); |
78 | 82 | if(rc) | |
79 | rc = ata_init(); | 83 | panicf("ata: %d",rc); |
80 | if(rc) | 84 | |
81 | panicf("ata: %d",rc); | 85 | pinfo = disk_init(); |
82 | 86 | if (!pinfo) | |
83 | pinfo = disk_init(); | 87 | panicf("disk: NULL"); |
84 | if (!pinfo) | 88 | |
85 | panicf("disk: NULL"); | 89 | rc = fat_mount(pinfo[0].start); |
86 | 90 | if(rc) | |
87 | rc = fat_mount(pinfo[0].start); | 91 | panicf("mount: %d",rc); |
88 | if(rc) | ||
89 | panicf("mount: %d",rc); | ||
90 | } | 92 | } |
91 | } | 93 | } |
92 | 94 | ||
@@ -100,70 +102,79 @@ static void usb_thread(void) | |||
100 | 102 | ||
101 | while(1) | 103 | while(1) |
102 | { | 104 | { |
103 | queue_wait(&usb_queue, &ev); | 105 | queue_wait(&usb_queue, &ev); |
104 | switch(ev.id) | 106 | switch(ev.id) |
105 | { | 107 | { |
106 | case USB_INSERTED: | 108 | case USB_INSERTED: |
107 | /* Tell all threads that they have to back off the ATA. | 109 | /* Tell all threads that they have to back off the ATA. |
108 | We subtract one for our own thread. */ | 110 | We subtract one for our own thread. */ |
109 | num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; | 111 | num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; |
110 | waiting_for_ack = true; | 112 | waiting_for_ack = true; |
111 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", | 113 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", |
112 | num_acks_to_expect); | 114 | num_acks_to_expect); |
113 | break; | 115 | break; |
114 | 116 | ||
115 | case SYS_USB_CONNECTED_ACK: | 117 | case SYS_USB_CONNECTED_ACK: |
116 | if(waiting_for_ack) | 118 | if(waiting_for_ack) |
117 | { | 119 | { |
118 | num_acks_to_expect--; | 120 | num_acks_to_expect--; |
119 | if(num_acks_to_expect == 0) | 121 | if(num_acks_to_expect == 0) |
120 | { | 122 | { |
121 | /* This is where we are supposed to be cool and keep | 123 | /* This is where we are supposed to be cool and keep |
122 | the Rockbox firmware running while the USB is enabled, | 124 | the Rockbox firmware running while the USB is enabled, |
123 | maybe even play some games and stuff. However, the | 125 | maybe even play some games and stuff. However, the |
124 | current firmware isn't quite ready for this yet. | 126 | current firmware isn't quite ready for this yet. |
125 | Let's just chicken out and reboot. */ | 127 | Let's just chicken out and reboot. */ |
126 | DEBUGF("All threads have acknowledged. Continuing...\n"); | 128 | DEBUGF("All threads have acknowledged. Continuing...\n"); |
127 | #ifdef USB_REALLY_BRAVE | 129 | #ifdef USB_REALLY_BRAVE |
128 | usb_slave_mode(true); | 130 | usb_slave_mode(true); |
131 | usb_state = USB_INSERTED; | ||
132 | usb_display_info(); | ||
129 | #else | 133 | #else |
130 | system_reboot(); | 134 | system_reboot(); |
131 | #endif | 135 | #endif |
132 | } | 136 | } |
133 | else | 137 | else |
134 | { | 138 | { |
135 | DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); | 139 | DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); |
136 | } | 140 | } |
137 | } | 141 | } |
138 | break; | 142 | break; |
143 | |||
144 | case USB_EXTRACTED: | ||
145 | if(usb_state == USB_INSERTED) | ||
146 | { | ||
147 | /* Only disable the USB mode if we really have enabled it | ||
148 | some threads might not have acknowledged the | ||
149 | insertion */ | ||
150 | usb_slave_mode(false); | ||
151 | } | ||
139 | 152 | ||
140 | case USB_EXTRACTED: | 153 | usb_state = USB_EXTRACTED; |
141 | /* First disable the USB mode */ | 154 | |
142 | usb_slave_mode(false); | 155 | /* Tell all threads that we are back in business */ |
143 | 156 | num_acks_to_expect = | |
144 | /* Tell all threads that we are back in business */ | 157 | queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1; |
145 | num_acks_to_expect = | 158 | waiting_for_ack = true; |
146 | queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1; | 159 | DEBUGF("USB extracted. Waiting for ack from %d threads...\n", |
147 | waiting_for_ack = true; | 160 | num_acks_to_expect); |
148 | DEBUGF("USB extracted. Waiting for ack from %d threads...\n", | 161 | break; |
149 | num_acks_to_expect); | 162 | |
150 | break; | 163 | case SYS_USB_DISCONNECTED_ACK: |
151 | 164 | if(waiting_for_ack) | |
152 | case SYS_USB_DISCONNECTED_ACK: | 165 | { |
153 | if(waiting_for_ack) | 166 | num_acks_to_expect--; |
154 | { | 167 | if(num_acks_to_expect == 0) |
155 | num_acks_to_expect--; | 168 | { |
156 | if(num_acks_to_expect == 0) | 169 | DEBUGF("All threads have acknowledged. We're in business.\n"); |
157 | { | 170 | } |
158 | DEBUGF("All threads have acknowledged. We're in business.\n"); | 171 | else |
159 | } | 172 | { |
160 | else | 173 | DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); |
161 | { | 174 | } |
162 | DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); | 175 | } |
163 | } | 176 | break; |
164 | } | 177 | } |
165 | break; | ||
166 | } | ||
167 | } | 178 | } |
168 | } | 179 | } |
169 | 180 | ||
@@ -174,21 +185,21 @@ static void usb_tick(void) | |||
174 | if(usb_monitor_enabled) | 185 | if(usb_monitor_enabled) |
175 | { | 186 | { |
176 | #ifdef ARCHOS_RECORDER | 187 | #ifdef ARCHOS_RECORDER |
177 | /* If AN2 reads more than about 500, the USB is inserted */ | 188 | /* If AN2 reads more than about 500, the USB is inserted */ |
178 | current_status = (adc_read(2) > 500); | 189 | current_status = (adc_read(2) > 500); |
179 | #else | 190 | #else |
180 | current_status = (PADR & 0x8000)?false:true; | 191 | current_status = (PADR & 0x8000)?false:true; |
181 | #endif | 192 | #endif |
182 | 193 | ||
183 | /* Only report when the status has changed */ | 194 | /* Only report when the status has changed */ |
184 | if(current_status != last_usb_status) | 195 | if(current_status != last_usb_status) |
185 | { | 196 | { |
186 | last_usb_status = current_status; | 197 | last_usb_status = current_status; |
187 | if(current_status) | 198 | if(current_status) |
188 | queue_post(&usb_queue, USB_INSERTED, NULL); | 199 | queue_post(&usb_queue, USB_INSERTED, NULL); |
189 | else | 200 | else |
190 | queue_post(&usb_queue, USB_EXTRACTED, NULL); | 201 | queue_post(&usb_queue, USB_EXTRACTED, NULL); |
191 | } | 202 | } |
192 | } | 203 | } |
193 | } | 204 | } |
194 | 205 | ||
@@ -199,6 +210,7 @@ void usb_acknowledge(int id) | |||
199 | 210 | ||
200 | void usb_init(void) | 211 | void usb_init(void) |
201 | { | 212 | { |
213 | usb_state = USB_EXTRACTED; | ||
202 | usb_monitor_enabled = false; | 214 | usb_monitor_enabled = false; |
203 | 215 | ||
204 | usb_enable(false); | 216 | usb_enable(false); |
@@ -219,12 +231,12 @@ void usb_wait_for_disconnect(struct event_queue *q) | |||
219 | /* Don't return until we get SYS_USB_DISCONNECTED */ | 231 | /* Don't return until we get SYS_USB_DISCONNECTED */ |
220 | while(1) | 232 | while(1) |
221 | { | 233 | { |
222 | queue_wait(q, &ev); | 234 | queue_wait(q, &ev); |
223 | if(ev.id == SYS_USB_DISCONNECTED) | 235 | if(ev.id == SYS_USB_DISCONNECTED) |
224 | { | 236 | { |
225 | usb_acknowledge(SYS_USB_DISCONNECTED_ACK); | 237 | usb_acknowledge(SYS_USB_DISCONNECTED_ACK); |
226 | return; | 238 | return; |
227 | } | 239 | } |
228 | } | 240 | } |
229 | } | 241 | } |
230 | 242 | ||