b23d196b9a3aa8edb619d90e3c7fb5732feab6b2
[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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
39 /* PRESTO access library includes */
40 #if BUILD_PRESTO_FTD2XX == 1
41 #include <ftd2xx.h>
42 #include "ftd2xx_common.h"
43 #elif BUILD_PRESTO_LIBFTDI == 1
44 #include <ftdi.h>
45 #else
46 #error "BUG: either FTD2XX and LIBFTDI has to be used"
47 #endif
48
49 /* -------------------------------------------------------------------------- */
50
51 #define FT_DEVICE_NAME_LEN 64
52 #define FT_DEVICE_SERNUM_LEN 64
53
54 #define PRESTO_VID_PID 0x0403f1a0
55 #define PRESTO_VID (0x0403)
56 #define PRESTO_PID (0xf1a0)
57
58 #define BUFFER_SIZE (64*62)
59
60 struct presto {
61 #if BUILD_PRESTO_FTD2XX == 1
62 FT_HANDLE handle;
63 FT_STATUS status;
64 #elif BUILD_PRESTO_LIBFTDI == 1
65 struct ftdi_context ftdic;
66 int retval;
67 #endif
68
69 char serial[FT_DEVICE_SERNUM_LEN];
70
71 uint8_t buff_out[BUFFER_SIZE];
72 int buff_out_pos;
73
74 uint8_t buff_in[BUFFER_SIZE];
75 int buff_in_exp; /* expected in buffer length */
76 int buff_in_len; /* length of data received */
77 int buff_in_pos;
78
79 unsigned long total_out;
80 unsigned long total_in;
81
82 int jtag_tms; /* last tms state */
83 int jtag_tck; /* last tck state */
84 int jtag_rst; /* last trst state */
85
86 int jtag_tdi_data;
87 int jtag_tdi_count;
88
89 int jtag_speed;
90 };
91
92 static struct presto presto_state;
93 static struct presto *presto = &presto_state;
94
95 static uint8_t presto_init_seq[] =
96 {
97 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
98 };
99
100 static int presto_write(uint8_t *buf, uint32_t size)
101 {
102 #if BUILD_PRESTO_FTD2XX == 1
103 DWORD ftbytes;
104 if ((presto->status = FT_Write(presto->handle, buf, size, &ftbytes)) != FT_OK)
105 {
106 LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto->status));
107 return ERROR_JTAG_DEVICE_ERROR;
108 }
109
110 #elif BUILD_PRESTO_LIBFTDI == 1
111 uint32_t ftbytes;
112 if ((presto->retval = ftdi_write_data(&presto->ftdic, buf, size)) < 0)
113 {
114 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
115 return ERROR_JTAG_DEVICE_ERROR;
116 }
117 ftbytes = presto->retval;
118 #endif
119
120 if (ftbytes != size)
121 {
122 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
123 (unsigned)ftbytes, (unsigned)size);
124 return ERROR_JTAG_DEVICE_ERROR;
125 }
126
127 return ERROR_OK;
128 }
129
130 static int presto_read(uint8_t* buf, uint32_t size)
131 {
132 #if BUILD_PRESTO_FTD2XX == 1
133 DWORD ftbytes;
134 if ((presto->status = FT_Read(presto->handle, buf, size, &ftbytes)) != FT_OK)
135 {
136 LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto->status));
137 return ERROR_JTAG_DEVICE_ERROR;
138 }
139
140 #elif BUILD_PRESTO_LIBFTDI == 1
141 uint32_t ftbytes = 0;
142
143 struct timeval timeout, now;
144 gettimeofday(&timeout, NULL);
145 timeval_add_time(&timeout, 1, 0); /* one second timeout */
146
147 while (ftbytes < size)
148 {
149 if ((presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes)) < 0)
150 {
151 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
152 return ERROR_JTAG_DEVICE_ERROR;
153 }
154 ftbytes += presto->retval;
155
156 gettimeofday(&now, NULL);
157 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
158 break;
159 }
160 #endif
161
162 if (ftbytes != size)
163 {
164 /* this is just a warning, there might have been timeout when detecting PRESTO, which is not fatal */
165 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
166 (unsigned)ftbytes, (unsigned)size);
167 return ERROR_JTAG_DEVICE_ERROR;
168 }
169
170 return ERROR_OK;
171 }
172
173 #if BUILD_PRESTO_FTD2XX == 1
174 static int presto_open_ftd2xx(char *req_serial)
175 {
176 uint32_t i;
177 DWORD numdevs;
178 DWORD vidpid;
179 char devname[FT_DEVICE_NAME_LEN];
180 FT_DEVICE device;
181
182 BYTE presto_data;
183 DWORD ftbytes;
184
185 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
186
187 #if IS_WIN32 == 0
188 /* Add non-standard Vid/Pid to the linux driver */
189 if ((presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID)) != FT_OK)
190 {
191 LOG_ERROR("couldn't add PRESTO VID/PID");
192 exit(-1);
193 }
194 #endif
195
196 if ((presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)) != FT_OK)
197 {
198 LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
199 return ERROR_JTAG_DEVICE_ERROR;
200 }
201
202 LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
203 for (i = 0; i < numdevs; i++)
204 {
205 if ((presto->status = FT_Open(i, &(presto->handle))) != FT_OK)
206 {
207 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
208 LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
209 continue;
210 }
211 LOG_DEBUG("FTDI device %i open", (int)i);
212
213 if ((presto->status = FT_GetDeviceInfo(presto->handle, &device, &vidpid,
214 presto->serial, devname, NULL)) == FT_OK)
215 {
216 if (vidpid == PRESTO_VID_PID
217 && (req_serial == NULL || !strcmp(presto->serial, req_serial)))
218 break;
219 }
220 else
221 LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(presto->status));
222
223 LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
224 FT_Close(presto->handle);
225 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
226 }
227
228 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
229 return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
230
231 if ((presto->status = FT_SetLatencyTimer(presto->handle, 1)) != FT_OK)
232 return ERROR_JTAG_DEVICE_ERROR;
233
234
235 if ((presto->status = FT_SetTimeouts(presto->handle, 100, 0)) != FT_OK)
236 return ERROR_JTAG_DEVICE_ERROR;
237
238 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
239 return ERROR_JTAG_DEVICE_ERROR;
240
241 presto_data = 0xD0;
242 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
243 return ERROR_JTAG_DEVICE_ERROR;
244
245 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
246 probably a bug in library threading */
247 usleep(100000);
248 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
249 return ERROR_JTAG_DEVICE_ERROR;
250
251 if (ftbytes != 1)
252 {
253 LOG_DEBUG("PRESTO reset");
254
255 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
256 return ERROR_JTAG_DEVICE_ERROR;
257 if ((presto->status = FT_SetBitMode(presto->handle, 0x80, 1)) != FT_OK)
258 return ERROR_JTAG_DEVICE_ERROR;
259 if ((presto->status = FT_SetBaudRate(presto->handle, 9600)) != FT_OK)
260 return ERROR_JTAG_DEVICE_ERROR;
261
262 presto_data = 0;
263 for (i = 0; i < 4 * 62; i++)
264 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
265 return ERROR_JTAG_DEVICE_ERROR;
266
267 usleep(100000);
268
269 if ((presto->status = FT_SetBitMode(presto->handle, 0x00, 0)) != FT_OK)
270 return ERROR_JTAG_DEVICE_ERROR;
271
272 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
273 return ERROR_JTAG_DEVICE_ERROR;
274
275 presto_data = 0xD0;
276 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
277 return ERROR_JTAG_DEVICE_ERROR;
278
279 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
280 probably a bug in library threading */
281 usleep(100000);
282 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
283 return ERROR_JTAG_DEVICE_ERROR;
284
285 if (ftbytes != 1)
286 {
287 LOG_DEBUG("PRESTO not responding");
288 return ERROR_JTAG_DEVICE_ERROR;
289 }
290 }
291
292 if ((presto->status = FT_SetTimeouts(presto->handle, 0, 0)) != FT_OK)
293 return ERROR_JTAG_DEVICE_ERROR;
294
295
296 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
297 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
298 return ERROR_JTAG_DEVICE_ERROR;
299
300 return ERROR_OK;
301 }
302
303 #elif BUILD_PRESTO_LIBFTDI == 1
304 static int presto_open_libftdi(char *req_serial)
305 {
306 uint8_t presto_data;
307
308 LOG_DEBUG("searching for PRESTO using libftdi");
309
310 /* initialize FTDI context structure */
311 if (ftdi_init(&presto->ftdic) < 0)
312 {
313 LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str);
314 return ERROR_JTAG_DEVICE_ERROR;
315 }
316
317 /* context, vendor id, product id */
318 if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0)
319 {
320 LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str);
321 return ERROR_JTAG_DEVICE_ERROR;
322 }
323
324 if (ftdi_usb_reset(&presto->ftdic) < 0)
325 {
326 LOG_ERROR("unable to reset PRESTO device");
327 return ERROR_JTAG_DEVICE_ERROR;
328 }
329
330 if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0)
331 {
332 LOG_ERROR("unable to set latency timer");
333 return ERROR_JTAG_DEVICE_ERROR;
334 }
335
336 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
337 {
338 LOG_ERROR("unable to purge PRESTO buffers");
339 return ERROR_JTAG_DEVICE_ERROR;
340 }
341
342 presto_data = 0xD0;
343 if (presto_write(&presto_data, 1) != ERROR_OK)
344 {
345 LOG_ERROR("error writing to PRESTO");
346 return ERROR_JTAG_DEVICE_ERROR;
347 }
348
349 if (presto_read(&presto_data, 1) != ERROR_OK)
350 {
351 LOG_DEBUG("no response from PRESTO, retrying");
352
353 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
354 return ERROR_JTAG_DEVICE_ERROR;
355
356 presto_data = 0xD0;
357 if (presto_write(&presto_data, 1) != ERROR_OK)
358 return ERROR_JTAG_DEVICE_ERROR;
359
360 if (presto_read(&presto_data, 1) != ERROR_OK)
361 {
362 LOG_ERROR("no response from PRESTO, giving up");
363 return ERROR_JTAG_DEVICE_ERROR;
364 }
365 }
366
367 if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK)
368 {
369 LOG_ERROR("error writing PRESTO init sequence");
370 return ERROR_JTAG_DEVICE_ERROR;
371 }
372
373 return ERROR_OK;
374 }
375 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
376
377 static int presto_open(char *req_serial)
378 {
379 presto->buff_out_pos = 0;
380 presto->buff_in_pos = 0;
381 presto->buff_in_len = 0;
382 presto->buff_in_exp = 0;
383
384 presto->total_out = 0;
385 presto->total_in = 0;
386
387 presto->jtag_tms = 0;
388 presto->jtag_tck = 0;
389 presto->jtag_rst = 0;
390 presto->jtag_tdi_data = 0;
391 presto->jtag_tdi_count = 0;
392
393 presto->jtag_speed = 0;
394
395 #if BUILD_PRESTO_FTD2XX == 1
396 return presto_open_ftd2xx(req_serial);
397 #elif BUILD_PRESTO_LIBFTDI == 1
398 return presto_open_libftdi(req_serial);
399 #endif
400 }
401
402 static int presto_close(void)
403 {
404
405 int result = ERROR_OK;
406
407 #if BUILD_PRESTO_FTD2XX == 1
408 DWORD ftbytes;
409
410 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
411 return result;
412
413 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
414 if (presto->status != FT_OK)
415 result = ERROR_JTAG_DEVICE_ERROR;
416
417 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
418 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
419 result = ERROR_JTAG_DEVICE_ERROR;
420
421 if ((presto->status = FT_SetLatencyTimer(presto->handle, 16)) != FT_OK)
422 result = ERROR_JTAG_DEVICE_ERROR;
423
424 if ((presto->status = FT_Close(presto->handle)) != FT_OK)
425 result = ERROR_JTAG_DEVICE_ERROR;
426 else
427 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
428
429 #elif BUILD_PRESTO_LIBFTDI == 1
430
431 if ((presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq))) != sizeof(presto_init_seq))
432 result = ERROR_JTAG_DEVICE_ERROR;
433
434 if ((presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16)) < 0)
435 result = ERROR_JTAG_DEVICE_ERROR;
436
437 if ((presto->retval = ftdi_usb_close(&presto->ftdic)) < 0)
438 result = ERROR_JTAG_DEVICE_ERROR;
439 else
440 ftdi_deinit(&presto->ftdic);
441 #endif
442
443 return result;
444 }
445
446 static int presto_flush(void)
447 {
448 if (presto->buff_out_pos == 0)
449 return ERROR_OK;
450
451 #if BUILD_PRESTO_FTD2XX == 1
452 if (presto->status != FT_OK)
453 #elif BUILD_PRESTO_LIBFTDI == 1
454 if (presto->retval < 0)
455 #endif
456 {
457 LOG_DEBUG("error in previous communication, canceling I/O operation");
458 return ERROR_JTAG_DEVICE_ERROR;
459 }
460
461 if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK)
462 {
463 presto->buff_out_pos = 0;
464 return ERROR_JTAG_DEVICE_ERROR;
465 }
466
467 presto->total_out += presto->buff_out_pos;
468 presto->buff_out_pos = 0;
469
470 if (presto->buff_in_exp == 0)
471 return ERROR_OK;
472
473 presto->buff_in_pos = 0;
474 presto->buff_in_len = 0;
475
476 if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK)
477 {
478 presto->buff_in_exp = 0;
479 return ERROR_JTAG_DEVICE_ERROR;
480 }
481
482 presto->total_in += presto->buff_in_exp;
483 presto->buff_in_len = presto->buff_in_exp;
484 presto->buff_in_exp = 0;
485
486 return ERROR_OK;
487 }
488
489 static int presto_sendbyte(int data)
490 {
491 if (data == EOF) return presto_flush();
492
493 if (presto->buff_out_pos < BUFFER_SIZE)
494 {
495 presto->buff_out[presto->buff_out_pos++] = (uint8_t)data;
496 if (((data & 0xC0) == 0x40) || ((data & 0xD0)== 0xD0))
497 presto->buff_in_exp++;
498 }
499 else
500 return ERROR_JTAG_DEVICE_ERROR;
501
502 #if BUILD_PRESTO_FTD2XX == 1
503 if (presto->buff_out_pos >= BUFFER_SIZE)
504 #elif BUILD_PRESTO_LIBFTDI == 1
505 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128 bytes only!) */
506 if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
507 #endif
508 return presto_flush();
509
510 return ERROR_OK;
511 }
512
513 #if 0
514 static int presto_getbyte(void)
515 {
516 if (presto->buff_in_pos < presto->buff_in_len)
517 return presto->buff_in[presto->buff_in_pos++];
518
519 if (presto->buff_in_exp == 0)
520 return -1;
521
522 if (presto_flush() != ERROR_OK)
523 return -1;
524
525 if (presto->buff_in_pos < presto->buff_in_len)
526 return presto->buff_in[presto->buff_in_pos++];
527
528 return -1;
529 }
530 #endif
531
532 /* -------------------------------------------------------------------------- */
533
534 static int presto_tdi_flush(void)
535 {
536 if (presto->jtag_tdi_count == 0)
537 return 0;
538
539 if (presto->jtag_tck == 0)
540 {
541 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
542 return -1;
543 }
544
545 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
546 presto_sendbyte(presto->jtag_tdi_data);
547 presto->jtag_tdi_count = 0;
548 presto->jtag_tdi_data = 0;
549
550 return 0;
551 }
552
553 static int presto_tck_idle(void)
554 {
555 if (presto->jtag_tck == 1)
556 {
557 presto_sendbyte(0xCA);
558 presto->jtag_tck = 0;
559 }
560
561 return 0;
562 }
563
564 /* -------------------------------------------------------------------------- */
565
566 static int presto_bitq_out(int tms, int tdi, int tdo_req)
567 {
568 int i;
569 unsigned char cmd;
570
571 if (presto->jtag_tck == 0)
572 {
573 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
574 }
575 else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms)
576 {
577 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
578
579 if (++presto->jtag_tdi_count == 4)
580 presto_tdi_flush();
581
582 return 0;
583 }
584
585 presto_tdi_flush();
586
587 cmd = tdi ? 0xCB : 0xCA;
588 presto_sendbyte(cmd);
589
590 if (tms != presto->jtag_tms)
591 {
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) return 1;
634 return 0;
635 }
636
637 static int presto_bitq_sleep(unsigned long us)
638 {
639 long waits;
640
641 presto_tdi_flush();
642 presto_tck_idle();
643
644 if (us > 100000)
645 {
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 {
688 *jtag_speed = 0;
689 return ERROR_INVALID_ARGUMENTS;
690 }
691
692 if (khz >= 3000) *jtag_speed = 0;
693 else *jtag_speed = (1000 + khz-1)/khz;
694
695 return 0;
696 }
697
698 static int presto_jtag_speed_div(int speed, int *khz)
699 {
700 if ((speed < 0) || (speed > 1000))
701 {
702 *khz = 0;
703 return ERROR_INVALID_ARGUMENTS;
704 }
705
706 if (speed == 0) *khz = 3000;
707 else *khz = 1000/speed;
708
709 return 0;
710 }
711
712 static int presto_jtag_speed(int speed)
713 {
714 int khz;
715
716 if (presto_jtag_speed_div(speed, &khz))
717 {
718 return ERROR_INVALID_ARGUMENTS;
719 }
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 {
737 if (presto_serial)
738 free(presto_serial);
739 presto_serial = strdup(CMD_ARGV[0]);
740 }
741 else
742 {
743 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
744 }
745
746 return ERROR_OK;
747 }
748
749 static const struct command_registration presto_command_handlers[] = {
750 {
751 .name = "presto_serial",
752 .handler = presto_handle_serial_command,
753 .mode = COMMAND_CONFIG,
754 .help = "Configure USB serial number of Presto device.",
755 .usage = "serial_string",
756 },
757 COMMAND_REGISTRATION_DONE
758 };
759
760 static int presto_jtag_init(void)
761 {
762 if (presto_open(presto_serial) != ERROR_OK)
763 {
764 presto_close();
765 if (presto_serial != NULL)
766 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
767 else
768 LOG_ERROR("Cannot open PRESTO");
769 return ERROR_JTAG_INIT_FAILED;
770 }
771 LOG_INFO("PRESTO open, serial number '%s'", presto->serial);
772
773 bitq_interface = &presto_bitq;
774 return ERROR_OK;
775 }
776
777 static int presto_jtag_quit(void)
778 {
779 bitq_cleanup();
780 presto_close();
781 LOG_INFO("PRESTO closed");
782
783 if (presto_serial)
784 {
785 free(presto_serial);
786 presto_serial = NULL;
787 }
788
789 return ERROR_OK;
790 }
791
792 struct jtag_interface presto_interface = {
793 .name = "presto",
794 .commands = presto_command_handlers,
795
796 .execute_queue = bitq_execute_queue,
797 .speed = presto_jtag_speed,
798 .khz = presto_adapter_khz,
799 .speed_div = presto_jtag_speed_div,
800 .init = presto_jtag_init,
801 .quit = presto_jtag_quit,
802 };

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)