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

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)