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

Subversion Repositories gecko4

[/] [gecko4/] [trunk/] [GECKO4com/] [fx2_firmware/] [c/] [usb_common.c] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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