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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [adv_jtag_bridge/] [cable_usbblaster.c] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
/* cable_usbblaster.c - Altera USB Blaster driver for the Advanced JTAG Bridge
2 21 xianfeng
   Copyright (C) 2008 - 2010 Nathan Yawn, nathan.yawn@opencores.org
3 12 xianfeng
 
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 2 of the License, or
7
   (at your option) any later version.
8
 
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
 
14
   You should have received a copy of the GNU General Public License
15
   along with this program; if not, write to the Free Software
16
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
 
18
 
19
#include <stdio.h>
20
#include <sys/types.h>
21
#include <unistd.h>  // for usleep()
22
#include <stdlib.h>  // for sleep()
23
#include <arpa/inet.h> // for htons()
24 21 xianfeng
#include <string.h>  // for memcpy()
25 12 xianfeng
 
26
#include "usb.h"  // libusb header
27
#include "cable_common.h"
28
#include "errcodes.h"
29
 
30
#define debug(...) //fprintf(stderr, __VA_ARGS__ )
31
 
32
// USB constants for the USB Blaster
33
// Valid endpoints: 0x81, 0x02, 0x06, 0x88
34
#define EP2        0x02
35
#define EP1        0x81
36
#define ALTERA_VID 0x09FB
37
#define ALTERA_PID 0x6001
38
 
39
//#define USB_TIMEOUT 500
40
#define USB_TIMEOUT 10000
41
 
42
 
43
// Bit meanings in the command byte sent to the USB-Blaster
44
#define USBBLASTER_CMD_TCK 0x01
45
#define USBBLASTER_CMD_TMS 0x02
46
#define USBBLASTER_CMD_nCE 0x04  /* should be left low */
47
#define USBBLASTER_CMD_nCS 0x08  /* must be set for byte-shift mode reads to work */
48
#define USBBLASTER_CMD_TDI 0x10
49
#define USBBLASTER_CMD_OE  0x20  /* appears necessary to set it to make everything work */
50
#define USBBLASTER_CMD_READ 0x40
51
#define USBBLASTER_CMD_BYTESHIFT 0x80
52
 
53
 
54
static struct usb_device *usbblaster_device;
55 21 xianfeng
static usb_dev_handle *h_device;
56 12 xianfeng
 
57 21 xianfeng
// libusb seems to give an error if we ask for a transfer larger than 64 bytes
58
// USBBlaster also has a max. single transaction of 63 bytes.
59
// So, size the max read and write to create 64-byte USB packets (reads have 2 useless bytes prepended)
60
#define USBBLASTER_MAX_WRITE 63
61
static char data_out_scratchpad[USBBLASTER_MAX_WRITE+1];
62
#define USBBLASTER_MAX_READ  62
63
static char data_in_scratchpad[USBBLASTER_MAX_READ+2];
64 12 xianfeng
 
65 21 xianfeng
int cable_usbblaster_open_cable(void);
66
void cable_usbblaster_close_cable(void);
67
//int cable_usbblaster_reopen_cable(void);
68 12 xianfeng
 
69
///////////////////////////////////////////////////////////////////////////////
70
/*-------------------------------------[ USB Blaster specific functions ]---*/
71
/////////////////////////////////////////////////////////////////////////////
72
 
73
 
74
static int usbblaster_start_interface(struct usb_dev_handle *xpcu)
75
{
76
  // Need to send a VENDOR request OUT, request = GET_STATUS
77
  // Other parameters are ignored
78
  if(usb_control_msg(xpcu, (USB_ENDPOINT_OUT | USB_TYPE_VENDOR), USB_REQ_GET_STATUS,
79
                     0, 0, NULL, 0, 1000)<0)
80
    {
81
      perror("usb_control_msg(start interface)");
82
      return APP_ERR_USB;
83
    }
84
 
85
  return APP_ERR_NONE;
86
}
87
 
88
 
89
static int usbblaster_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf)
90
{
91
  if(usb_control_msg(xpcu, 0xC0, 0x90, 0, 3, (char*)buf, 2, USB_TIMEOUT)<0)
92
    {
93
      perror("usb_control_msg(0x90.0) (read_firmware_version)");
94
      return APP_ERR_USB;
95
    }
96
 
97
  // Swap endian
98
  *buf = htons(*buf);
99
  //*buf = (*buf << 8) | (*buf >> 8);
100
 
101
  return APP_ERR_NONE;
102
}
103
 
104
 
105
 
