initial commit of s3load
[s3load.git] / libnexys.c
CommitLineData
5ee943f9
JW
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
12nexys2_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
86static 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
97int 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
133int 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
169int 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
205int 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
266int 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
321int 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
370void 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
395void 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.047901 seconds and 4 git commands to generate.