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