prettier async output
[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, u32* bytes_written)
143 {
144 #if BUILD_PRESTO_FTD2XX == 1
145 DWORD dw_bytes_written;
146 if ((presto->status = FT_Write(presto->handle, buf, size, &dw_bytes_written)) != FT_OK)
147 {
148 *bytes_written = dw_bytes_written;
149 ERROR("FT_Write returned: %lu", presto->status);
150 return ERROR_JTAG_DEVICE_ERROR;
151 }
152 else
153 {
154 *bytes_written = dw_bytes_written;
155 return ERROR_OK;
156 }
157 #elif BUILD_PRESTO_LIBFTDI == 1
158 if ((presto->retval = ftdi_write_data(&presto->ftdic, buf, size)) < 0)
159 {
160 *bytes_written = 0;
161 ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
162 return ERROR_JTAG_DEVICE_ERROR;
163 }
164 else
165 {
166 *bytes_written = presto->retval; /* FIXME: Correct? */
167 return ERROR_OK;
168 }
169 #endif
170 }
171
172 int presto_read(u8* buf, int size, u32* bytes_read)
173 {
174 #if BUILD_PRESTO_FTD2XX == 1
175 DWORD dw_bytes_read;
176 int timeout = 5;
177 *bytes_read = 0;
178
179 while ((*bytes_read < size) && timeout--)
180 {
181 if ((presto->status = FT_Read(presto->handle, buf + *bytes_read, size -
182 *bytes_read, &dw_bytes_read)) != FT_OK)
183 {
184 *bytes_read = 0;
185 ERROR("FT_Read returned: %lu", presto->status);
186 return ERROR_JTAG_DEVICE_ERROR;
187 }
188 *bytes_read += dw_bytes_read;
189 }
190 #elif BUILD_PRESTO_LIBFTDI == 1
191 int timeout = 100;
192 *bytes_read = 0;
193
194 while ((*bytes_read < size) && timeout--)
195 {
196 if ((presto->retval = ftdi_read_data(&presto->ftdic, buf + *bytes_read, size - *bytes_read)) < 0)
197 {
198 *bytes_read = 0;
199 ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
200 return ERROR_JTAG_DEVICE_ERROR;
201 }
202 *bytes_read += presto->retval; /* FIXME: Correct? */
203 }
204 #endif
205
206 if (*bytes_read < size)
207 {
208 ERROR("couldn't read the requested number of bytes from PRESTO (%i < %i)", *bytes_read, size);
209 return ERROR_JTAG_DEVICE_ERROR;
210 }
211
212 return ERROR_OK;
213 }
214
215 #if BUILD_PRESTO_FTD2XX == 1
216 int presto_open_ftd2xx(char *req_serial)
217 {
218 int i;
219 DWORD numdevs;
220 DWORD vidpid;
221 char devname[FT_DEVICE_NAME_LEN];
222 FT_DEVICE device;
223
224 BYTE presto_data;
225 unsigned long ftbytes;
226
227 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
228
229 #if IS_WIN32 == 0
230 /* Add non-standard Vid/Pid to the linux driver */
231 if ((presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID)) != FT_OK)
232 {
233 ERROR("couldn't add PRESTO VID/PID");
234 exit(-1);
235 }
236 #endif
237
238 if ((presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)) != FT_OK)
239 {
240 ERROR("FT_ListDevices failed: %i", (int)presto->status);
241 return ERROR_JTAG_DEVICE_ERROR;
242 }
243
244 DEBUG("FTDI devices available: %i", numdevs);
245 for (i = 0; i < numdevs; i++)
246 {
247 if ((presto->status = FT_Open(i, &(presto->handle))) != FT_OK)
248 {
249 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
250 DEBUG("FT_Open failed: %i", (int)presto->status);
251 continue;
252 }
253 DEBUG("FTDI device %i open", i);
254
255 if ((presto->status = FT_GetDeviceInfo(presto->handle, &device, &vidpid,
256 presto->serial, devname, NULL)) == FT_OK)
257 {
258 if (vidpid == PRESTO_VID_PID
259 && (req_serial == NULL || !strcmp(presto->serial, req_serial)))
260 break;
261 }
262 else
263 DEBUG("FT_GetDeviceInfo failed: %i", presto->status);
264
265 DEBUG("FTDI device %i does not match, closing", i);
266 FT_Close(presto->handle);
267 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
268 }
269
270 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
271 return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
272
273 if ((presto->status = FT_SetLatencyTimer(presto->handle, 1)) != FT_OK)
274 return ERROR_JTAG_DEVICE_ERROR;
275
276
277 if ((presto->status = FT_SetTimeouts(presto->handle, 100, 0)) != FT_OK)
278 return ERROR_JTAG_DEVICE_ERROR;
279
280 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
281 return ERROR_JTAG_DEVICE_ERROR;
282
283 presto_data = 0xD0;
284 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != 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 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
291 return ERROR_JTAG_DEVICE_ERROR;
292
293 if (ftbytes!=1)
294 {
295 DEBUG("PRESTO reset");
296
297 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
298 return ERROR_JTAG_DEVICE_ERROR;
299 if ((presto->status = FT_SetBitMode(presto->handle, 0x80, 1)) != FT_OK)
300 return ERROR_JTAG_DEVICE_ERROR;
301 if ((presto->status = FT_SetBaudRate(presto->handle, 9600)) != FT_OK)
302 return ERROR_JTAG_DEVICE_ERROR;
303
304 presto_data = 0;
305 for (i = 0; i < 4 * 62; i++)
306 if ((presto->status=FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
307 return ERROR_JTAG_DEVICE_ERROR;
308
309 usleep(100000);
310
311 if ((presto->status = FT_SetBitMode(presto->handle, 0x00, 0)) != FT_OK)
312 return ERROR_JTAG_DEVICE_ERROR;
313
314 if ((presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX)) != FT_OK)
315 return ERROR_JTAG_DEVICE_ERROR;
316
317 presto_data = 0xD0;
318 if ((presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
319 return ERROR_JTAG_DEVICE_ERROR;
320
321 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
322 probably a bug in library threading */
323 usleep(100000);
324 if ((presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes)) != FT_OK)
325 return ERROR_JTAG_DEVICE_ERROR;
326
327 if (ftbytes!=1)
328 {
329 DEBUG("PRESTO not responding");
330 return ERROR_JTAG_DEVICE_ERROR;
331 }
332 }
333
334 if ((presto->status = FT_SetTimeouts(presto->handle, 0, 0)) != FT_OK)
335 return ERROR_JTAG_DEVICE_ERROR;
336
337
338 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
339 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
340 return ERROR_JTAG_DEVICE_ERROR;
341
342 return ERROR_OK;
343 }
344
345 #elif BUILD_PRESTO_LIBFTDI == 1
346 int presto_open_libftdi(char *req_serial)
347 {
348 u8 presto_data;
349 u32 ftbytes;
350
351 DEBUG("searching for presto JTAG interface using libftdi");
352
353 /* context, vendor id, product id */
354 if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0)
355 {
356 ERROR("unable to open presto: %s", presto->ftdic.error_str);
357 return ERROR_JTAG_DEVICE_ERROR;
358 }
359
360 if (ftdi_usb_reset(&presto->ftdic) < 0)
361 {
362 ERROR("unable to reset presto device");
363 return ERROR_JTAG_DEVICE_ERROR;
364 }
365
366 if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0)
367 {
368 ERROR("unable to set latency timer");
369 return ERROR_JTAG_DEVICE_ERROR;
370 }
371
372 if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
373 {
374 ERROR("unable to purge presto buffer");
375 return ERROR_JTAG_DEVICE_ERROR;
376 }
377
378 presto_data = 0xD0;
379 if ((presto->retval = presto_write(&presto_data, 1, &ftbytes)) != ERROR_OK)
380 return ERROR_JTAG_DEVICE_ERROR;
381 if ((presto->retval = presto_read(&presto_data, 1, &ftbytes)) != ERROR_OK)
382 return ERROR_JTAG_DEVICE_ERROR;
383
384 return ERROR_OK;
385 }
386 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
387
388 int presto_open(char *req_serial)
389 {
390 presto->buff_out_pos=0;
391 presto->buff_in_pos=0;
392 presto->buff_in_len=0;
393 presto->buff_in_exp=0;
394
395 presto->total_out=0;
396 presto->total_in=0;
397
398 presto->jtag_tms=0;
399 presto->jtag_tck=0;
400 presto->jtag_tdi_data=0;
401 presto->jtag_tdi_count=0;
402
403 #if BUILD_PRESTO_FTD2XX == 1
404 return presto_open_ftd2xx(req_serial);
405 #elif BUILD_PRESTO_LIBFTDI == 1
406 return presto_open_libftdi(req_serial);
407 #endif
408 }
409
410 int presto_close(void)
411 {
412
413 int result = ERROR_OK;
414
415 #if BUILD_PRESTO_FTD2XX == 1
416 unsigned long ftbytes;
417
418 if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
419 return result;
420
421 presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
422 if (presto->status != FT_OK)
423 result = ERROR_JTAG_DEVICE_ERROR;
424
425 presto->status = FT_Write(presto->handle, &presto_init_seq, sizeof(presto_init_seq), &ftbytes);
426 if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
427 result = ERROR_JTAG_DEVICE_ERROR;
428
429 if ((presto->status = FT_SetLatencyTimer(presto->handle, 16)) != FT_OK)
430 result = ERROR_JTAG_DEVICE_ERROR;
431
432 if ((presto->status = FT_Close(presto->handle)) != FT_OK)
433 result = ERROR_JTAG_DEVICE_ERROR;
434 else
435 presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
436
437 #elif BUILD_PRESTO_LIBFTDI == 1
438
439 if ((presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq))) < 0)
440 {
441 result = ERROR_JTAG_DEVICE_ERROR;
442 }
443
444 if ((presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16)) < 0)
445 {
446 result = ERROR_JTAG_DEVICE_ERROR;
447 }
448
449 ftdi_deinit(&presto->ftdic);
450
451 #endif
452
453 return result;
454 }
455
456
457 int presto_flush(void)
458 {
459 u32 ftbytes;
460
461 if (presto->buff_out_pos == 0)
462 return ERROR_OK;
463
464 #if BUILD_PRESTO_FTD2XX == 1
465 if (presto->status != FT_OK)
466 #elif BUILD_PRESTO_LIBFTDI == 1
467 if (presto->retval != ERROR_OK)
468 #endif
469 return ERROR_JTAG_DEVICE_ERROR;
470
471
472 if (presto_write(presto->buff_out, presto->buff_out_pos, &ftbytes) != ERROR_OK)
473 {
474 presto->buff_out_pos = 0;
475 return ERROR_JTAG_DEVICE_ERROR;
476 }
477
478 presto->total_out += ftbytes;
479
480 if (presto->buff_out_pos != ftbytes)
481 {
482 presto->buff_out_pos = 0;
483 return ERROR_JTAG_DEVICE_ERROR;
484 }
485
486 presto->buff_out_pos = 0;
487
488 if (presto->buff_in_exp == 0)
489 return ERROR_OK;
490
491 presto->buff_in_pos = 0;
492 presto->buff_in_len = 0;
493
494 if (presto_read(presto->buff_in, presto->buff_in_exp, &ftbytes) != ERROR_OK)
495 {
496 presto->buff_in_exp = 0;
497 return ERROR_JTAG_DEVICE_ERROR;
498 }
499
500 presto->total_in += ftbytes;
501
502 if (ftbytes != presto->buff_in_exp)
503 {
504 presto->buff_in_exp = 0;
505 return ERROR_JTAG_DEVICE_ERROR;
506 }
507
508 presto->buff_in_len = presto->buff_in_exp;
509 presto->buff_in_exp = 0;
510
511 return ERROR_OK;
512 }
513
514
515 int presto_sendbyte(int data)
516 {
517 if (data == EOF) return presto_flush();
518
519 if (presto->buff_out_pos < BUFFER_SIZE)
520 {
521 presto->buff_out[presto->buff_out_pos++] = (u8)data;
522 if (((data & 0xC0) == 0x40) || ((data & 0xD0)== 0xD0))
523 presto->buff_in_exp++;
524 }
525 else
526 return ERROR_JTAG_DEVICE_ERROR;
527
528 if (presto->buff_out_pos >= BUFFER_SIZE)
529 return presto_flush();
530
531 return ERROR_OK;
532 }
533
534
535 int presto_getbyte(void)
536 {
537 if (presto->buff_in_pos < presto->buff_in_len)
538 return presto->buff_in[presto->buff_in_pos++];
539
540 if (presto->buff_in_exp == 0)
541 return -1;
542
543 if (presto_flush() != ERROR_OK)
544 return -1;
545
546 if (presto->buff_in_pos<presto->buff_in_len)
547 return presto->buff_in[presto->buff_in_pos++];
548
549 return -1;
550 }
551
552
553 /* -------------------------------------------------------------------------- */
554
555
556 int presto_bitq_out(int tms, int tdi, int tdo_req)
557 {
558 unsigned char cmdparam;
559
560 if (presto->jtag_tck == 0)
561 {
562 presto_sendbyte(0xA4);
563 presto->jtag_tck = 1;
564 }
565
566 else if (!tdo_req && tms == presto->jtag_tms)
567 {
568 if (presto->jtag_tdi_count == 0)
569 presto->jtag_tdi_data = (tdi != 0);
570 else
571 presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;
572
573 if (++presto->jtag_tdi_count == 4)
574 {
575 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
576 presto_sendbyte(presto->jtag_tdi_data);
577 presto->jtag_tdi_count = 0;
578 }
579 return 0;
580 }
581
582 if (presto->jtag_tdi_count)
583 {
584 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
585 presto_sendbyte(presto->jtag_tdi_data);
586 presto->jtag_tdi_count = 0;
587 }
588
589 if (tdi)
590 cmdparam = 0x0B;
591 else
592 cmdparam = 0x0A;
593
594 presto_sendbyte( 0xC0 | cmdparam);
595
596 if (tms != presto->jtag_tms)
597 {
598 if (tms)
599 presto_sendbyte(0xEC);
600 else
601 presto_sendbyte(0xE8);
602 presto->jtag_tms = tms;
603 }
604
605 if (tdo_req)
606 presto_sendbyte(0xD4 | cmdparam);
607 else
608 presto_sendbyte(0xC4|cmdparam);
609
610 return 0;
611 }
612
613
614 int presto_bitq_flush(void)
615 {
616 if (presto->jtag_tdi_count)
617 {
618 presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
619 presto_sendbyte(presto->jtag_tdi_data);
620 presto->jtag_tdi_count = 0;
621 }
622
623 presto_sendbyte(0xCA);
624 presto->jtag_tck = 0;
625
626 presto_sendbyte(0xA0);
627
628 return presto_flush();
629 }
630
631
632 int presto_bitq_in_rdy(void)
633 {
634 if (presto->buff_in_pos>=presto->buff_in_len)
635 return 0;
636 return presto->buff_in_len-presto->buff_in_pos;
637 }
638
639
640 int presto_bitq_in(void)
641 {
642 if (presto->buff_in_pos>=presto->buff_in_len)
643 return -1;
644 if (presto->buff_in[presto->buff_in_pos++]&0x08) return 1;
645 return 0;
646 }
647
648
649 int presto_bitq_sleep(unsigned long us)
650 {
651 long waits;
652
653 if (us > 100000)
654 {
655 presto_bitq_flush();
656 jtag_sleep(us);
657 return 0;
658 }
659
660 waits = us / 170 + 2;
661 while (waits--)
662 presto_sendbyte(0x80);
663
664 return 0;
665 }
666
667
668 int presto_bitq_reset(int trst, int srst)
669 {
670 unsigned char cmd;
671
672 cmd = 0xE8;
673 if (presto->jtag_tms)
674 cmd |= 0x04;
675
676 if (trst || srst)
677 cmd |= 0x02;
678
679 presto_sendbyte(cmd);
680 return 0;
681 }
682
683
684 /* -------------------------------------------------------------------------- */
685
686 char *presto_speed_text[4] =
687 {
688 "3 MHz",
689 "1.5 MHz",
690 "750 kHz",
691 "93.75 kHz"
692 };
693
694 int presto_jtag_speed(int speed)
695 {
696
697 if ((speed < 0) || (speed > 3))
698 {
699 INFO("valid speed values: 0 (3 MHz), 1 (1.5 MHz), 2 (750 kHz) and 3 (93.75 kHz)");
700 return ERROR_INVALID_ARGUMENTS;
701 }
702
703 jtag_speed = speed;
704 INFO("setting speed to %d, max. TCK freq. is %s", speed, presto_speed_text[speed]);
705 return presto_sendbyte(0xA8 | speed);
706 }
707
708
709 char *presto_serial;
710
711 int presto_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
712 {
713 if (argc == 1)
714 {
715 if (presto_serial)
716 free(presto_serial);
717 presto_serial = strdup(args[0]);
718 }
719 else
720 {
721 ERROR("expected exactly one argument to presto_serial <serial-number>");
722 }
723
724 return ERROR_OK;
725 }
726
727
728 int presto_jtag_register_commands(struct command_context_s *cmd_ctx)
729 {
730 register_command(cmd_ctx, NULL, "presto_serial", presto_handle_serial_command,
731 COMMAND_CONFIG, NULL);
732 return ERROR_OK;
733 }
734
735
736 int presto_jtag_init(void)
737 {
738 if (presto_open(presto_serial) != ERROR_OK)
739 {
740 presto_close();
741 if (presto_serial != NULL)
742 ERROR("Cannot open PRESTO, serial number '%s'", presto_serial);
743 else
744 ERROR("Cannot open PRESTO");
745 return ERROR_JTAG_INIT_FAILED;
746 }
747 INFO("PRESTO open, serial number '%s'", presto->serial);
748
749 /* use JTAG speed setting from configuration file */
750 presto_jtag_speed(jtag_speed);
751
752 bitq_interface = &presto_bitq;
753 return ERROR_OK;
754 }
755
756
757 int presto_jtag_quit(void)
758 {
759 bitq_cleanup();
760 presto_close();
761 INFO("PRESTO closed");
762
763 if (presto_serial)
764 {
765 free(presto_serial);
766 presto_serial = NULL;
767 }
768
769 return ERROR_OK;
770 }

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)