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 9

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
 
191
        FIFORESET = 0;               SYNCDELAY;
192
 
193
      }
194
 
195
      /* check if the active transfer has the requested bTag value */
196
      else if(usb_tmc_transfer.bTag == wValueL) {
197
        usb_tmc_status = TMC_STATUS_SUCCESS;
198
        usb_tmc_state = TMC_STATE_IDLE;
199
        IEEE488_clear_mav();
200
      }
201
 
202
      else {
203
        usb_tmc_status = TMC_STATUS_TRANSFER_NOT_IN_PROGRESS;
204
      }
205
 
206
      EP0BUF[0] = usb_tmc_status;
207
      EP0BUF[1] = wValueL;
208
      EP0BCH = 0;
209
      EP0BCL = 2;
210
      break;
211
 
212
    case CHECK_ABORT_BULK_IN_STATUS:
213
      /* send number of transmitted bytes */
214
      usb_tmc_status = TMC_STATUS_SUCCESS;
215
      EP0BUF[0] = usb_tmc_status;
216
      EP0BUF[1] = 0;
217
      EP0BUF[2] = 0;
218
      EP0BUF[3] = 0;
219
      EP0BUF[4] = (usb_tmc_transfer.nbytes_txd & 0x0000FF);
220
      EP0BUF[5] = (usb_tmc_transfer.nbytes_txd & 0x00FF00)>>8;
221
      EP0BUF[6] = (usb_tmc_transfer.nbytes_txd & 0xFF0000)>>16;
222
      EP0BUF[7] = usb_tmc_transfer.nbytes_txd >>24;
223
      EP0BCH = 0;
224
      EP0BCL = 8;
225
      break;
226
 
227
    case INITIATE_CLEAR:
228
      usb_tmc_status = TMC_STATUS_SUCCESS;
229
      usb_tmc_state = TMC_STATE_IDLE;
230
      IEEE488_clear_mav();
231
 
232
      /* --------------------------------------------------------------------*/
233
      /* abort GECKO3COM specific stuff */
234
      if( flLOCAL == GECKO3COM_REMOTE) {
235
        deactivate_gpif();
236
        flLOCAL = GECKO3COM_LOCAL;
237
 
238
        /* configure the fpga interface for configuration */
239
        init_fpga_interface();
240
      }
241
 
242
      /* --------------------------------------------------------------------*/
243
 
244
 
245
      /* reset FIFOs */
246
      FIFORESET = bmNAKALL;                    SYNCDELAY;
247
      FIFORESET = bmNAKALL | USB_TMC_EP_OUT;   SYNCDELAY;
248
      FIFORESET = bmNAKALL | USB_TMC_EP_IN;    SYNCDELAY;
249
 
250
      /* because we use quad buffering we have to flush all for buffers */
251
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
252
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
253
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
254
      OUTPKTEND = bmSKIP | USB_TMC_EP_OUT;       SYNCDELAY;
255
 
256
      FIFORESET = 0;                 SYNCDELAY;
257
 
258
      EP0BUF[0] = usb_tmc_status;
259
      EP0BCH = 0;
260
      EP0BCL = 1;
261
 
262
      break;
263
 
264
    case CHECK_CLEAR_STATUS:
265
      usb_tmc_status = TMC_STATUS_SUCCESS;
266
      EP0BUF[0] = usb_tmc_status;
267
      EP0BUF[1] = 0; /* no queued data in bulk-in buffer */
268
 
269
      EP0BCH = 0;
270
      EP0BCL = 2;
271
      break;
272
 
273
    case GET_CAPABILITIES:
274
      usb_tmc_status = TMC_STATUS_SUCCESS;
275
      {
276
        uint8_t i = 0;
277
        for(i;i<0x18;i++){
278
          EP0BUF[i] = (&(uintptr_t)USB_TMC_CAPABILITIES)[i];
279
        }
280
        EP0BCH = 0;
281
        EP0BCL = 0x18;
282
      }
283
      break;
284
 
285
    case INDICATOR_PULSE:
286
      /* GECKO3COM spcific command to set external LED */
287
      set_led_ext(ORANGE);
288
      usb_tmc_status = TMC_STATUS_SUCCESS;
289
      EP0BUF[0] = usb_tmc_status;
290
      EP0BCH = 0;
291
      EP0BCL = 1;
292
      break;
293
 
294
    /* USB488 subclass commands */
295
    case READ_STATUS_BYTE:
296
      usb_tmc_status = TMC_STATUS_SUCCESS;
297
      EP0BUF[0] = usb_tmc_status;
298
      EP0BUF[1] = wValueL;
299
      EP0BUF[2] = IEEE488_status_query(&ieee488_status);
300
      EP0BCH = 0;
301
      EP0BCL = 3;
302
      break;
303
 
304
    case REN_CONTROL:
305
      /* optional command, not implemented */
306
      break;
307
 
308
    case GO_TO_LOCAL:
309
      /* optional command, not implemented */
310
      return 0;
311
      break;
312
 
313
    case LOCAL_LOCKOUT:
314
      /* optional command, not implemented */
315
      return 0;
316
      break;
317
 
318
    default:
319
      return 0;
320
    }
321
  }
322
 
323
  else if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_OUT){
324
 
325
    /***********************************
326
     *    handle the TMC OUT requests
327
     **********************************/
328
 
329
    switch (bRequest){
330
 
331
    default:
332
      usb_tmc_status = TMC_STATUS_FAILED;
333
      return 0;
334
    }
335
  }
336
  else
337
    return 0;    /* invalid bRequestType */
338
 
339
  return 1;
340
}

powered by: WebSVN 2.1.0

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