]> Joshua Wise's Git repositories - s3load.git/blob - libnexys.c
GPLv2
[s3load.git] / libnexys.c
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
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
25 nexys2_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         
61         if (usb_reset(udev) < 0)        /* Sometimes the board locks up when you close it, so send this. */
62         {
63                 fprintf(stderr, "nexys2_init: failed to reset the USB (%s)\n", usb_strerror());
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
99 static 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
110 int 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
146 int 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
182 int 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
218 int 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
279 int 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
334 int 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
383 void 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
408 void 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.042415 seconds and 4 git commands to generate.