3 * Copyright 2003 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
23 #include "usb_common.h"
25 #include "syncdelay.h"
28 #include "usb_descriptors.h"
29 #include "usb_requests.h"
31 extern xdata char str0[];
32 extern xdata char str1[];
33 extern xdata char str2[];
34 extern xdata char str3[];
35 extern xdata char str4[];
36 extern xdata char str5[];
39 #define bRequestType SETUPDAT[0]
40 #define bRequest SETUPDAT[1]
41 #define wValueL SETUPDAT[2]
42 #define wValueH SETUPDAT[3]
43 #define wIndexL SETUPDAT[4]
44 #define wIndexH SETUPDAT[5]
45 #define wLengthL SETUPDAT[6]
46 #define wLengthH SETUPDAT[7]
48 #define MSB(x) (((unsigned short) x) >> 8)
49 #define LSB(x) (((unsigned short) x) & 0xff)
51 volatile bit _usb_got_SUDAV;
53 unsigned char _usb_config = 0;
54 unsigned char _usb_alt_setting = 0; // FIXME really 1/interface
56 xdata unsigned char *current_device_descr;
57 xdata unsigned char *current_devqual_descr;
58 xdata unsigned char *current_config_descr;
59 xdata unsigned char *other_config_descr;
62 setup_descriptors (void)
64 if (USBCS & bmHSM){ // high speed mode
65 current_device_descr = high_speed_device_descr;
66 current_devqual_descr = high_speed_devqual_descr;
67 current_config_descr = high_speed_config_descr;
68 other_config_descr = full_speed_config_descr;
71 current_device_descr = full_speed_device_descr;
72 current_devqual_descr = full_speed_devqual_descr;
73 current_config_descr = full_speed_config_descr;
74 other_config_descr = high_speed_config_descr;
77 // whack the type fields
78 // FIXME, may not be required.
79 // current_config_descr[1] = DT_CONFIG;
80 // other_config_descr[1] = DT_OTHER_SPEED;
84 isr_SUDAV (void) interrupt
91 isr_USBRESET (void) interrupt
98 isr_HIGHSPEED (void) interrupt
101 setup_descriptors ();
105 usb_install_handlers (void)
107 setup_descriptors (); // ensure that they're set before use
109 hook_uv (UV_SUDAV, (unsigned short) isr_SUDAV);
110 hook_uv (UV_USBRESET, (unsigned short) isr_USBRESET);
111 hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
113 USBIE = bmSUDAV | bmURES | bmHSGRANT;
116 // On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8
117 // This doesn't check to see that they're enabled
120 plausible_endpoint (unsigned char ep)
122 ep &= ~0x80; // ignore direction bit
130 return (ep & 0x1) == 0; // must be even
133 // return pointer to control and status register for endpoint.
134 // only called with plausible_endpoints
136 xdata volatile unsigned char *
137 epcs (unsigned char ep)
139 if (ep == 0x01) // ep1 has different in and out CS regs
145 ep &= ~0x80; // ignore direction bit
147 if (ep == 0x00) // ep0
150 return EP2CS + (ep >> 1); // 2, 4, 6, 8 are consecutive
154 usb_handle_setup_packet (void)
158 // handle the standard requests...
160 switch (bRequestType & bmRT_TYPE_MASK){
162 case bmRT_TYPE_CLASS:
163 case bmRT_TYPE_RESERVED:
164 fx2_stall_ep0 (); // we don't handle these. indicate error
167 case bmRT_TYPE_VENDOR:
168 // call the application code.
169 // If it handles the command it returns non-zero
171 if (!app_vendor_cmd ())
176 // these are the standard requests...
178 if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
180 ////////////////////////////////////
181 // handle the IN requests
182 ////////////////////////////////////
187 EP0BUF[0] = _usb_config; // FIXME app should handle
192 // --------------------------------
194 case RQ_GET_INTERFACE:
195 EP0BUF[0] = _usb_alt_setting; // FIXME app should handle
200 // --------------------------------
206 SUDPTRH = MSB (current_device_descr);
207 SUDPTRL = LSB (current_device_descr);
211 SUDPTRH = MSB (current_devqual_descr);
212 SUDPTRL = LSB (current_devqual_descr);
216 if (0 && wValueL != 1) // FIXME only a single configuration
219 SUDPTRH = MSB (current_config_descr);
220 SUDPTRL = LSB (current_config_descr);
225 if (0 && wValueL != 1) // FIXME only a single configuration
228 SUDPTRH = MSB (other_config_descr);
229 SUDPTRL = LSB (other_config_descr);
234 if (wValueL >= nstring_descriptors)
237 xdata char *p = string_descriptors[wValueL];
244 fx2_stall_ep0 (); // invalid request
249 // --------------------------------
252 switch (bRequestType & bmRT_RECIP_MASK){
253 case bmRT_RECIP_DEVICE:
254 EP0BUF[0] = bmGSDA_SELF_POWERED; // FIXME app should handle
260 case bmRT_RECIP_INTERFACE:
267 case bmRT_RECIP_ENDPOINT:
268 if (plausible_endpoint (wIndexL)){
269 EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;
284 // --------------------------------
286 case RQ_SYNCH_FRAME: // not implemented
295 ////////////////////////////////////
296 // handle the OUT requests
297 ////////////////////////////////////
302 _usb_config = wValueL; // FIXME app should handle
305 case RQ_SET_INTERFACE:
306 _usb_alt_setting = wValueL; // FIXME app should handle
309 // --------------------------------
311 case RQ_CLEAR_FEATURE:
312 switch (bRequestType & bmRT_RECIP_MASK){
314 case bmRT_RECIP_DEVICE:
316 case FS_DEV_REMOTE_WAKEUP:
322 case bmRT_RECIP_ENDPOINT:
323 if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){
324 *epcs (wIndexL) &= ~bmEPSTALL;
325 fx2_reset_data_toggle (wIndexL);
337 // --------------------------------
340 switch (bRequestType & bmRT_RECIP_MASK){
342 case bmRT_RECIP_DEVICE:
345 // hardware handles this after we complete SETUP phase handshake
348 case FS_DEV_REMOTE_WAKEUP:
356 case bmRT_RECIP_ENDPOINT:
358 case FS_ENDPOINT_HALT:
359 if (plausible_endpoint (wIndexL))
360 *epcs (wIndexL) |= bmEPSTALL;
371 // --------------------------------
373 case RQ_SET_ADDRESS: // handled by fx2 hardware
374 case RQ_SET_DESCR: // not implemented
384 // ack handshake phase of device request