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

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [firmware/] [src/] [usb_tmc.c] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 nussgipfel
/* GECKO3COM
2
 *
3
 * Copyright (C) 2008 by
4
 *   ___    ____  _   _
5
 *  (  _`\ (  __)( ) ( )
6
 *  | (_) )| (_  | |_| |   Berne University of Applied Sciences
7
 *  |  _ <'|  _) |  _  |   School of Engineering and
8
 *  | (_) )| |   | | | |   Information Technology
9
 *  (____/'(_)   (_) (_)
10
 *
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation, either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
 
25
/*********************************************************************/
26
/** \file     usb_tmc.c
27
 *********************************************************************
28
 * \brief     The USB Test and Measurement Class (TMC) functions.
29
 *
30
 * \author    Christoph Zimmermann bfh.ch
31
 * \date      2009-02-04
32
 *
33
*/
34
 
35
#include <stdint.h>
36
 
37
#include "fx2regs.h"
38
#include "isr.h"
39
#include "usb_requests.h"
40
#include "usb_descriptors.h"
41
#include "usb_tmc.h"
42
#include "debugprint.h"
43
 
44
/* GECKO3COM specific includes */
45
#include "gecko3com_common.h"
46
#include "gecko3com_interfaces.h"
47
#include "gecko3com_gpif.h"
48
#include "fpga_load.h"
49
 
50
 
51
volatile static TMC_Status usb_tmc_status;
52
volatile TMC_State usb_tmc_state;
53
volatile idata TMC_Transfer_Info usb_tmc_transfer;
54
 
55
volatile idata IEEE488_status_registers ieee488_status;
56
 
57
/** This constant contains the device capabilities according to the TMC specification, Ref.: Table 37 */
58
volatile const USB_TMC_Capabilities USB_TMC_CAPABILITIES = {
59
  TMC_STATUS_SUCCESS,
60
      0,
61
      0x00,   /* BCD version number of TMC specification, 1.00 */
62
      0x01,
63
      HAS_INDICATOR_PULSE,
64
      0,
65
        {0,0,0,0,0,0},
66
    /* place here USB488 subclass capabilities */
67
    0x00,  /* BCD version number of USB488 specification, 1.00 */
68
      0x01,
69
      0,
70
      0,
71
        {0,0,0,0,0,0,0,0}
72
};
73
 
74
void init_usb_tmc(){
75
  usb_tmc_transfer.bTag = 0;
76
  usb_tmc_transfer.transfer_size = 0;
77
  usb_tmc_transfer.new_transfer = 0;
78
  usb_tmc_transfer.nbytes_rxd = 0;
79
  usb_tmc_transfer.nbytes_txd = 0;
80
 
81
  usb_tmc_status = TMC_STATUS_SUCCESS;
82
  usb_tmc_state = TMC_STATE_IDLE;
83
 
84
  ieee488_status.EventStatusRegister = bmPOWER_ON;
85
  ieee488_status.EventStatusEnable = 0;
86
  ieee488_status.StatusByteRegister = 0;
87
  ieee488_status.ServiceRequestEnable = 0;
88
}
89
 
90
uint8_t IEEE488_status_query(idata IEEE488_status_registers *status){
91
 
92
  uint8_t local_status, local_enable;
93
 
94
  local_status = status->EventStatusRegister;
95
  local_enable =  status->EventStatusEnable;
96
 
97
  if(local_status & local_enable)
98
    local_status |= 0x20; /* set the ESB bit */
99
  else
100
    local_status &= !0xDF;
101
 
102
  status->EventStatusRegister = local_status;
103
 
104
  local_status = status->StatusByteRegister;
105
  local_enable = status->ServiceRequestEnable;
106
 
107
  if((local_status &= 0xBF) & (local_enable & 0xBF)) {
108
    local_status |= 0x40; /* set the MSS bit */
109
    status->StatusByteRegister = local_status;
110
  }
111
 
112
  return local_status;
113
}
114
 
