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_xpc_dlc9.c] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
/* cable_xpc_dlc9.c - Xilinx Platform Cable (DLC9) 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
 
24
 
25
#include "usb.h"  // libusb header
26
#include "cable_common.h"
27
#include "errcodes.h"
28
 
29
#define USB_TIMEOUT 500
30
 
31
// Note that this is based on the UrJTAG driver for the XPC-USB,
32
// which was 'experimental' at the time.
33
// It only supports bit-bang mode, and therefore will not be fast.
34
 
35
// USB constants for the DLC9
36
#define XPCUSB_VID  0x3fd
37
#define XPCUSB_PID  0x08
38
 
39
// Bit meanings in the command byte sent to the DLC9
40
// DLC9 has no TRST bit
41
#define XPCUSB_CMD_TDI 0x01
42
#define XPCUSB_CMD_TDO 0x01
43
#define XPCUSB_CMD_TMS 0x02
44
#define XPCUSB_CMD_TCK 0x04
45
#define XPCUSB_CMD_PROG 0x08
46
 
47
 
48
static struct usb_device *device;
49
 
50
 
51
///////////////////////////////////////////////////////////////////////////////
52
/*----- Functions for the Xilinx Platform Cable USB (Model DLC9)            */
53
/////////////////////////////////////////////////////////////////////////////
54
 
55
 
56
static int xpcu_request_28(struct usb_dev_handle *xpcu, int value)
57
{
58
  // Maybe clock speed setting?
59
  if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, USB_TIMEOUT)<0)
60
    {
61
      fprintf(stderr, "Error sending usb_control_msg(0x28.x)\n");
62
      return APP_ERR_USB;
63
    }
64
 
65
  return APP_ERR_NONE;
66
}
67
 
68
 
69
static int xpcu_raise_ioa5(struct usb_dev_handle *xpcu)
70
{
71
  if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0018, 0x0000, NULL, 0, USB_TIMEOUT)<0)
72
    {
73
      fprintf(stderr, "Error sending usb_control_msg(0x18.0x00) (raise IOA.5{\n");
74
      return APP_ERR_USB;
75
    }
76
 
77
  return APP_ERR_NONE;
78
}
79
 
80
static int xpcu_select_gpio(struct usb_dev_handle *xpcu, int chain)
81
{
82
  if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, chain, NULL, 0, USB_TIMEOUT)<0)
83
    {
84
      fprintf(stderr, "Error sending usb_control_msg(0x52.x) (select gpio)\n");
85
      return APP_ERR_USB;
86
    }
87
 
88
  return APP_ERR_NONE;
89
}
90
 
91
static int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf)
92
{
93
  if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, USB_TIMEOUT)<0)
94
    {
95
      fprintf(stderr,"Error sending usb_control_msg(0x50.0) (read_firmware_version)\n");
96
      return APP_ERR_USB;
97
    }
98
  return APP_ERR_NONE;
99
}
100
 
101
static int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, uint16_t *buf)
102
{
103
  if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, USB_TIMEOUT)<0)
104
    {
105
      fprintf(stderr, "Error sending usb_control_msg(0x50.1) (read_cpld_version)\n");
106
      return APP_ERR_USB;
107
    }
108
  return APP_ERR_NONE;
109
}
110
 
111
 
112
static int xpcusb_enumerate_bus(void)
113
{
114
  int             flag;  // for USB bus scanning stop condition
115
  struct usb_bus *bus;   // pointer on the USB bus
116
 
117
  // board detection
118
  usb_init();
119
  usb_find_busses();
120
  usb_find_devices();
121
 
122
  flag = 0;
123
 
124
  for (bus = usb_get_busses(); bus; bus = bus->next)
125
  {
126
    for (device = bus->devices; device; device = device->next)
127
    {
128
      if (device->descriptor.idVendor  == XPCUSB_VID &&
129
          device->descriptor.idProduct == XPCUSB_PID)
130
      {
131
              flag = 1;
132
              fprintf(stderr, "Found Xilinx Platform Cable USB (DLC9)\n");
133
              return APP_ERR_NONE;
134
      }
135
    }
136
    if (flag)
137
      break;
138
  }
139
 
140
  fprintf(stderr, "Failed to find Xilinx Platform Cable USB\n");
141
  return APP_ERR_CABLENOTFOUND;
142
}
143
 
144
 