106
static int usbblaster_enumerate_bus(void)
107
{
108
  int             flag;  // for USB bus scanning stop condition
109
  struct usb_bus *bus;   // pointer on the USB bus
110
 
111
  // board detection
112
  usb_init();
113
  usb_find_busses();
114
  usb_find_devices();
115
 
116
  flag = 0;
117
 
118
  for (bus = usb_get_busses(); bus; bus = bus->next)
119
  {
120
    for (usbblaster_device = bus->devices; usbblaster_device; usbblaster_device = usbblaster_device->next)
121
    {
122
      if (usbblaster_device->descriptor.idVendor  == ALTERA_VID &&
123
          usbblaster_device->descriptor.idProduct == ALTERA_PID)
124
      {
125
              flag = 1;
126
              fprintf(stderr, "Found Altera USB-Blaster\n");
127
              return APP_ERR_NONE;
128
      }
129
    }
130
    if (flag)
131
      break;
132
  }
133
 
134
  fprintf(stderr, "Failed to find USB-Blaster\n");
135
  return APP_ERR_CABLENOTFOUND;
136
}
137
 
138
 
139
int cable_usbblaster_init(){
140
  int err = APP_ERR_NONE;
141
 
142
  // Process to reset the usb blaster
143
  if(err |= usbblaster_enumerate_bus()) {
144
    return err;
145
  }
146
 
147 21 xianfeng
  h_device = usb_open(usbblaster_device);
148 12 xianfeng
 
149
  if(h_device == NULL)
150
    {
151
      fprintf(stderr, "Init failed to open USB device for reset\n");
152
      return APP_ERR_USB;
153
    }
154
 
155
  if(usb_reset(h_device) != APP_ERR_NONE)
156
    fprintf(stderr, "Failed to reset USB Blaster\n");
157
 
158
  usb_close(h_device);
159
 
160
  // Wait for reset!!!
161
  sleep(1);
162
 
163
  // Do device initialization
164
  if(err |= usbblaster_enumerate_bus())
165
    return err;
166
 
167 21 xianfeng
  err = cable_usbblaster_open_cable();
168
  if(err != APP_ERR_NONE) return err;
169 12 xianfeng
 
170
  //usb_clear_halt(h_device, EP1);
171
  //usb_clear_halt(h_device, EP2);
172
 
173
  // IMPORTANT:  DO NOT SEND A REQUEST TYPE "CLASS" OR TYPE "RESERVED".  This may stall the EP.
174
 
175
  // Some clones need this before they will start processing IN/OUT requests
176
  if(usbblaster_start_interface(h_device) != APP_ERR_NONE)
177
    fprintf(stderr, "Failed to start remote interface\n");
178
 
179
  uint16_t buf;
180
  if(err |= usbblaster_read_firmware_version(h_device, &buf))
181
    {
182
      usb_close(h_device);
183
      fprintf(stderr, "Failed to read firmware version\n");
184
      return err;
185
    }
186
  else
187
    {
188
      printf("firmware version = 0x%04X (%u)\n", buf, buf);
189
    }
190
 
191
 
192
  // USB blaster is expecting us to read 2 bytes, which are useless to us...
193
  char ret[2];
194
  int rv = usb_bulk_read(h_device, EP1, ret, 2, USB_TIMEOUT);
195
  if (rv < 0){  // But if we fail, who cares?
196
    fprintf(stderr, "\nWarning: Failed to read post-init bytes from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
197
  }
198 21 xianfeng
 
199 12 xianfeng
  return APP_ERR_NONE;
200
}
201
 
202
 
203
int cable_usbblaster_out(uint8_t value)
204
{
205
  int             rv;                  // to catch return values of functions
206
  char out;
207
  int err = APP_ERR_NONE;
208
 
209 21 xianfeng
  // open the device, if necessary
210
  if(h_device == NULL) {
211
    rv = cable_usbblaster_open_cable();
212
    if(rv != APP_ERR_NONE) return rv;
213 12 xianfeng
  }
214
 
215
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (appears necessary) and nCS (necessary for byte-shift reads)
216
 
217
  // Translate to USB blaster protocol
218
  // USB-Blaster has no TRST pin
219
  if(value & TCLK_BIT)
220
    out |= USBBLASTER_CMD_TCK;
221
  if(value & TDI_BIT)
222
    out |= USBBLASTER_CMD_TDI;
223
  if(value & TMS_BIT)
224
    out |= USBBLASTER_CMD_TMS;
225
 
226
 
227
  rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT);
228
  if (rv != 1){
229
    fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
230
    err |= APP_ERR_USB;
231
  }
232
 
233
  return err;
234
}
235
 
236
 
