libusb: require pkg-config support
[openocd.git] / src / jtag / drivers / presto.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
3 * chromy@asix.cz *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
20
21 /**
22 * @file
23 * Holds driver for PRESTO programmer from ASIX.
24 * http://tools.asix.net/prg_presto.htm
25 */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #if IS_CYGWIN == 1
31 #include "windows.h"
32 #endif
33
34 #include <jtag/interface.h>
35 #include <helper/time_support.h>
36 #include "bitq.h"
37
38 /* PRESTO access library includes */
39 #if BUILD_PRESTO_FTD2XX == 1
40 #include <ftd2xx.h>
41 #include "ftd2xx_common.h"
42 #elif BUILD_PRESTO_LIBFTDI == 1
43 #include <ftdi.h>
44 #else
45 #error "BUG: either FTD2XX and LIBFTDI has to be used"
46 #endif
47
48 /* -------------------------------------------------------------------------- */
49
50 #define FT_DEVICE_NAME_LEN 64
51 #define FT_DEVICE_SERNUM_LEN 64
52
53 #define PRESTO_VID_PID 0x0403f1a0
54 #define PRESTO_VID (0x0403)
55 #define PRESTO_PID (0xf1a0)
56
57 #define BUFFER_SIZE (64*62)
58
59 struct presto {
60 #if BUILD_PRESTO_FTD2XX == 1
61 FT_HANDLE handle;
62 FT_STATUS status;
63 #elif BUILD_PRESTO_LIBFTDI == 1
64 struct ftdi_context ftdic;
65 int retval;
66 #endif
67
68 char serial[FT_DEVICE_SERNUM_LEN];
69
70 uint8_t buff_out[BUFFER_SIZE];
71 int buff_out_pos;
72
73 uint8_t buff_in[BUFFER_SIZE];
74 int buff_in_exp;/* expected in buffer length */
75 int buff_in_len;/* length of data received */
76 int buff_in_pos;
77
78 unsigned long total_out;
79 unsigned long total_in;
80
81 int jtag_tms; /* last tms state */
82 int jtag_tck; /* last tck state */
83 int jtag_rst; /* last trst state */
84
85 int jtag_tdi_data;
86 int jtag_tdi_count;
87
88 int jtag_speed;
89 };
90
91 static struct presto presto_state;
92 static struct presto *presto = &presto_state;
93
94 static uint8_t presto_init_seq[] = {
95 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
96 };
97
98 static int presto_write(uint8_t *buf, uint32_t size)
99 {
100 #if BUILD_PRESTO_FTD2XX == 1
101 DWORD ftbytes;
102 presto->status = FT_Write(presto->handle, buf, size, &ftbytes);
103 if (presto->status != FT_OK) {
104 LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto->status));
105 return ERROR_JTAG_DEVICE_ERROR;
106 }
107
108 #elif BUILD_PRESTO_LIBFTDI == 1
109 uint32_t ftbytes;
110 presto->retval = ftdi_write_data(&presto->ftdic, buf, size);
111 if (presto->retval < 0) {
112 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
113 return ERROR_JTAG_DEVICE_ERROR;
114 }
115 ftbytes = presto->retval;
116 #endif
117
118 if (ftbytes != size) {
119 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
120 (unsigned)ftbytes, (unsigned)size);
121 return ERROR_JTAG_DEVICE_ERROR;
122 }
123
124 return ERROR_OK;
125 }
126
127 static int presto_read(uint8_t *buf, uint32_t size)
128 {
129 #if BUILD_PRESTO_FTD2XX == 1
130 DWORD ftbytes;
131 presto->status = FT_Read(presto->handle, buf, size, &ftbytes);
132 if (presto->status != FT_OK) {
133 LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto->status));
134 return ERROR_JTAG_DEVICE_ERROR;
135 }
136
137 #elif BUILD_PRESTO_LIBFTDI == 1
138 uint32_t ftbytes = 0;
139
140 struct timeval timeout, now;
141 gettimeofday(&timeout, NULL);
142 timeval_add_time(&timeout, 1, 0); /* one second timeout */
143
144 while (ftbytes < size) {
145 presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes);
146 if (presto->retval < 0) {
147 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
148 return ERROR_JTAG_DEVICE_ERROR;
149 }
150 ftbytes += presto->retval;
151
152 gettimeofday(&now, NULL);
153 if ((now.tv_sec > timeout.tv_sec) ||
154 ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
155 break;
156 }
157 #endif
158
159 if (ftbytes != size) {
160 /* this is just a warning, there might have been timeout when detecting PRESTO,
161 *which is not fatal */
162 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
163 (unsigned)ftbytes, (unsigned)size);
164 return ERROR_JTAG_DEVICE_ERROR;
165 }
166
167 return ERROR_OK;
168 }
169
170 #if BUILD_PRESTO_FTD2XX == 1
171 static int presto_open_ftd2xx(char *req_serial)
172 {
173 uint32_t i;
174 DWORD numdevs;
175 DWORD vidpid;
176 char devname[FT_DEVICE_NAME_LEN];
177 FT_DEVICE device;
178
179 BYTE presto_data;
180 DWORD ftbytes;
181
182 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
183
184 #if IS_WIN32 == 0
185 /* Add non-standard Vid/Pid to the linux driver */
186 presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID);
187 if (presto->status != FT_OK) {
188 LOG_ERROR("couldn't add PRESTO VID/PID");
189 exit(-1);
190 }
191 #endif
192
193 presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY);
194 if (presto->status != FT_OK) {
195 LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
196 return ERROR_JTAG_DEVICE_ERROR;
197 }
198
199 LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
200 for (i = 0; i < numdevs; i++) {
201 presto->status = FT_Open(i, &(presto->handle));
202 if (presto->status != FT_OK) {
203 /* this is not fatal, the device may be legitimately open by other process,
204 *hence debug message only */
205 LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
206 continue;
207 }
208 LOG_DEBUG("FTDI device %i open", (int)i);
209
210 presto->status = FT_GetDeviceInfo(presto->handle, &device,
211 &vidpid, presto->serial, devname, NULL);
212 if (presto->status == FT_OK) {
213 if (vidpid == PRESTO_VID_PID && (req_serial == NULL ||
214 !strcmp(presto->serial, req_serial)))
215 break;
216 } else
217 LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
218 presto->status));
219
220 LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
221 FT_Close(presto->handle);
222 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
223 }
224
225 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
226 return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
227
228 presto->status = FT_SetLatencyTimer(presto->handle, 1);
229 if (presto->status != FT_OK)
230 return ERROR_JTAG_DEVICE_ERROR;
231
232 presto->status = FT_SetTimeouts(presto->handle, 100, 0);
233 if (presto->status != FT_OK)
234 return ERROR_JTAG_DEVICE_ERROR;
235
236 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
237 if (presto->status != FT_OK)
238 return ERROR_JTAG_DEVICE_ERROR;
239
240 presto_data = 0xD0;
241 presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
242 if (presto->status != FT_OK)
243 return ERROR_JTAG_DEVICE_ERROR;
244
245 /* delay between first write/read turnaround (after purge?) necessary
246 * under Linux for unknown reason,
247 * probably a bug in library threading */
248 usleep(100000);
249 presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
250 if (presto->status != FT_OK)
251 return ERROR_JTAG_DEVICE_ERROR;
252
253 if (ftbytes != 1) {
254 LOG_DEBUG("PRESTO reset");
255
256 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
257 if (presto->status != FT_OK)
258 return ERROR_JTAG_DEVICE_ERROR;
259 presto->status = FT_SetBitMode(presto->handle, 0x80, 1);
260 if (presto->status != FT_OK)
261 return ERROR_JTAG_DEVICE_ERROR;
262 presto->status = FT_SetBaudRate(presto->handle, 9600);
263 if (presto->status != FT_OK)
264 return ERROR_JTAG_DEVICE_ERROR;
265
266 presto_data = 0;
267 for (i = 0; i < 4 * 62; i++) {
268 presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
269 if (presto->status != FT_OK)
270 return ERROR_JTAG_DEVICE_ERROR;
271 }
272 usleep(100000);
273
274 presto->status = FT_SetBitMode(presto->handle, 0x00, 0);
275 if (presto->status != FT_OK)
276 return ERROR_JTAG_DEVICE_ERROR;
277
278 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
279 if (presto->status != FT_OK)
280 return ERROR_JTAG_DEVICE_ERROR;
281
282 presto_data = 0xD0;
283 presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
284 if (presto->status != FT_OK)
285 return ERROR_JTAG_DEVICE_ERROR;
286
287 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
288 probably a bug in library threading */
289 usleep(100000);
290 presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
291 if (presto->status != FT_OK)
292 return ERROR_JTAG_DEVICE_ERROR;
293
294 if (ftbytes != 1) {
295 LOG_DEBUG("PRESTO not responding");
296 return ERROR_JTAG_DEVICE_ERROR;
297 }
298 }
299
300 presto->status = FT_SetTimeouts(presto->handle, 0, 0);
301 if (presto->status != FT_OK)
302 return ERROR_JTAG_DEVICE_ERROR;
303
304 presto->status = FT_Write(presto->handle, &presto_init_seq,
305 sizeof(presto_init_seq), &ftbytes);
306
307 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
308 return ERROR_JTAG_DEVICE_ERROR;
309
310 return ERROR_OK;
311 }
312
313 #elif BUILD_PRESTO_LIBFTDI == 1
314 static int presto_open_libftdi(char *req_serial)
315 {
316 uint8_t presto_data;
317
318 LOG_DEBUG("searching for PRESTO using libftdi");
319
320 /* initialize FTDI context structure */
321 if (ftdi_init(&presto->ftdic) < 0) {
322 LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str);
323 return ERROR_JTAG_DEVICE_ERROR;
324 }
325
326 /* context, vendor id, product id */
327 if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) {
328 LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str);
329 return ERROR_JTAG_DEVICE_ERROR;
330 }
331
332 if (ftdi_usb_reset(&presto->ftdic) < 0) {
333 LOG_ERROR("unable to reset PRESTO device");
334 return ERROR_JTAG_DEVICE_ERROR;
335 }
336
337 if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) {
338 LOG_ERROR("unable to set latency timer");
339 return ERROR_JTAG_DEVICE_ERROR;
340 }
341
342 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) {
343 LOG_ERROR("unable to purge PRESTO buffers");
344 return ERROR_JTAG_DEVICE_ERROR;
345 }
346
347 presto_data = 0xD0;
348 if (presto_write(&presto_data, 1) != ERROR_OK) {
349 LOG_ERROR("error writing to PRESTO");
350 return ERROR_JTAG_DEVICE_ERROR;
351 }
352
353 if (presto_read(&presto_data, 1) != ERROR_OK) {
354 LOG_DEBUG("no response from PRESTO, retrying");
355
356 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
357 return ERROR_JTAG_DEVICE_ERROR;
358
359 presto_data = 0xD0;
360 if (presto_write(&presto_data, 1) != ERROR_OK)
361 return ERROR_JTAG_DEVICE_ERROR;
362
363 if (presto_read(&presto_data, 1) != ERROR_OK) {
364 LOG_ERROR("no response from PRESTO, giving up");
365 return ERROR_JTAG_DEVICE_ERROR;
366 }
367 }
368
369 if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) {
370 LOG_ERROR("error writing PRESTO init sequence");
371 return ERROR_JTAG_DEVICE_ERROR;
372 }
373
374 return ERROR_OK;
375 }
376 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
377
378 static int presto_open(char *req_serial)
379 {
380 presto->buff_out_pos = 0;
381 presto->buff_in_pos = 0;
382 presto->buff_in_len = 0;
383 presto->buff_in_exp = 0;
384
385 presto->total_out = 0;
386 presto->total_in = 0;
387
388 presto->jtag_tms = 0;
389 presto->jtag_tck = 0;
390 presto->jtag_rst = 0;
391 presto->jtag_tdi_data = 0;
392 presto->jtag_tdi_count = 0;
393
394 presto->jtag_speed = 0;
395
396 #if BUILD_PRESTO_FTD2XX == 1
397 return presto_open_ftd2xx(req_serial);
398 #elif BUILD_PRESTO_LIBFTDI == 1
399 return presto_open_libftdi(req_serial);
400 #endif
401 }
402
403 static int presto_close(void)
404 {
405
406 int result = ERROR_OK;
407
408 #if BUILD_PRESTO_FTD2XX == 1
409 DWORD ftbytes;
410
411 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
412 return result;
413
414 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
415 if (presto->status != FT_OK)
416 result = ERROR_JTAG_DEVICE_ERROR;
417
418 presto->status = FT_Write(presto->handle,
419 &presto_init_seq,
420 sizeof(presto_init_seq),
421 &ftbytes);
422 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
423 result = ERROR_JTAG_DEVICE_ERROR;
424
425 presto->status = FT_SetLatencyTimer(presto->handle, 16);
426 if (presto->status != FT_OK)
427 result = ERROR_JTAG_DEVICE_ERROR;
428
429 presto->status = FT_Close(presto->handle);
430 if (presto->status != FT_OK)
431 result = ERROR_JTAG_DEVICE_ERROR;
432 else
433 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
434
435 #elif BUILD_PRESTO_LIBFTDI == 1
436
437 presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq));
438 if (presto->retval != sizeof(presto_init_seq))
439 result = ERROR_JTAG_DEVICE_ERROR;
440
441 presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16);
442 if (presto->retval < 0)
443 result = ERROR_JTAG_DEVICE_ERROR;
444
445 presto->retval = ftdi_usb_close(&presto->ftdic);
446 if (presto->retval < 0)
447 result = ERROR_JTAG_DEVICE_ERROR;
448 else
449 ftdi_deinit(&presto->ftdic);
450 #endif
451
452 return result;
453 }
454
455 static int presto_flush(void)
456 {
457 if (presto->buff_out_pos == 0)
458 return ERROR_OK;
459
460 #if BUILD_PRESTO_FTD2XX == 1
461 if (presto->status != FT_OK) {
462 #elif BUILD_PRESTO_LIBFTDI == 1
463 if (presto->retval < 0) {
464 #endif
465 LOG_DEBUG("error in previous communication, canceling I/O operation");
466 return ERROR_JTAG_DEVICE_ERROR;
467 }
468
469 if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) {
470 presto->buff_out_pos = 0;
471 return ERROR_JTAG_DEVICE_ERROR;
472 }
473
474 presto->total_out += presto->buff_out_pos;
475 presto->buff_out_pos = 0;
476
477 if (presto->buff_in_exp == 0)
478 return ERROR_OK;
479
480 presto->buff_in_pos = 0;
481 presto->buff_in_len = 0;
482
483 if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) {
484 presto->buff_in_exp = 0;
485 return ERROR_JTAG_DEVICE_ERROR;
486 }
487
488 presto->total_in += presto->buff_in_exp;
489 presto->buff_in_len = presto->buff_in_exp;
490 presto->buff_in_exp = 0;
491
492 return ERROR_OK;
493 }
494
495 static int presto_sendbyte(int data)
496 {
497 if (data == EOF)
498 return presto_flush();
499
500 if (presto->buff_out_pos < BUFFER_SIZE) {
501 presto->buff_out[presto->buff_out_pos++] = (uint8_t)data;
502 if (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0))
503 presto->buff_in_exp++;
504 } else
505 return ERROR_JTAG_DEVICE_ERROR;
506
507 #if BUILD_PRESTO_FTD2XX == 1
508 if (presto->buff_out_pos >= BUFFER_SIZE)
509 #elif BUILD_PRESTO_LIBFTDI == 1
510 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
511 *bytes only!) */
512 if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
513 #endif
514 return presto_flush();
515
516 return ERROR_OK;
517 }
518
519 #if 0
520 static int presto_getbyte(void)
521 {
522 if (presto->buff_in_pos < presto->buff_in_len)
523 return presto->buff_in[presto->buff_in_pos++];
524
525 if (presto->buff_in_exp == 0)
526 return -1;
527
528 if (presto_flush() != ERROR_OK)
529 return -1;
530
531 if (presto->buff_in_pos < presto->buff_in_len)
532 return presto->buff_in[presto->buff_in_pos++];
533
534 return -1;
535 }
536 #endif
537
538 /* -------------------------------------------------------------------------- */
539
540 static int presto_tdi_flush(void)
541 {
542 if (presto->jtag_tdi_count == 0)
543 return 0;
544
545 if (presto->jtag_tck == 0) {
546 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
547 return -1;
548 }
549
550 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
551 presto_sendbyte(presto->jtag_tdi_data);
552 presto->jtag_tdi_count = 0;
553 presto->jtag_tdi_data = 0;
554
555 return 0;
556 }
557
558 static int presto_tck_idle(void)
559 {
560 if (presto->jtag_tck == 1) {
561 presto_sendbyte(0xCA);
562 presto->jtag_tck = 0;
563 }
564
565 return 0;
566 }
567
568 /* -------------------------------------------------------------------------- */
569
570 static int presto_bitq_out(int tms, int tdi, int tdo_req)
571 {
572 int i;
573 unsigned char cmd;
574
575 if (presto->jtag_tck == 0)
576 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
577 else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) {
578 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
579
580 if (++presto->jtag_tdi_count == 4)
581 presto_tdi_flush();
582
583 return 0;
584 }
585
586 presto_tdi_flush();
587
588 cmd = tdi ? 0xCB : 0xCA;
589 presto_sendbyte(cmd);
590
591 if (tms != presto->jtag_tms) {
592 presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));
593 presto->jtag_tms = tms;
594 }
595
596 /* delay with TCK low */
597 for (i = presto->jtag_speed; i > 1; i--)
598 presto_sendbyte(cmd);
599
600 cmd |= 0x04;
601 presto_sendbyte(cmd | (tdo_req ? 0x10 : 0));
602
603 /* delay with TCK high */
604 for (i = presto->jtag_speed; i > 1; i--)
605 presto_sendbyte(cmd);
606
607 presto->jtag_tck = 1;
608
609 return 0;
610 }
611
612 static int presto_bitq_flush(void)
613 {
614 presto_tdi_flush();
615 presto_tck_idle();
616
617 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
618
619 return presto_flush();
620 }
621
622 static int presto_bitq_in_rdy(void)
623 {
624 if (presto->buff_in_pos >= presto->buff_in_len)
625 return 0;
626 return presto->buff_in_len-presto->buff_in_pos;
627 }
628
629 static int presto_bitq_in(void)
630 {
631 if (presto->buff_in_pos >= presto->buff_in_len)
632 return -1;
633 if (presto->buff_in[presto->buff_in_pos++]&0x08)
634 return 1;
635 return 0;
636 }
637
638 static int presto_bitq_sleep(unsigned long us)
639 {
640 long waits;
641
642 presto_tdi_flush();
643 presto_tck_idle();
644
645 if (us > 100000) {
646 presto_bitq_flush();
647 jtag_sleep(us);
648 return 0;
649 }
650
651 waits = us / 170 + 2;
652 while (waits--)
653 presto_sendbyte(0x80);
654
655 return 0;
656 }
657
658 static int presto_bitq_reset(int trst, int srst)
659 {
660 presto_tdi_flush();
661 presto_tck_idle();
662
663 /* add a delay after possible TCK transition */
664 presto_sendbyte(0x80);
665 presto_sendbyte(0x80);
666
667 presto->jtag_rst = trst || srst;
668 presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0));
669
670 return 0;
671 }
672
673 static struct bitq_interface presto_bitq = {
674 .out = &presto_bitq_out,
675 .flush = &presto_bitq_flush,
676 .sleep = &presto_bitq_sleep,
677 .reset = &presto_bitq_reset,
678 .in_rdy = &presto_bitq_in_rdy,
679 .in = &presto_bitq_in,
680 };
681
682 /* -------------------------------------------------------------------------- */
683
684 static int presto_adapter_khz(int khz, int *jtag_speed)
685 {
686 if (khz < 0) {
687 *jtag_speed = 0;
688 return ERROR_COMMAND_SYNTAX_ERROR;
689 }
690
691 if (khz >= 3000)
692 *jtag_speed = 0;
693 else
694 *jtag_speed = (1000 + khz-1)/khz;
695
696 return 0;
697 }
698
699 static int presto_jtag_speed_div(int speed, int *khz)
700 {
701 if ((speed < 0) || (speed > 1000)) {
702 *khz = 0;
703 return ERROR_COMMAND_SYNTAX_ERROR;
704 }
705
706 if (speed == 0)
707 *khz = 3000;
708 else
709 *khz = 1000/speed;
710
711 return 0;
712 }
713
714 static int presto_jtag_speed(int speed)
715 {
716 int khz;
717
718 if (presto_jtag_speed_div(speed, &khz))
719 return ERROR_COMMAND_SYNTAX_ERROR;
720
721 presto->jtag_speed = speed;
722
723 if (khz%1000 == 0)
724 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed, khz/1000);
725 else
726 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed, khz);
727
728 return 0;
729 }
730
731 static char *presto_serial;
732
733 COMMAND_HANDLER(presto_handle_serial_command)
734 {
735 if (CMD_ARGC == 1) {
736 if (presto_serial)
737 free(presto_serial);
738 presto_serial = strdup(CMD_ARGV[0]);
739 } else
740 return ERROR_COMMAND_SYNTAX_ERROR;
741
742 return ERROR_OK;
743 }
744
745 static const struct command_registration presto_command_handlers[] = {
746 {
747 .name = "presto_serial",
748 .handler = presto_handle_serial_command,
749 .mode = COMMAND_CONFIG,
750 .help = "Configure USB serial number of Presto device.",
751 .usage = "serial_string",
752 },
753 COMMAND_REGISTRATION_DONE
754 };
755
756 static int presto_jtag_init(void)
757 {
758 if (presto_open(presto_serial) != ERROR_OK) {
759 presto_close();
760 if (presto_serial != NULL)
761 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
762 else
763 LOG_ERROR("Cannot open PRESTO");
764 return ERROR_JTAG_INIT_FAILED;
765 }
766 LOG_INFO("PRESTO open, serial number '%s'", presto->serial);
767
768 bitq_interface = &presto_bitq;
769 return ERROR_OK;
770 }
771
772 static int presto_jtag_quit(void)
773 {
774 bitq_cleanup();
775 presto_close();
776 LOG_INFO("PRESTO closed");
777
778 if (presto_serial) {
779 free(presto_serial);
780 presto_serial = NULL;
781 }
782
783 return ERROR_OK;
784 }
785
786 struct jtag_interface presto_interface = {
787 .name = "presto",
788 .commands = presto_command_handlers,
789
790 .execute_queue = bitq_execute_queue,
791 .speed = presto_jtag_speed,
792 .khz = presto_adapter_khz,
793 .speed_div = presto_jtag_speed_div,
794 .init = presto_jtag_init,
795 .quit = presto_jtag_quit,
796 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)