]> Joshua Wise's Git repositories - s3load.git/blame - libnexys.c
GPLv2
[s3load.git] / libnexys.c
CommitLineData
de1916b0
JW
1/* libnexys.c
2 * Main libusb driver for libnexys
3 * libnexys, a free driver for Digilent NEXYS2 boards
4 *
5 * Copyright (c) 2007-2008 Joshua Wise
6 *
7 * This program 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 2 of the License.
10 *
11 * Commercial licenses are available by request.
12 */
13
5ee943f9
JW
14#ifdef WIN32_NATIVE
15#include "libnexys.win32.c"
16#else
17#define LIBNEXYS_INTERNAL
18#include "libnexys.h"
19#include <stdio.h>
20#include <usb.h>
21
22#define NEXYS2_VENDOR 0x1443
23#define NEXYS2_DEVICE 0x0005
24
25nexys2_t nexys2_init(void) {
26 struct usb_bus *bus;
27 struct usb_device *dev;
28 usb_dev_handle *udev;
29 int dev_found, ret;
30 unsigned char buf[15];
31
32 usb_init();
33
34 usb_find_busses();
35 usb_find_devices();
36
37 udev = NULL;
38 for (bus = usb_get_busses(); bus && !udev; bus = bus->next)
39 for (dev = bus->devices; dev && !udev; dev = dev->next)
40 if ((dev->descriptor.idVendor == NEXYS2_VENDOR) && (dev->descriptor.idProduct == NEXYS2_DEVICE))
41 udev = usb_open(dev);
42
43 if (!udev)
44 {
45 fprintf(stderr, "nexys2_init: no device found or device open failed\n");
46 return NULL;
47 }
48
49 if (usb_set_configuration(udev, 1) < 0)
50 {
51 fprintf(stderr, "nexys2_init: failed to set configuration 1 -- check your permissions\n");
52 return NULL;
53 }
54
55 if (usb_claim_interface(udev, 0) < 0) /* Needed for libusb on win32. This code somehow crashes win32 libusb/kernel anyway, but... */
56 {
57 fprintf(stderr, "nexys2_init: failed to claim interface 0 -- check your permissions\n");
58 return NULL;
59 }
60
0b5a2b64 61 if (usb_reset(udev) < 0) /* Sometimes the board locks up when you close it, so send this. */
5ee943f9 62 {
0b5a2b64 63 fprintf(stderr, "nexys2_init: failed to reset the USB (%s)\n", usb_strerror());
5ee943f9
JW
64 return NULL;
65 }
66
67 ret = usb_control_msg(udev, 0x00, 0x09, 1, 0, NULL, 0, 1000);
68 if (ret < 0)
69 {
70 fprintf(stderr, "nexys2_init: failed to send setup control message\n");
71 return NULL;
72 }
73
74 ret = usb_control_msg(udev, 0xC0, 0xE4, 0, 0, buf, 14, 1000);
75 if (ret < 0)
76 {
77 fprintf(stderr, "nexys2_init: failed to send serial number control message\n");
78 return NULL;
79 }
80
81 buf[ret] = 0;
82 fprintf(stderr, "nexys2_init: got serial number \"%s\" (%d bytes)\n", buf, ret);
83
84 ret = usb_control_msg(udev, 0xC0, 0xE6, 0, 0, buf, 4, 1000);
85 if (ret < 0)
86 {
87 fprintf(stderr, "nexys2_init: failed to send magic goo message\n");
88 return NULL;
89 }
90 if (memcmp(buf, "\x01\x00\x02\x00", 4))
91 {
92 fprintf(stderr, "nexys2_init: magic goo did not return what we expected (%d, %02x %02x %02x %02x)\n", ret, buf[0], buf[1], buf[2], buf[3]);
93 return NULL;
94 }
95
96 return udev;
97}
98
99static unsigned char common_response[64] =
100 { 0x00, 0x03, 0xf3, 0x77, 0x9f, 0xf5, 0xdf, 0xdd,
101 0xdf, 0xfe, 0x5f, 0xac, 0xff, 0xad, 0xf3, 0x34,
102 0xaf, 0xf5, 0xac, 0xf7, 0xca, 0xb7, 0xf7, 0x6f,
103 0xff, 0x5e, 0x5e, 0xf7, 0xfb, 0xfd, 0xfb, 0x37,
104 0x81, 0x53, 0xbf, 0x64, 0x59, 0x47, 0x59, 0x2d,
105 0xe8, 0x30, 0x77, 0xda, 0x4f, 0xaf, 0x7f, 0xd7,
106 0x5f, 0xee, 0xc7, 0x3b, 0xdf, 0x3e, 0xbf, 0x35,
107 0xd1, 0xdf, 0xef, 0x3f, 0x9f, 0xde, 0xfa, 0xe2
108 };
109
110int nexys2_jtag_enable(usb_dev_handle *udev)
111{
112 int ret;
113 unsigned char message[64] =
114 { 0x07, 0x01, 0x00, 0x00, 0xdc, 0xff, 0xd3, 0x00,
115 0xf3, 0x99, 0x83, 0x7c, 0x08, 0x26, 0x80, 0x7c,
116 0xff, 0xff, 0xff, 0xff, 0x00, 0x26, 0x80, 0x7c,
117 0xf1, 0xe2, 0x90, 0x7c, 0xb7, 0x24, 0x80, 0x7c,
118 0x14, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x2a, 0x95, 0x80, 0x7c, 0x5b, 0x3d, 0x00, 0x11,
120 0x14, 0x07, 0x00, 0x00, 0xe8, 0x22, 0xa0, 0x00,
121 0x02, 0x00, 0x00, 0x00, 0xb3, 0x9e, 0x01, 0x11 /* XXX does this need to be sequenced? */
122 };
123 unsigned char resp[64];
124
125 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
126 {
127 fprintf(stderr, "nexys2_jtag_enable: write failed: %d (%s)\n", ret, usb_strerror());
128 return -1;
129 }
130
131 if ((ret = usb_bulk_read(udev, 0x81, resp, 64, 1000)) < 64)
132 {
133 fprintf(stderr, "nexys2_jtag_enable: short read on response: %d\n", ret);
134 return -1;
135 }
136
137 if (memcmp(resp, common_response, 64))
138 {
139 fprintf(stderr, "nexys2_jtag_enable: incorrect response?\n");
140// return -1;
141 }
142
143 return 0;
144}
145
146int nexys2_jtag_disable(usb_dev_handle *udev)
147{
148 int ret;
149 unsigned char message[64] =
150 { 0x07, 0x00, 0xf3, 0x76, 0xdc, 0xff, 0xd3, 0x00,
151 0xf3, 0x99, 0x83, 0x7c, 0x08, 0x26, 0x80, 0x7c,
152 0xff, 0xff, 0xff, 0xff, 0x00, 0x26, 0x80, 0x7c,
153 0xf1, 0xe2, 0x90, 0x7c, 0xb7, 0x24, 0x80, 0x7c,
154 0x14, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x2a, 0x95, 0x80, 0x7c, 0x5b, 0x3d, 0x00, 0x11,
156 0x14, 0x07, 0x00, 0x00, 0xe8, 0x22, 0xa0, 0x00,
157 0x05, 0x00, 0x00, 0x00, 0xb3, 0x9e, 0x01, 0x11 /* XXX does this need to be sequenced? */
158 };
159 unsigned char resp[64];
160
161 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
162 {
163 fprintf(stderr, "nexys2_jtag_disable: write failed: %d (%s)\n", ret, usb_strerror());
164 return -1;
165 }
166
167 if ((ret = usb_bulk_read(udev, 0x81, resp, 64, 1000)) < 64)
168 {
169 fprintf(stderr, "nexys2_jtag_disable: short read on response: %d\n", ret);
170 return -1;
171 }
172
173 if (memcmp(resp, common_response, 64))
174 {
175 fprintf(stderr, "nexys2_jtag_disable: incorrect response?\n");
176// return -1;
177 }
178
179 return 0;
180}
181
182int nexys2_jtag_setbits(usb_dev_handle *udev, int tms, int tdi, int tck)
183{
184 int ret;
185 unsigned char message[64] =
186 { 0x08, !!tms, !!tdi, !!tck, 0xdc, 0xff, 0xd3, 0x00,
187 0xf3, 0x99, 0x83, 0x7c, 0x08, 0x26, 0x80, 0x7c,
188 0xff, 0xff, 0xff, 0xff, 0x00, 0x26, 0x80, 0x7c,
189 0xf1, 0xe2, 0x90, 0x7c, 0xb7, 0x24, 0x80, 0x7c,
190 0x14, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x2a, 0x95, 0x80, 0x7c, 0x5b, 0x3d, 0x00, 0x11,
192 0x14, 0x07, 0x00, 0x00, 0xe8, 0x22, 0xa0, 0x00,
193 0x03, 0x00, 0x00, 0x00, 0xb3, 0x9e, 0x01, 0x11 /* XXX does this need to be sequenced? */
194 };
195 unsigned char resp[64];
196
197 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
198 {
199 fprintf(stderr, "nexys2_jtag_setbits: write failed: %d (%s)\n", ret, usb_strerror());
200 return -1;
201 }
202
203/* if ((ret = usb_bulk_read(udev, 0x81, resp, 64, 1000)) < 64)
204 {
205 fprintf(stderr, "nexys2_jtag_setbits: short read on response: %d\n", ret);
206 return -1;
207 }
208
209 if (memcmp(resp, common_response, 64))
210 {
211 fprintf(stderr, "nexys2_jtag_setbits: incorrect response?\n");
212 return -1;
213 }*/
214
215 return 0;
216}
217
218int nexys2_jtag_puttdi(usb_dev_handle *udev, int tms, int nbits, unsigned char *bits, unsigned char *obits)
219{
220 int wanttdo = obits ? 1 : 0;
221 int bytesrem;
222 int ret;
223
224 unsigned char message[64] =
225 { 0x09, wanttdo, !!tms, 0x00, 0x00, (nbits >> 8) & 0xFF, nbits & 0xFF, 0x7C,
226 0xeb, 0x06, 0x91, 0x7c, 0x28, 0xfa, 0xd3, 0x00,
227 0xec, 0xfc, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
233 };
234
235 if (nbits > 0xFFFF)
236 {
237 fprintf(stderr, "nexys2_jtag_puttdi: too many bits!\n");
238 return -1;
239 }
240
241 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
242 {
243 fprintf(stderr, "nexys2_jtag_puttdi: write failed: %d (%s)\n", ret, usb_strerror());
244 return -1;
245 }
246
247 bytesrem = nbits / 8 + ((nbits % 8) != 0);
248 while (bytesrem)
249 {
250 int nbytes = (bytesrem > 512) ? 512 : bytesrem;
251 if ((ret = usb_bulk_write(udev, 0x02, bits, nbytes, 1000)) < nbytes)
252 {
253 fprintf(stderr, "nexys2_jtag_puttdi: data write failed: %d (%s)\n", ret, usb_strerror());
254 return -1;
255 }
256 bits += nbytes;
257 bytesrem -= nbytes;
258 }
259
260 if (obits)
261 {
262 bytesrem = nbits / 8 + ((nbits % 8) != 0);
263 while (bytesrem)
264 {
265 int nbytes = (bytesrem > 512) ? 512 : bytesrem;
266 if ((ret = usb_bulk_read(udev, 0x86, obits, nbytes, 1000)) < nbytes)
267 {
268 fprintf(stderr, "nexys2_jtag_puttdi: data read failed: %d (%s)\n", ret, usb_strerror());
269 return -1;
270 }
271 obits += nbytes;
272 bytesrem -= nbytes;
273 }
274 }
275
276 return 0;
277}
278
279int nexys2_jtag_puttmstdi(usb_dev_handle *udev, int nbits, unsigned char *bits, unsigned char *obits)
280{
281 int wanttdo = obits ? 1 : 0;
282 int bytesrem;
283 int ret;
284
285 unsigned char message[64] =
286 { 0x0a, wanttdo, 0x00, 0x00, (nbits >> 8) & 0xFF, nbits & 0xFF, 0x91, 0x7C,
287 0xeb, 0x06, 0x91, 0x7c, 0x28, 0xfa, 0xd3, 0x00,
288 0xec, 0xfc, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
294 };
295
296 if (nbits > 0xFFFF)
297 {
298 fprintf(stderr, "nexys2_jtag_puttmstdi: too many bits!\n");
299 return -1;
300 }
301
302 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
303 {
304 fprintf(stderr, "nexys2_jtag_puttmstdi: write failed: %d (%s)\n", ret, usb_strerror());
305 return -1;
306 }
307
308 bytesrem = nbits / 4 + ((nbits % 4) != 0);
309 while (bytesrem)
310 {
311 int nbytes = (bytesrem > 512) ? 512 : bytesrem;
312 if ((ret = usb_bulk_write(udev, 0x02, bits, nbytes, 1000)) < nbytes)
313 {
314 fprintf(stderr, "nexys2_jtag_puttmstdi: data write failed: %d (%s)\n", ret, usb_strerror());
315 return -1;
316 }
317 if (obits)
318 {
319 int nrbytes = nbytes/2 + (nbytes % 2);
320 if ((ret = usb_bulk_read(udev, 0x86, obits, nrbytes, 1000)) < nrbytes)
321 {
322 fprintf(stderr, "nexys2_jtag_puttmstdi: data read failed: %d (%s)\n", ret, usb_strerror());
323 return -1;
324 }
325 obits += nrbytes;
326 }
327 bits += nbytes;
328 bytesrem -= nbytes;
329 }
330
331 return 0;
332}
333
334int nexys2_jtag_gettdo(usb_dev_handle *udev, int tdi, int tms, int nbits, unsigned char *obits)
335{
336 int wanttdo = obits ? 1 : 0;
337 int bytesrem;
338 int ret;
339
340 unsigned char message[64] =
341 { 0x0B, !!tdi, !!tms, 0x00, 0x00, (nbits >> 8) & 0xFF, nbits & 0xFF, 0x7C,
342 0xeb, 0x06, 0x91, 0x7c, 0x28, 0xfa, 0xd3, 0x00,
343 0xec, 0xfc, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
349 };
350
351 if (nbits > 0xFFFF)
352 {
353 fprintf(stderr, "nexys2_jtag_puttdo: too many bits!\n");
354 return -1;
355 }
356
357 if ((ret = usb_bulk_write(udev, 0x01, message, 64, 1000)) < 64)
358 {
359 fprintf(stderr, "nexys2_jtag_gettdo: write failed: %d (%s)\n", ret, usb_strerror());
360 return -1;
361 }
362
363 bytesrem = nbits / 8 + ((nbits % 8) != 0);
364 while (bytesrem)
365 {
366 int nbytes = (bytesrem > 512) ? 512 : bytesrem;
367 if ((ret = usb_bulk_read(udev, 0x86, obits, nbytes, 1000)) < nbytes)
368 {
369 fprintf(stderr, "nexys2_jtag_gettdo: data read failed: %d (%s)\n", ret, usb_strerror());
370 return -1;
371 }
372 obits += nbytes;
373 bytesrem -= nbytes;
374 }
375
376 return 0;
377}
378
379#endif
380
381#ifdef TEST_DRIVER
382
383void poke_idcode(nexys2_t nexys)
384{
385 unsigned char seq1[] = { 0xaa, 0x22};
386 unsigned char seq2[] = { 0xaa, 0x02};
387 unsigned int idcode = 0;
388
389// while(1)
390 {
391 while (nexys2_jtag_enable(nexys) < 0)
392 ;
393 if (nexys2_jtag_puttmstdi(nexys, 8, seq1, NULL) < 0)
394 return;
395 do
396 {
397 if (nexys2_jtag_gettdo(nexys, 0, 0, 32, &idcode) < 0)
398 return;
399 printf("IDCODE: %08x\n", idcode);
400 } while(idcode && (idcode != 0xFFFFFFFF));
401 if (nexys2_jtag_puttmstdi(nexys, 8, seq2, NULL) < 0)
402 return;
403 if (nexys2_jtag_disable(nexys) < 0)
404 return;
405 }
406}
407
408void main()
409{
410 nexys2_t nexys;
411 nexys = nexys2_init();
412 if (!nexys)
413 return;
414 poke_idcode(nexys);
415}
416
417#endif
418
This page took 0.060157 seconds and 5 git commands to generate.