115
uint8_t usb_handle_tmc_packet (void){
116
 
117
  if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
118
    /*********************************
119
     *    handle the TMC IN requests
120
     ********************************/
121
 
122
    switch (bRequest){
123
 
124
    case INITIATE_ABORT_BULK_OUT:
125
      /* --------------------------------------------------------------------*/
126
      /* abort GECKO3COM specific stuff */
127
      if( flLOCAL == GECKO3COM_REMOTE) {
128
        usb_tmc_status = TMC_STATUS_SUCCESS;
129
        usb_tmc_state = TMC_STATE_IDLE;
130
        abort_gpif();
131
      }
132
 
133
      /* check if the active transfer has the requested bTag value */
134
      else if(usb_tmc_transfer.bTag == wValueL) {
135
        usb_tmc_status = TMC_STATUS_SUCCESS;
136
        usb_tmc_state = TMC_STATE_IDLE;
137
 
138
        /* reset OUT FIFOs */
139
        FIFORESET = bmNAKALL;                    SYNCDELAY;
140
        FIFORESET = bmNAKALL | USB_TMC_EP_OUT;   SYNCDELAY;
141
 
142
        /* because we use quad buffering we have to flush all for buffers */
143
        OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
144
        OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
145
        OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
146
        OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
147
 
148
        FIFORESET = 0;               SYNCDELAY;
149
      }
150
 
151
      else {
152
        usb_tmc_status = TMC_STATUS_TRANSFER_NOT_IN_PROGRESS;
153
      }
154
 
155
      EP0BUF[0] = usb_tmc_status;
156
      EP0BUF[1] = usb_tmc_transfer.bTag;
157
      EP0BCH = 0;
158
      EP0BCL = 2;
159
      break;
160
 
161
    case CHECK_ABORT_BULK_OUT_STATUS:
162
      /* send number of transmitted bytes */
163
      usb_tmc_status = TMC_STATUS_SUCCESS;
164
      EP0BUF[0] = usb_tmc_status;
165
      EP0BUF[1] = 0;
166
      EP0BUF[2] = 0;
167
      EP0BUF[3] = 0;
168
      EP0BUF[4] = (usb_tmc_transfer.nbytes_rxd & 0x0000FF);
169
      EP0BUF[5] = (usb_tmc_transfer.nbytes_rxd & 0x00FF00)>>8;
170
      EP0BUF[6] = (usb_tmc_transfer.nbytes_rxd & 0xFF0000)>>16;
171
      EP0BUF[7] = usb_tmc_transfer.nbytes_rxd >>24;
172
      EP0BCH = 0;
173
      EP0BCL = 8;
174
      break;
175
 
176
    case INITIATE_ABORT_BULK_IN:
177
      /* --------------------------------------------------------------------*/
178
      /* abort GECKO3COM specific stuff */
179
      if( flLOCAL == GECKO3COM_REMOTE) {
180
        usb_tmc_status = TMC_STATUS_SUCCESS;
181
        usb_tmc_state = TMC_STATE_IDLE;
182
 
183
        abort_gpif();
184
 
185
        /* reset IN FIFOs */
186
        FIFORESET = bmNAKALL;                   SYNCDELAY;
187
        FIFORESET = bmNAKALL | USB_TMC_EP_IN;   SYNCDELAY;
188
 
189
        INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
190 28 nussgipfel
        INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
191
        INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
192
        INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
193 9 nussgipfel
 
194
        FIFORESET = 0;               SYNCDELAY;
195
 
196
      }
197
 
198
      /* check if the active transfer has the requested bTag value */
199
      else if(usb_tmc_transfer.bTag == wValueL) {
200
        usb_tmc_status = TMC_STATUS_SUCCESS;
201
        usb_tmc_state = TMC_STATE_IDLE;
202
        IEEE488_clear_mav();
203
      }
204
 
205
      else {
206
        usb_tmc_status = TMC_STATUS_TRANSFER_NOT_IN_PROGRESS;
207
      }
208
 
209
      EP0BUF[0] = usb_tmc_status;
210
      EP0BUF[1] = wValueL;
211
      EP0BCH = 0;
212
      EP0BCL = 2;
213
      break;
214
 
215
    case CHECK_ABORT_BULK_IN_STATUS:
216
      /* send number of transmitted bytes */
217
      usb_tmc_status = TMC_STATUS_SUCCESS;
218
      EP0BUF[0] = usb_tmc_status;
219
      EP0BUF[1] = 0;
220
      EP0BUF[2] = 0;
221
      EP0BUF[3] = 0;
222
      EP0BUF[4] = (usb_tmc_transfer.nbytes_txd & 0x0000FF);
223
      EP0BUF[5] = (usb_tmc_transfer.nbytes_txd & 0x00FF00)>>8;
224
      EP0BUF[6] = (usb_tmc_transfer.nbytes_txd & 0xFF0000)>>16;
225
      EP0BUF[7] = usb_tmc_transfer.nbytes_txd >>24;
226
      EP0BCH = 0;
227
      EP0BCL = 8;
228
      break;
229
 
230
    case INITIATE_CLEAR:
231
      usb_tmc_status = TMC_STATUS_SUCCESS;
232
      usb_tmc_state = TMC_STATE_IDLE;
233
      IEEE488_clear_mav();
234
 
235
      /* --------------------------------------------------------------------*/
236
      /* abort GECKO3COM specific stuff */
237
      if( flLOCAL == GECKO3COM_REMOTE) {
238
        deactivate_gpif();
239
        flLOCAL = GECKO3COM_LOCAL;
240
 
241
        /* configure the fpga interface for configuration */
242
        init_fpga_interface();
243
      }
244
 
245
      /* --------------------------------------------------------------------*/
246
 
247
 
248
      /* reset FIFOs */
249
      FIFORESET = bmNAKALL;                    SYNCDELAY;
250
      FIFORESET = bmNAKALL | USB_TMC_EP_OUT;   SYNCDELAY;
251
      FIFORESET = bmNAKALL | USB_TMC_EP_IN;    SYNCDELAY;
252
 
253
      /* because we use quad buffering we have to flush all for buffers */
254
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
255
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
256
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
257
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
258
 
259 28 nussgipfel
      INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
260
      INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
261
      INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
262
      INPKTEND = bmSKIP | USB_TMC_EP_IN;      SYNCDELAY;
263
 
264 9 nussgipfel
      FIFORESET = 0;                 SYNCDELAY;
265
 
266 28 nussgipfel
      EP2CS &= ~bmEPSTALL;
267
      EP6CS &= ~bmEPSTALL;
268
 
269 9 nussgipfel
      EP0BUF[0] = usb_tmc_status;
270
      EP0BCH = 0;
271
      EP0BCL = 1;
272
 
273
      break;
274
 
275
    case CHECK_CLEAR_STATUS:
276
      usb_tmc_status = TMC_STATUS_SUCCESS;
277
      EP0BUF[0] = usb_tmc_status;
278
      EP0BUF[1] = 0; /* no queued data in bulk-in buffer */
279
 
280
      EP0BCH = 0;
281
      EP0BCL = 2;
282
      break;
283
 
284
    case GET_CAPABILITIES:
285
      usb_tmc_status = TMC_STATUS_SUCCESS;
286
      {
287
        uint8_t i = 0;
288 16 nussgipfel
        //code char *local_capabilities = &((code char)USB_TMC_CAPABILITIES);
289 9 nussgipfel
        for(i;i<0x18;i++){
290 16 nussgipfel
          //EP0BUF[i] = (&(code char)USB_TMC_CAPABILITIES)[i];
291
          //EP0BUF[i] = local_capabilities[i];
292
          EP0BUF[i] = (&(code unsigned char)USB_TMC_CAPABILITIES)[i];
293 9 nussgipfel
        }
294
        EP0BCH = 0;
295
        EP0BCL = 0x18;
296
      }
297
      break;
298
 
299
    case INDICATOR_PULSE:
300
      /* GECKO3COM spcific command to set external LED */
301
      set_led_ext(ORANGE);
302
      usb_tmc_status = TMC_STATUS_SUCCESS;
303
      EP0BUF[0] = usb_tmc_status;
304
      EP0BCH = 0;
305
      EP0BCL = 1;
306
      break;
307
 
308
    /* USB488 subclass commands */
309
    case READ_STATUS_BYTE:
310
      usb_tmc_status = TMC_STATUS_SUCCESS;
311
      EP0BUF[0] = usb_tmc_status;
312
      EP0BUF[1] = wValueL;
313
      EP0BUF[2] = IEEE488_status_query(&ieee488_status);
314
      EP0BCH = 0;
315
      EP0BCL = 3;
316
      break;
317
 
318
    case REN_CONTROL:
319
      /* optional command, not implemented */
320
      break;
321
 
322
    case GO_TO_LOCAL:
323
      /* optional command, not implemented */
324
      return 0;
325
      break;
326
 
327
    case LOCAL_LOCKOUT:
328
      /* optional command, not implemented */
329
      return 0;
330
      break;
331
 
332
    default:
333
      return 0;
334
    }
335
  }
336
 
337
  else if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_OUT){
338
 
339
    /***********************************
340
     *    handle the TMC OUT requests
341
     **********************************/
342
 
343
    switch (bRequest){
344
 
345
    default:
346
      usb_tmc_status = TMC_STATUS_FAILED;
347
      return 0;
348
    }
349
  }
350
  else
351
    return 0;    /* invalid bRequestType */
352
 
353
  return 1;
354
}

powered by: WebSVN 2.1.0

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