source: trunk/FirmwareFX2/fx2/usb_common.c@ 137

Last change on this file since 137 was 25, checked in by demin, 15 years ago

remove OE

File size: 8.6 KB
Line 
1/* -*- c++ -*- */
2/*-----------------------------------------------------------------------------
3 * Common USB code for FX2
4 *-----------------------------------------------------------------------------
5 * Code taken from USRP2 firmware (GNU Radio Project), version 3.0.2,
6 * Copyright 2003 Free Software Foundation, Inc.
7 *-----------------------------------------------------------------------------
8 * This code is part of usbjtag. usbjtag is free software; you can redistribute
9 * it and/or modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the License,
11 * or (at your option) any later version. usbjtag is distributed in the hope
12 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. You should have received a
15 * copy of the GNU General Public License along with this program in the file
16 * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin
17 * St, Fifth Floor, Boston, MA 02110-1301 USA
18 *-----------------------------------------------------------------------------
19 */
20
21#include "usb_common.h"
22#include "fx2regs.h"
23#include "syncdelay.h"
24#include "fx2utils.h"
25#include "isr.h"
26#include "usb_descriptors.h"
27#include "usb_requests.h"
28
29extern xdata char str0[];
30extern xdata char str1[];
31extern xdata char str2[];
32extern xdata char str3[];
33extern xdata char str4[];
34extern xdata char str5[];
35
36volatile bit _usb_got_SUDAV;
37
38unsigned char _usb_config = 0;
39unsigned char _usb_alt_setting = 0; // FIXME really 1/interface
40
41xdata unsigned char *current_device_descr;
42xdata unsigned char *current_devqual_descr;
43xdata unsigned char *current_config_descr;
44xdata unsigned char *other_config_descr;
45
46static void
47setup_descriptors (void)
48{
49 if (USBCS & bmHSM){ // high speed mode
50 current_device_descr = high_speed_device_descr;
51 current_devqual_descr = high_speed_devqual_descr;
52 current_config_descr = high_speed_config_descr;
53 other_config_descr = full_speed_config_descr;
54 EP8AUTOINLENH = 0x02; SYNCDELAY; // Size in bytes of the IN data automatically commited (512 bytes here)
55 EP8AUTOINLENL = 0x00; SYNCDELAY; // Can use signal PKTEND if you want to commit a shorter packet
56 }
57 else {
58 current_device_descr = full_speed_device_descr;
59 current_devqual_descr = full_speed_devqual_descr;
60 current_config_descr = full_speed_config_descr;
61 other_config_descr = high_speed_config_descr;
62 EP8AUTOINLENH = 0x00; SYNCDELAY; // Size in bytes of the IN data automatically commited (64 bytes here)
63 EP8AUTOINLENL = 0x40; SYNCDELAY; // Can use signal PKTEND if you want to commit a shorter packet
64 }
65
66 // whack the type fields
67 // FIXME, may not be required.
68 // current_config_descr[1] = DT_CONFIG;
69 // other_config_descr[1] = DT_OTHER_SPEED;
70}
71
72static void
73isr_SUDAV (void) interrupt
74{
75 clear_usb_irq ();
76 _usb_got_SUDAV = 1;
77}
78
79static void
80isr_USBRESET (void) interrupt
81{
82 clear_usb_irq ();
83 setup_descriptors ();
84}
85
86static void
87isr_HIGHSPEED (void) interrupt
88{
89 clear_usb_irq ();
90 setup_descriptors ();
91}
92
93void
94usb_install_handlers (void)
95{
96 setup_descriptors (); // ensure that they're set before use
97
98 hook_uv (UV_SUDAV, (unsigned short) isr_SUDAV);
99 hook_uv (UV_USBRESET, (unsigned short) isr_USBRESET);
100 hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
101
102 USBIE = bmSUDAV | bmURES | bmHSGRANT;
103}
104
105// On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8
106// This doesn't check to see that they're enabled
107
108unsigned char
109plausible_endpoint (unsigned char ep)
110{
111 ep &= ~0x80; // ignore direction bit
112
113 if (ep > 8)
114 return 0;
115
116 if (ep == 1)
117 return 1;
118
119 return (ep & 0x1) == 0; // must be even
120}
121
122// return pointer to control and status register for endpoint.
123// only called with plausible_endpoints
124
125xdata volatile unsigned char *
126epcs (unsigned char ep)
127{
128 if (ep == 0x01) // ep1 has different in and out CS regs
129 return EP1OUTCS;
130
131 if (ep == 0x81)
132 return EP1INCS;
133
134 ep &= ~0x80; // ignore direction bit
135
136 if (ep == 0x00) // ep0
137 return EP0CS;
138
139 return EP2CS + (ep >> 1); // 2, 4, 6, 8 are consecutive
140}
141
142void
143usb_handle_setup_packet (void)
144{
145 _usb_got_SUDAV = 0;
146
147 // handle the standard requests...
148
149 switch (bRequestType & bmRT_TYPE_MASK){
150
151 case bmRT_TYPE_CLASS:
152 case bmRT_TYPE_RESERVED:
153 fx2_stall_ep0 (); // we don't handle these. indicate error
154 break;
155
156 case bmRT_TYPE_VENDOR:
157 // call the application code.
158 // If it handles the command it returns non-zero
159
160 if (!app_vendor_cmd ())
161 fx2_stall_ep0 ();
162 break;
163
164 case bmRT_TYPE_STD:
165 // these are the standard requests...
166
167 if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
168
169 ////////////////////////////////////
170 // handle the IN requests
171 ////////////////////////////////////
172
173 switch (bRequest){
174
175 case RQ_GET_CONFIG:
176 EP0BUF[0] = _usb_config; // FIXME app should handle
177 EP0BCH = 0;
178 EP0BCL = 1;
179 break;
180
181 // --------------------------------
182
183 case RQ_GET_INTERFACE:
184 EP0BUF[0] = _usb_alt_setting; // FIXME app should handle
185 EP0BCH = 0;
186 EP0BCL = 1;
187 break;
188
189 // --------------------------------
190
191 case RQ_GET_DESCR:
192 switch (wValueH){
193
194 case DT_DEVICE:
195 SUDPTRH = MSB (current_device_descr);
196 SUDPTRL = LSB (current_device_descr);
197 break;
198
199 case DT_DEVQUAL:
200 SUDPTRH = MSB (current_devqual_descr);
201 SUDPTRL = LSB (current_devqual_descr);
202 break;
203
204 case DT_CONFIG:
205 if (0 && wValueL != 1) // FIXME only a single configuration
206 fx2_stall_ep0 ();
207 else {
208 SUDPTRH = MSB (current_config_descr);
209 SUDPTRL = LSB (current_config_descr);
210 }
211 break;
212
213 case DT_OTHER_SPEED:
214 if (0 && wValueL != 1) // FIXME only a single configuration
215 fx2_stall_ep0 ();
216 else {
217 SUDPTRH = MSB (other_config_descr);
218 SUDPTRL = LSB (other_config_descr);
219 }
220 break;
221
222 case DT_STRING:
223 if (wValueL >= nstring_descriptors)
224 fx2_stall_ep0 ();
225 else {
226 xdata char *p = string_descriptors[wValueL];
227 SUDPTRH = MSB (p);
228 SUDPTRL = LSB (p);
229 }
230 break;
231
232 default:
233 fx2_stall_ep0 (); // invalid request
234 break;
235 }
236 break;
237
238 // --------------------------------
239
240 case RQ_GET_STATUS:
241 switch (bRequestType & bmRT_RECIP_MASK){
242 case bmRT_RECIP_DEVICE:
243 EP0BUF[0] = 0;
244 EP0BUF[1] = 0;
245 EP0BCH = 0;
246 EP0BCL = 2;
247 break;
248
249 case bmRT_RECIP_INTERFACE:
250 EP0BUF[0] = 0;
251 EP0BUF[1] = 0;
252 EP0BCH = 0;
253 EP0BCL = 2;
254 break;
255
256 case bmRT_RECIP_ENDPOINT:
257 if (plausible_endpoint (wIndexL)){
258 EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;
259 EP0BUF[1] = 0;
260 EP0BCH = 0;
261 EP0BCL = 2;
262 }
263 else
264 fx2_stall_ep0 ();
265 break;
266
267 default:
268 fx2_stall_ep0 ();
269 break;
270 }
271 break;
272
273 // --------------------------------
274
275 case RQ_SYNCH_FRAME: // not implemented
276 default:
277 fx2_stall_ep0 ();
278 break;
279 }
280 }
281
282 else {
283
284 ////////////////////////////////////
285 // handle the OUT requests
286 ////////////////////////////////////
287
288 switch (bRequest){
289
290 case RQ_SET_CONFIG:
291 _usb_config = wValueL; // FIXME app should handle
292 break;
293
294 case RQ_SET_INTERFACE:
295 _usb_alt_setting = wValueL; // FIXME app should handle
296 break;
297
298 // --------------------------------
299
300 case RQ_CLEAR_FEATURE:
301 switch (bRequestType & bmRT_RECIP_MASK){
302
303 case bmRT_RECIP_DEVICE:
304 switch (wValueL){
305 case FS_DEV_REMOTE_WAKEUP:
306 default:
307 fx2_stall_ep0 ();
308 }
309 break;
310
311 case bmRT_RECIP_ENDPOINT:
312 if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){
313 *epcs (wIndexL) &= ~bmEPSTALL;
314 fx2_reset_data_toggle (wIndexL);
315 }
316 else
317 fx2_stall_ep0 ();
318 break;
319
320 default:
321 fx2_stall_ep0 ();
322 break;
323 }
324 break;
325
326 // --------------------------------
327
328 case RQ_SET_FEATURE:
329 switch (bRequestType & bmRT_RECIP_MASK){
330
331 case bmRT_RECIP_DEVICE:
332 switch (wValueL){
333 case FS_TEST_MODE:
334 // hardware handles this after we complete SETUP phase handshake
335 break;
336
337 case FS_DEV_REMOTE_WAKEUP:
338 default:
339 fx2_stall_ep0 ();
340 break;
341 }
342 }
343 break;
344
345 case bmRT_RECIP_ENDPOINT:
346 switch (wValueL){
347 case FS_ENDPOINT_HALT:
348 if (plausible_endpoint (wIndexL))
349 *epcs (wIndexL) |= bmEPSTALL;
350 else
351 fx2_stall_ep0 ();
352 break;
353
354 default:
355 fx2_stall_ep0 ();
356 break;
357 }
358 break;
359
360 // --------------------------------
361
362 case RQ_SET_ADDRESS: // handled by fx2 hardware
363 case RQ_SET_DESCR: // not implemented
364 default:
365 fx2_stall_ep0 ();
366 }
367
368 }
369 break;
370
371 } // bmRT_TYPE_MASK
372
373 // ack handshake phase of device request
374 EP0CS |= bmHSNAK;
375}
Note: See TracBrowser for help on using the repository browser.