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

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [firmware/] [lib/] [usb_common.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 nussgipfel
/* -*- c++ -*- */
2
/*
3
 * Copyright 2003 Free Software Foundation, Inc.
4
 *
5
 * This file is part of GNU Radio
6
 *
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)
10
 * any later version.
11
 *
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.
16
 *
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.
21
 */
22
 
23
#include <stdint.h>
24
#include <stdio.h>
25
 
26
#include "usb_common.h"
27
#include "fx2regs.h"
28
#include "syncdelay.h"
29
#include "fx2utils.h"
30
#include "isr.h"
31
#include "usb_descriptors.h"
32
#include "usb_requests.h"
33
#include "debugprint.h"
34
#ifdef USB_DFU_SUPPORT
35
#include "usb_dfu.h"
36
#endif
37
 
38
extern xdata char str0[];
39
extern xdata char str1[];
40
extern xdata char str2[];
41
extern xdata char str3[];
42
extern xdata char str4[];
43
extern xdata char str5[];
44
 
45
 
46
#define MSB(x)  (((unsigned short) x) >> 8)
47
#define LSB(x)  (((unsigned short) x) & 0xff)
48
 
49
volatile bit _usb_got_SUDAV;
50
 
51
unsigned char   _usb_config = 0;
52
unsigned char   _usb_alt_setting = 0;    // FIXME really 1/interface
53
 
54
xdata unsigned char *current_device_descr;
55
xdata unsigned char *current_devqual_descr;
56
xdata unsigned char *current_config_descr;
57
xdata unsigned char *other_config_descr;
58
 
59
static void
60
setup_descriptors (void)
61
{
62
  if (USBCS & bmHSM){           // high speed mode
63
    current_device_descr  = high_speed_device_descr;
64
    current_devqual_descr = high_speed_devqual_descr;
65
    current_config_descr  = high_speed_config_descr;
66
    other_config_descr    = full_speed_config_descr;
67
  }
68
  else {
69
    current_device_descr  = full_speed_device_descr;
70
    current_devqual_descr = full_speed_devqual_descr;
71
    current_config_descr  = full_speed_config_descr;
72
    other_config_descr    = high_speed_config_descr;
73
  }
74
 
75
  // whack the type fields
76
  // FIXME, may not be required.
77
  // current_config_descr[1] = DT_CONFIG;
78
  // other_config_descr[1]   = DT_OTHER_SPEED;
79
}
80
 
81
static void
82
isr_SUDAV (void) interrupt
83
{
84
  clear_usb_irq ();
85
  _usb_got_SUDAV = 1;
86
}
87
 
88
static void
89
isr_USBRESET (void) interrupt
90
{
91
  clear_usb_irq ();
92
  setup_descriptors ();
93
 
94
#ifdef USB_DFU_SUPPORT
95
  usb_dfu_state = DFU_STATE_appIDLE;
96
#endif
97
}
98
 
99
static void
100
isr_HIGHSPEED (void) interrupt
101
{
102
  clear_usb_irq ();
103
  setup_descriptors ();
104
#ifdef USB_DFU_SUPPORT
105
  usb_dfu_state = DFU_STATE_appIDLE;
106
#endif
107
}
108
 
109
void
110
usb_install_handlers (void)
111
{
112
  setup_descriptors ();     // ensure that they're set before use
113
 
114
  hook_uv (UV_SUDAV,     (unsigned short) isr_SUDAV);
115
  hook_uv (UV_USBRESET,  (unsigned short) isr_USBRESET);
116
  hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
117
 
118
  USBIE = bmSUDAV | bmURES | bmHSGRANT;
119
}
120
 
121
/** On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8
122
 * This doesn't check to see that they're enabled */
123
unsigned char
124
plausible_endpoint (unsigned char ep)
125
{
126
  ep &= ~0x80;  // ignore direction bit
127
 
128
  if (ep > 8)
129
    return 0;
130
 
131
  if (ep == 1)
132
    return 1;
133
 
134
  return (ep & 0x1) == 0;        // must be even
135
}
136
 
137
/** return pointer to control and status register for endpoint.
138
 * only called with plausible_endpoints */
139
xdata volatile unsigned char *
140
epcs (unsigned char ep)
141
{
142
  if (ep == 0x01)               // ep1 has different in and out CS regs
143
    return &EP1OUTCS;
144
 
145
  if (ep == 0x81)
146
    return &EP1INCS;
147
 
148
  ep &= ~0x80;                  // ignore direction bit
149
 
150
  if (ep == 0x00)               // ep0
151
    return &EP0CS;
152
 
153
  //return EP2CS + (ep >> 1);   // 2, 4, 6, 8 are consecutive
154
  return &EP1INCS + (ep >> 1);  // EP2CS -1; 2, 4, 6, 8 are consecutive
155
}
156
 
157
#ifdef USB_DFU_SUPPORT
158
static void
159
setup_dfu_descriptors (void)
160
{
161
  current_device_descr  = dfu_mode_device_descr;
162
  current_config_descr  = dfu_mode_config_descr;
163
}
164
 
165
static void
166
isr_DFURESET (void) interrupt
167
{
168
  clear_usb_irq ();
169
  setup_dfu_descriptors ();
170
  usb_dfu_state = DFU_STATE_dfuIDLE;
171
}
172
 
173
void
174
usb_toggle_dfu_handlers (void)
175
{
176
  if(usb_dfu_state == DFU_STATE_appIDLE){
177
    hook_uv (UV_USBRESET,  (unsigned short) isr_DFURESET);
178
    hook_uv (UV_HIGHSPEED, (unsigned short) isr_DFURESET);
179
  }
180
  else {
181
  hook_uv (UV_USBRESET,  (unsigned short) isr_USBRESET);
182
  hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
183
  usb_dfu_state = DFU_STATE_appIDLE;
184
  }
185
}
186
#endif
187
 
188
void
189
usb_handle_setup_packet (void)
190
{
191
  _usb_got_SUDAV = 0;
192
 
193
  switch (bRequestType & bmRT_TYPE_MASK){
194
 
195
  case bmRT_TYPE_CLASS:
196
    // call the application code class requests.
197
    // If it handles the command it returns non-zero
198
 
199
    if (!app_class_cmd ())
200
      fx2_stall_ep0 ();
201
    break;
202
 
203
  case bmRT_TYPE_RESERVED:
204
    fx2_stall_ep0 ();           // we don't handle these.  indicate error
205
    break;
206
 
207
  case bmRT_TYPE_VENDOR:
208
    // call the application code for vendor commands.
209
    // If it handles the command it returns non-zero
210
 
211
    if (!app_vendor_cmd ())
212
      fx2_stall_ep0 ();
213
    break;
214
 
215
  case bmRT_TYPE_STD:
216
    // these are the standard requests...
217
 
218
    if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
219
 
220
      ////////////////////////////////////
221
      //    handle the IN requests
222
      ////////////////////////////////////
223
 
224
      switch (bRequest){
225
 
226
      case RQ_GET_CONFIG:
227
        EP0BUF[0] = _usb_config; // FIXME app should handle
228
        EP0BCH = 0;
229
        EP0BCL = 1;
230
        break;
231
 
232
      // --------------------------------
233
 
234
      case RQ_GET_INTERFACE:
235
        EP0BUF[0] = _usb_alt_setting;    // FIXME app should handle
236
        EP0BCH = 0;
237
        EP0BCL = 1;
238
        break;
239
 
240
      // --------------------------------
241
 
242
      case RQ_GET_DESCR:
243
        switch (wValueH){
244
 
245
        case DT_DEVICE:
246
          SUDPTRH = MSB (current_device_descr);
247
          SUDPTRL = LSB (current_device_descr);
248
          break;
249
 
250
        case DT_DEVQUAL:
251
          SUDPTRH = MSB (current_devqual_descr);
252
          SUDPTRL = LSB (current_devqual_descr);
253
          break;
254
 
255
        case DT_CONFIG:
256
          if (0 && wValueL != 1) // FIXME only a single configuration
257
            fx2_stall_ep0 ();
258
          else {
259
            SUDPTRH = MSB (current_config_descr);
260
            SUDPTRL = LSB (current_config_descr);
261
          }
262
          break;
263
 
264
        case DT_OTHER_SPEED:
265
          if (0 && wValueL != 1) // FIXME only a single configuration
266
            fx2_stall_ep0 ();
267
          else {
268
            SUDPTRH = MSB (other_config_descr);
269
            SUDPTRL = LSB (other_config_descr);
270
          }
271
          break;
272
 
273
        case DT_STRING:
274
          if (wValueL >= nstring_descriptors)
275
            fx2_stall_ep0 ();
276
          else {
277
            xdata char *p = string_descriptors[wValueL];
278
            SUDPTRH = MSB (p);
279
            SUDPTRL = LSB (p);
280
          }
281
          break;
282
 
283
#ifdef USB_DFU_SUPPORT
284
        case DT_DFU_FUNCTIONAL:
285
          SUDPTRH = MSB (dfu_mode_functional_descr);
286
          SUDPTRL = LSB (dfu_mode_functional_descr);
287
          break;
288
#endif
289
 
290
        default:
291
          fx2_stall_ep0 ();     // invalid request
292
          break;
293
        }
294
        break;
295
 
296
      // --------------------------------
297
 
298
      case RQ_GET_STATUS:
299
        switch (bRequestType & bmRT_RECIP_MASK){
300
        case bmRT_RECIP_DEVICE:
301
          EP0BUF[0] = bmGSDA_SELF_POWERED;       // FIXME app should handle
302
          EP0BUF[1] = 0;
303
          EP0BCH = 0;
304
          EP0BCL = 2;
305
          break;
306
 
307
        case bmRT_RECIP_INTERFACE:
308
          EP0BUF[0] = 0;
309
          EP0BUF[1] = 0;
310
          EP0BCH = 0;
311
          EP0BCL = 2;
312
          break;
313
 
314
        case bmRT_RECIP_ENDPOINT:
315
          if (plausible_endpoint (wIndexL)){
316
            EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;
317
            EP0BUF[1] = 0;
318
            EP0BCH = 0;
319
            EP0BCL = 2;
320
          }
321
          else
322
            fx2_stall_ep0 ();
323
          break;
324
 
325
        default:
326
          fx2_stall_ep0 ();
327
          break;
328
        }
329
        break;
330
 
331
      // --------------------------------
332
 
333
      case RQ_SYNCH_FRAME:      // not implemented
334
      default:
335
        fx2_stall_ep0 ();
336
        break;
337
      }
338
    }
339
 
340
    else {
341
 
342
      ////////////////////////////////////
343
      //    handle the OUT requests
344
      ////////////////////////////////////
345
 
346
      switch (bRequest){
347
 
348
      case RQ_SET_CONFIG:
349
        _usb_config = wValueL;          // FIXME app should handle
350
        break;
351
 
352
      case RQ_SET_INTERFACE:
353
        _usb_alt_setting = wValueL;     // FIXME app should handle
354
        break;
355
 
356
      // --------------------------------
357
 
358
      case RQ_CLEAR_FEATURE:
359
        switch (bRequestType & bmRT_RECIP_MASK){
360
 
361
        case bmRT_RECIP_DEVICE:
362
          switch (wValueL){
363
          case FS_DEV_REMOTE_WAKEUP:
364
          default:
365
            fx2_stall_ep0 ();
366
          }
367
          break;
368
 
369
        case bmRT_RECIP_ENDPOINT:
370
          if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){
371
            *epcs (wIndexL) &= ~bmEPSTALL;
372
            EP2CS &= ~bmEPSTALL;
373
            fx2_reset_data_toggle (wIndexL);
374
          }
375
          else
376
            fx2_stall_ep0 ();
377
          break;
378
 
379
        default:
380
          fx2_stall_ep0 ();
381
          break;
382
        }
383
        break;
384
 
385
      // --------------------------------
386
 
387
      case RQ_SET_FEATURE:
388
        switch (bRequestType & bmRT_RECIP_MASK){
389
 
390
        case bmRT_RECIP_DEVICE:
391
          switch (wValueL){
392
          case FS_TEST_MODE:
393
            // hardware handles this after we complete SETUP phase handshake
394
            break;
395
 
396
          case FS_DEV_REMOTE_WAKEUP:
397
          default:
398
            fx2_stall_ep0 ();
399
            break;
400
          }
401
        }
402
        break;
403
 
404
      case bmRT_RECIP_ENDPOINT:
405
        switch (wValueL){
406
        case FS_ENDPOINT_HALT:
407
          if (plausible_endpoint (wIndexL))
408
            *epcs (wIndexL) |= bmEPSTALL;
409
          else
410
            fx2_stall_ep0 ();
411
          break;
412
 
413
        default:
414
          fx2_stall_ep0 ();
415
          break;
416
        }
417
        break;
418
 
419
      // --------------------------------
420
 
421
      case RQ_SET_ADDRESS:      // handled by fx2 hardware
422
      case RQ_SET_DESCR:        // not implemented
423
      default:
424
        fx2_stall_ep0 ();
425
      }
426
 
427
    }
428
    break;
429
 
430
  }     // bmRT_TYPE_MASK
431
 
432
  // ack handshake phase of device request
433
  EP0CS |= bmHSNAK;
434
}

powered by: WebSVN 2.1.0

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