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

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)