OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [fx2/] [src/] [lib/] [usb_common.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.