145
int cable_xpcusb_init()
146
{
147
  int err = APP_ERR_NONE;
148
 
149
  // Process to reset the XPC USB (DLC9)
150
  if(err |= xpcusb_enumerate_bus()) {
151
    return err;
152
  }
153
 
154
  usb_dev_handle *h_device = usb_open(device);
155
 
156
  if(h_device == NULL)
157
    {
158
      fprintf(stderr, "Init failed to open USB device for reset\n");
159
      return APP_ERR_USB;
160
    }
161
 
162
  if(usb_reset(h_device) != APP_ERR_NONE)
163
    fprintf(stderr, "Failed to reset XPC-USB\n");
164
 
165
  usb_close(h_device);
166
 
167
  // Wait for reset!!!
168
  sleep(1);
169
 
170
  // Do device initialization
171
  if(err |= xpcusb_enumerate_bus())
172
    return err;
173
 
174
  h_device = usb_open(device);
175
  if(h_device == NULL)
176
    {
177
      fprintf(stderr, "Init failed to open USB device for initialization\n");
178
      return APP_ERR_USB;
179
    }
180
 
181
  // set the configuration
182
  if (usb_set_configuration(h_device, device->config->bConfigurationValue))
183
    {
184
      usb_close(h_device);
185
      fprintf(stderr, "USB-reset failed to set configuration\n");
186
      return APP_ERR_USB;
187
    }
188
 
189
  while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber));
190
 
191
  // DO DEVICE-SPECIFIC INIT HERE
192
  // Don't mess with the order here, it's easy to break.
193
 
194
  // Maybe set the clock speed?
195
  if(xpcu_request_28(h_device, 0x11) != APP_ERR_NONE)   {
196
    fprintf(stderr, "Request 28 (set clock speed?) failed.\n");
197
  }
198
 
199
  // Set internal TCK,TMS,TDO to 0
200
  if(usb_control_msg(h_device, 0x40, 0xB0, 0x0030, 0x08, NULL, 0, USB_TIMEOUT)!= APP_ERR_NONE) {
201
    fprintf(stderr, "usb_control_msg(0x30.0x00) (write port E) failed\n");
202
  }
203
 
204
  // Read firmware version (constant embedded in firmware)
205
  uint16_t buf;
206
 
207
  if(xpcu_read_firmware_version(h_device, &buf) != APP_ERR_NONE)        {
208
    fprintf(stderr, "Failed to read firmware version.\n");
209
  }
210
  else  {
211
    printf("firmware version = 0x%04X (%u)\n", buf, buf);
212
  }
213
 
214
  // Read CPLD version (uses the internal GPIF interface)
215
  if(xpcu_read_cpld_version(h_device, &buf) != APP_ERR_NONE) {
216
    fprintf(stderr, "Failed to read CPLD version.\n");
217
  }
218
  else
219
    {
220
      printf("cable CPLD version = 0x%04X (%u)\n", buf, buf);
221
      if(buf == 0)               {
222
        printf("Warning: version '0' can't be correct. Please try resetting the cable\n");
223
      }
224
    }
225
 
226
  // Set IOA bit 5, which enables output buffers
227
  if(xpcu_raise_ioa5(h_device) != APP_ERR_NONE) {
228
    fprintf(stderr, "Failed to enable XPC output buffers\n");
229
  }
230
 
231
  // access external chain for normal operation
232
  if(xpcu_select_gpio(h_device, 0) != APP_ERR_NONE) {
233
    fprintf(stderr, "Failed to select external JTAG chain\n");
234
  }
235
 
236
  // Init all done, release cable
237
  if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){
238
    usb_close(h_device);
239
    fprintf(stderr, "USB-out failed to release interface\n");
240
    return APP_ERR_USB;
241
  }
242
 
243
  usb_close(h_device);
244
 
245
  return APP_ERR_NONE;
246
}
247
 
248
 
249
int cable_xpcusb_out(uint8_t value)
250
{
251
  int             rv;                  // to catch return values of functions
252
  usb_dev_handle *h_device;            // handle on the ubs device
253
  uint8_t out;
254
 
255
  // open the device
256
  h_device = usb_open(device);
257
  if (h_device == NULL){
258
    usb_close(h_device);
259
    fprintf(stderr, "USB-out failed to open device\n");
260
    return APP_ERR_USB;
261
  }
262
 
263
  // set the configuration
264
  if (usb_set_configuration(h_device, device->config->bConfigurationValue))
265
    {
266
      usb_close(h_device);
267
      fprintf(stderr, "USB-out failed to set configuration\n");
268
      return APP_ERR_USB;
269
    }
270
 
271
  // wait until device is ready
272
  while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber));
273
 
274
  // send the buffer
275
  // Translate to USB blaster protocol
276
  out = 0;
277
  if(value & TCLK_BIT)
278
    out |= XPCUSB_CMD_TCK;
279
  if(value & TDI_BIT)
280
    out |= XPCUSB_CMD_TDI;
281
  if(value & TMS_BIT)
282
    out |= XPCUSB_CMD_TMS;
283
 
284
  out |= XPCUSB_CMD_PROG;  // Set output PROG (always necessary)
285
 
286
  /* debug
287
  if(value & TDI_BIT)
288
    printf("Write 1\n");
289
  else
290
    printf("Write 0\n");
291
  */