237
int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit)
238
{
239
  int             rv;                  // to catch return values of functions
240
  char ret[3] = {0,0,0};               // Two useless bytes (0x31,0x60) always precede the useful byte
241
  char out;
242
 
243
  out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS);  // Set output enable (?) and nCS (necessary for byte-shift reads)
244
  out |=  USBBLASTER_CMD_READ;
245
 
246
  // Translate to USB blaster protocol
247
  // USB-Blaster has no TRST pin
248
  if(value & TCLK_BIT)
249
    out |= USBBLASTER_CMD_TCK;
250
  if(value & TDI_BIT)
251
    out |= USBBLASTER_CMD_TDI;
252
  if(value & TMS_BIT)
253
    out |= USBBLASTER_CMD_TMS;
254
 
255 21 xianfeng
  // open the device, if necessary
256
  if(h_device == NULL) {
257
    rv = cable_usbblaster_open_cable();
258
    if(rv != APP_ERR_NONE) return rv;
259 12 xianfeng
  }
260
 
261
  // Send a read request
262
  rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT);
263
  if (rv != 1){
264
    fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror());
265 21 xianfeng
    cable_usbblaster_close_cable();
266 12 xianfeng
    return APP_ERR_USB;
267
  }
268
 
269
 
270
  // receive the response
271
  // Sometimes, we do a read but just get the useless 0x31,0x60 chars...
272
  // retry until we get a 3rd byte (with real data), for a reasonable number of retries.
273
  int retries = 0;
274
  do {
275
    rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT);
276
    if (rv < 0){
277
      fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
278 21 xianfeng
      cable_usbblaster_close_cable();
279 12 xianfeng
      return APP_ERR_USB;
280
    }
281
 
282
    // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]);
283
    retries++;
284
  }
285
  while((rv < 3) && (retries < 20));
286
 
287
  *in_bit = (ret[2] & 0x01); /* TDO is bit 0.  USB-Blaster may also set bit 1. */
288
  return APP_ERR_NONE;
289
}
290
 
291
 
292
// The usbblaster transfers the bits in the stream in the following order:
293
// bit 0 of the first byte received ... bit 7 of the first byte received
294
// bit 0 of second byte received ... etc.
295
int cable_usbblaster_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
296
  int             rv;                  // to catch return values of functions
297
  unsigned int bytes_to_transfer, leftover_bit_length;
298
  uint32_t leftover_bits;
299 21 xianfeng
  int bytes_remaining;
300
  char *xfer_ptr;
301 12 xianfeng
  int err = APP_ERR_NONE;
302
 
303 21 xianfeng
  debug("cable_usbblaster_write_stream(0x%X, %d, %i)\n", stream, len, set_last_bit);
304 12 xianfeng
 
305
  // This routine must transfer at least 8 bits.  Additionally, TMS (the last bit)
306
  // cannot be set by 'byte shift mode'.  So we need at least 8 bits to transfer,
307
  // plus one bit to send along with TMS.
308
  bytes_to_transfer = len_bits / 8;
309
  leftover_bit_length = len_bits - (bytes_to_transfer * 8);
310
 
311
  if((!leftover_bit_length) && set_last_bit) {
312
    bytes_to_transfer -= 1;
313
    leftover_bit_length += 8;
314
  }
315
 
316 21 xianfeng
  debug("bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);
317 12 xianfeng
 
318
  // Not enough bits for high-speed transfer. bit-bang.
319
  if(bytes_to_transfer == 0) {
320
    return cable_common_write_stream(stream, len_bits, set_last_bit);
321
  }
322
 
323
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
324 21 xianfeng
  err |= cable_usbblaster_out(0);  // Lower the clock.
325 12 xianfeng
 
326
  // Set leftover bits
327
  leftover_bits = (stream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
328
 
329 21 xianfeng
  debug("leftover_bits: 0x%X, LSB_first_xfer = %d\n", leftover_bits, LSB_first_xfer);
330 12 xianfeng
 
331 21 xianfeng
  // open the device, if necessary
332
  if(h_device == NULL) {
333
    rv = cable_usbblaster_open_cable();
334
    if(rv != APP_ERR_NONE) return rv;
335 12 xianfeng
  }
336
 
337 21 xianfeng
  bytes_remaining = bytes_to_transfer;
338
  xfer_ptr = (char *) stream;
339
  while(bytes_remaining > 0)
340
    {
341
      int bytes_this_xfer = (bytes_remaining > USBBLASTER_MAX_WRITE) ? USBBLASTER_MAX_WRITE:bytes_remaining;
342 12 xianfeng
 
343 21 xianfeng
      data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | (bytes_this_xfer & 0x3F);
344
      memcpy(&data_out_scratchpad[1], xfer_ptr, bytes_this_xfer);
345
 
346
      /* printf("Data packet: ");
347
         for(i = 0; i <= bytes_to_transfer; i++)
348
         printf("0x%X ", out[i]);
349
         printf("\n"); */
350
 
351
      rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT);
352
      if (rv != (bytes_this_xfer+1)){
353
        fprintf(stderr, "\nFailed to write to the FIFO (rv = %d):\n%s", rv, usb_strerror());
354
        err |= APP_ERR_USB;
355
        break;
356
      }
357 12 xianfeng
 
358 21 xianfeng
      bytes_remaining -= bytes_this_xfer;
359
      xfer_ptr += bytes_this_xfer;
360 12 xianfeng
    }
361
 
362
  // if we have a number of bits not divisible by 8, or we need to set TMS...
363
  if(leftover_bit_length != 0) {
364
    //printf("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
365
    return cable_common_write_stream(&leftover_bits, leftover_bit_length, set_last_bit);
366
  }
367
 
368
  return err;
369
}
370
 
371
 
372
int cable_usbblaster_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
373
  int             rv;                  // to catch return values of functions
374 21 xianfeng
  unsigned int bytes_received = 0, total_bytes_received = 0;
375 12 xianfeng
  unsigned int bytes_to_transfer, leftover_bit_length;
376
  uint32_t leftover_bits, leftovers_received = 0;
377 21 xianfeng
  unsigned char i;
378
  int bytes_remaining;
379
  char *xfer_ptr;
380 12 xianfeng
  int retval = APP_ERR_NONE;
381
 
382
  debug("cable_usbblaster_read_stream(0x%X, %d, %i)\n", outstream[0], len_bits, set_last_bit);
383
 
384
  // This routine must transfer at least 8 bits.  Additionally, TMS (the last bit)
385
  // cannot be set by 'byte shift mode'.  So we need at least 8 bits to transfer,
386
  // plus one bit to send along with TMS.
387
  bytes_to_transfer = len_bits / 8;
388
  leftover_bit_length = len_bits - (bytes_to_transfer * 8);
389
 
390
  if((!leftover_bit_length) && set_last_bit) {
391
    bytes_to_transfer -= 1;
392
    leftover_bit_length += 8;
393
  }
394
 
395 21 xianfeng
  debug("RD bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length);
396 12 xianfeng
 
397
  // Not enough bits for high-speed transfer. bit-bang.
398
  if(bytes_to_transfer == 0) {
399
    return cable_common_read_stream(outstream, instream, len_bits, set_last_bit);
400
  }
401
 
402
  // Bitbang functions leave clock high.  USBBlaster assumes clock low at the start of a burst.
403
  // Lower the clock.
404
  retval |= cable_usbblaster_out(0);
405
 
406
  // Zero the input, since we add new data by logical-OR
407 21 xianfeng
  for(i = 0; i < (len_bits/32); i++)  instream[i] = 0;
408
  if(len_bits % 32)                   instream[i] = 0;
409 12 xianfeng
 
410
  // Set leftover bits
411
  leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF;
412
  debug("leftover_bits: 0x%X\n", leftover_bits);
413
 
414 21 xianfeng
  // open the device, if necessary
415
  if(h_device == NULL) {
416
    rv = cable_usbblaster_open_cable();
417
    if(rv != APP_ERR_NONE) return rv;
418 12 xianfeng
  }
419
 
420 21 xianfeng
  // Transfer the data.  USBBlaster has a max transfer size of 64 bytes.
421
  bytes_remaining = bytes_to_transfer;
422
  xfer_ptr = (char *) outstream;
423
  total_bytes_received = 0;
424
  while(bytes_remaining > 0)
425
    {
426
      int bytes_this_xfer = (bytes_remaining > USBBLASTER_MAX_READ) ? USBBLASTER_MAX_READ:bytes_remaining;
427
      data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | USBBLASTER_CMD_READ | (bytes_this_xfer & 0x3F);
428
      memcpy(&data_out_scratchpad[1], xfer_ptr, bytes_this_xfer);
429 12 xianfeng
 
430 21 xianfeng
      /* debug("Data packet: ");
431
         for(i = 0; i <= bytes_to_transfer; i++) debug("0x%X ", data_out_scratchpad[i]);
432
         debug("\n"); */
433 12 xianfeng
 
434 21 xianfeng
      rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT);
435
      if (rv != (bytes_this_xfer+1)){
436
        fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror());
437
        cable_usbblaster_close_cable();
438
        return APP_ERR_USB;
439
      }