292
 
293
  rv = usb_control_msg(h_device, 0x40, 0xB0, 0x0030, out, NULL, 0, USB_TIMEOUT);
294
  if (rv < 0){
295
    fprintf(stderr, "\nFailed to send a write control message (rv = %d):\n%s\n", rv, usb_strerror());
296
  }
297
 
298
  // release the interface cleanly
299
  if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){
300
    fprintf(stderr, "Warning: failed to release usb interface after write\n");
301
  }
302
 
303
  // close the device
304
  usb_close(h_device);
305
  return APP_ERR_NONE;
306
}
307
 
308
 
309
int cable_xpcusb_inout(uint8_t value, uint8_t *inval)
310
{
311
  int rv;                  // to catch return values of functions
312
  usb_dev_handle *h_device;            // handle on the usb device
313
  char ret = 0;
314
  uint8_t out;
315
 
316
  // Translate to USB blaster protocol
317
  out = 0;
318
  if(value & TCLK_BIT)
319
    out |= XPCUSB_CMD_TCK;
320
  if(value & TDI_BIT)
321
    out |= XPCUSB_CMD_TDI;
322
  if(value & TMS_BIT)
323
    out |= XPCUSB_CMD_TMS;
324
 
325
  out |= XPCUSB_CMD_PROG;  // Set output PROG (always necessary)
326
 
327
  // open the device
328
  h_device = usb_open(device);
329
  if (h_device == NULL){
330
    usb_close(h_device);
331
    return APP_ERR_USB;
332
  }
333
 
334
  // set the configuration
335
  if (usb_set_configuration(h_device, device->config->bConfigurationValue)){
336
    usb_close(h_device);
337
    return APP_ERR_USB;
338
  }
339
 
340
  // wait until device is ready
341
  while (usb_claim_interface(h_device, device->config->interface->altsetting->bInterfaceNumber));
342
 
343
  // Send the output
344
  rv = usb_control_msg(h_device, 0x40, 0xB0, 0x0030, out, NULL, 0, USB_TIMEOUT);
345
  if (rv < 0){
346
    fprintf(stderr, "\nFailed to send a write control message (rv = %x):\n%s\n", rv, usb_strerror());
347
    goto usbblaster_in_fail;
348
  }
349
 
350
 
351
  // receive the response
352
  rv = usb_control_msg(h_device, 0xC0, 0xB0, 0x0038, 0, (char*)&ret, 1, USB_TIMEOUT);
353
  if (rv < 0){
354
    fprintf(stderr, "\nFailed to execute a read control message:\n%s\n", usb_strerror());
355
    goto usbblaster_in_fail;
356
  }
357
 
358
 
359
  // release the interface cleanly
360
  if (usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber)){
361
    fprintf(stderr, "Warning: failed to release USB interface after read\n");
362
    usb_close(h_device);
363
    return APP_ERR_USB;
364
  }
365
 
366
  // close the device
367
  usb_close(h_device);
368
 
369
  /* debug
370
  if(value & TDI_BIT)
371
    printf("Write 1, ");
372
  else
373
    printf("Write 0, ");
374
  */
375
 
376
  if(ret & XPCUSB_CMD_TDO)
377
    *inval = 1;
378
  else
379
    *inval = 0;
380
 
381
  //printf("Read 0\n");
382
  return APP_ERR_NONE;
383
 
384
usbblaster_in_fail:
385
  usb_release_interface(h_device, device->config->interface->altsetting->bInterfaceNumber);
386
  usb_close(h_device);
387
  return APP_ERR_USB;
388
}
389
 
390
 
391
// Xilinx couldn't be like everyone else.  Oh, no.
392
// For some reason, "set data/drop TCK" then "read data/raise TCK" won't work.
393
// So we have our very own bit read/write function.  @whee.
394
int cable_xpcusb_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
395
  uint8_t data = TRST_BIT;  //  TRST is active low, don't clear unless /set/ in 'packet'
396
  int err = APP_ERR_NONE;
397
 
398
  /* Write data, drop clock */
399
  if(packet_out & TDO) data |= TDI_BIT;
400
  if(packet_out & TMS) data |= TMS_BIT;
401
  if(packet_out & TRST) data &= ~TRST_BIT;
402
 
403
  err |= cable_xpcusb_inout(data, bit_in);  // read in bit, set data, drop clock
404
  err |= cable_xpcusb_out(data|TCLK_BIT);  // clk hi
405
 
406
  return err;
407
}
408
 
409
 
410
int cable_xpcusb_opt(int c, char *str)
411
{
412
    fprintf(stderr, "Unknown parameter '%c'\n", c);
413
    return APP_ERR_BAD_PARAM;
414
}
415
 

powered by: WebSVN 2.1.0

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