440 12 xianfeng
 
441 21 xianfeng
      // receive the response
442
      // Sometimes, we do a read but just get the useless 0x31,0x60 chars...
443
      // retry until we get at least 3 bytes (with real data), for a reasonable number of retries.
444
      int retries = 0;
445
      bytes_received = 0;
446
      do {
447
        debug("stream read, bytes_this_xfer = %i, bytes_received = %i\n", bytes_this_xfer, bytes_received);
448
        rv = usb_bulk_read(h_device, EP1, data_in_scratchpad, (bytes_this_xfer-bytes_received)+2, USB_TIMEOUT);
449
        if (rv < 0){
450
          fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror());
451
          cable_usbblaster_close_cable();
452
          return APP_ERR_USB;
453
        }
454 12 xianfeng
 
455 21 xianfeng
        /* debug("Read %i bytes: ", rv);
456
           for(i = 0; i < rv; i++)
457
           debug("0x%X ", data_in_scratchpad[i]);
458
           debug("\n"); */
459
 
460
        if(rv > 2) retries = 0;
461
        else retries++;
462
 
463
        /* Put the received bytes into the return stream.  Works for either endian. */
464
        for(i = 0; i < (rv-2); i++) {
465
          // Do size/type promotion before shift.  Must cast to unsigned, else the value may be
466
          // sign-extended through the upper 16 bits of the uint32_t.
467
          uint32_t tmp = (unsigned char) data_in_scratchpad[2+i];
468
          instream[(total_bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8));
469
        }
470 12 xianfeng
 
471 21 xianfeng
        bytes_received += (rv-2);
472
        total_bytes_received += (rv-2);
473
      }
474
      while((bytes_received < bytes_this_xfer) && (retries < 15));
475 12 xianfeng
 
476 21 xianfeng
      bytes_remaining -= bytes_this_xfer;
477
      xfer_ptr += bytes_this_xfer;
478 12 xianfeng
    }
479
 
480
  // if we have a number of bits not divisible by 8
481
  if(leftover_bit_length != 0) {
482
    debug("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit);
483
    retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit);
484
    instream[bytes_to_transfer>>2] |= (leftovers_received & 0xFF) << (8*(bytes_to_transfer & 0x3));
485
  }
486
 
487
  return retval;
488
}
489
 
490
 
491
int cable_usbblaster_opt(int c, char *str)
492
{
493
  fprintf(stderr, "Unknown parameter '%c'\n", c);
494
  return APP_ERR_BAD_PARAM;
495
}
496
 
497
 
498 21 xianfeng
int cable_usbblaster_open_cable(void)
499 12 xianfeng
{
500 21 xianfeng
  // open the device
501
  h_device = usb_open(usbblaster_device);
502
  if (h_device == NULL){
503
        fprintf(stderr, "USBBlaster driver failed to open device\n");
504
        return APP_ERR_USB;
505
  }
506
 
507
  // set the configuration
508
  if (usb_set_configuration(h_device, usbblaster_device->config->bConfigurationValue))
509
  {
510
        usb_close(h_device);
511
        h_device = NULL;
512
        fprintf(stderr, "USBBlaster driver failed to set configuration\n");
513
        return APP_ERR_USB;
514
  }
515 12 xianfeng
 
516 21 xianfeng
  // wait until device is ready
517
  // *** TODO: add timeout
518
  while (usb_claim_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber));
519 12 xianfeng
 
520 21 xianfeng
  return APP_ERR_NONE;
521 12 xianfeng
}
522
 
523
 
524 21 xianfeng
void cable_usbblaster_close_cable(void)
525 12 xianfeng
{
526 21 xianfeng
  if(h_device != NULL) {
527
    // release the interface cleanly
528
    if (usb_release_interface(h_device, usbblaster_device->config->interface->altsetting->bInterfaceNumber)){
529
      fprintf(stderr, "Warning: failed to release usb interface\n");
530
    }
531
 
532
    // close the device
533
    usb_close(h_device);
534
    h_device = NULL;
535
  }
536 12 xianfeng
 
537 21 xianfeng
  return;
538 12 xianfeng
}
539
 
540 21 xianfeng
/*
541
int cable_usbblaster_reopen_cable(void)
542 12 xianfeng
{
543 21 xianfeng
  cable_usbblaster_close_cable();
544
  return cable_usbblaster_open_cable();
545 12 xianfeng
}
546 21 xianfeng
*/

powered by: WebSVN 2.1.0

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