1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
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. *
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. *
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 ***************************************************************************/
28 #include "interface.h"
29 #include "time_support.h"
33 /* PRESTO access library includes */
34 #if BUILD_PRESTO_FTD2XX == 1
36 #elif BUILD_PRESTO_LIBFTDI == 1
39 #error "BUG: either FTD2XX and LIBFTDI has to be used"
42 static int presto_jtag_speed(int speed
);
43 static int presto_jtag_khz(int khz
, int *jtag_speed
);
44 static int presto_jtag_speed_div(int speed
, int *khz
);
45 static int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
);
46 static int presto_jtag_init(void);
47 static int presto_jtag_quit(void);
49 struct jtag_interface presto_interface
=
52 .execute_queue
= bitq_execute_queue
,
53 .speed
= presto_jtag_speed
,
54 .khz
= presto_jtag_khz
,
55 .speed_div
= presto_jtag_speed_div
,
56 .register_commands
= presto_jtag_register_commands
,
57 .init
= presto_jtag_init
,
58 .quit
= presto_jtag_quit
,
61 static int presto_bitq_out(int tms
, int tdi
, int tdo_req
);
62 static int presto_bitq_flush(void);
63 static int presto_bitq_sleep(unsigned long us
);
64 static int presto_bitq_reset(int trst
, int srst
);
65 static int presto_bitq_in_rdy(void);
66 static int presto_bitq_in(void);
68 static struct bitq_interface presto_bitq
=
70 .out
= presto_bitq_out
,
71 .flush
= presto_bitq_flush
,
72 .sleep
= presto_bitq_sleep
,
73 .reset
= presto_bitq_reset
,
74 .in_rdy
= presto_bitq_in_rdy
,
78 /* -------------------------------------------------------------------------- */
80 #define FT_DEVICE_NAME_LEN 64
81 #define FT_DEVICE_SERNUM_LEN 64
83 #define PRESTO_VID_PID 0x0403f1a0
84 #define PRESTO_VID (0x0403)
85 #define PRESTO_PID (0xf1a0)
87 #define BUFFER_SIZE (64*62)
90 #if BUILD_PRESTO_FTD2XX == 1
93 #elif BUILD_PRESTO_LIBFTDI == 1
94 struct ftdi_context ftdic
;
98 char serial
[FT_DEVICE_SERNUM_LEN
];
100 uint8_t buff_out
[BUFFER_SIZE
];
103 uint8_t buff_in
[BUFFER_SIZE
];
104 int buff_in_exp
; /* expected in buffer length */
105 int buff_in_len
; /* length of data received */
108 unsigned long total_out
;
109 unsigned long total_in
;
111 int jtag_tms
; /* last tms state */
112 int jtag_tck
; /* last tck state */
113 int jtag_rst
; /* last trst state */
121 static struct presto presto_state
;
122 static struct presto
*presto
= &presto_state
;
124 static uint8_t presto_init_seq
[] =
126 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
129 static int presto_write(uint8_t *buf
, uint32_t size
)
131 #if BUILD_PRESTO_FTD2XX == 1
133 if ((presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
135 LOG_ERROR("FT_Write returned: %lu", presto
->status
);
136 return ERROR_JTAG_DEVICE_ERROR
;
139 #elif BUILD_PRESTO_LIBFTDI == 1
141 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
)) < 0)
143 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
144 return ERROR_JTAG_DEVICE_ERROR
;
146 ftbytes
= presto
->retval
;
151 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
152 (unsigned)ftbytes
, (unsigned)size
);
153 return ERROR_JTAG_DEVICE_ERROR
;
159 static int presto_read(uint8_t* buf
, uint32_t size
)
161 #if BUILD_PRESTO_FTD2XX == 1
163 if ((presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
165 LOG_ERROR("FT_Read returned: %lu", presto
->status
);
166 return ERROR_JTAG_DEVICE_ERROR
;
169 #elif BUILD_PRESTO_LIBFTDI == 1
170 uint32_t ftbytes
= 0;
172 struct timeval timeout
, now
;
173 gettimeofday(&timeout
, NULL
);
174 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
176 while (ftbytes
< size
)
178 if ((presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
)) < 0)
180 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
181 return ERROR_JTAG_DEVICE_ERROR
;
183 ftbytes
+= presto
->retval
;
185 gettimeofday(&now
, NULL
);
186 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
193 /* this is just a warning, there might have been timeout when detecting PRESTO, which is not fatal */
194 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
195 (unsigned)ftbytes
, (unsigned)size
);
196 return ERROR_JTAG_DEVICE_ERROR
;
202 #if BUILD_PRESTO_FTD2XX == 1
203 static int presto_open_ftd2xx(char *req_serial
)
208 char devname
[FT_DEVICE_NAME_LEN
];
214 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
217 /* Add non-standard Vid/Pid to the linux driver */
218 if ((presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
)) != FT_OK
)
220 LOG_ERROR("couldn't add PRESTO VID/PID");
225 if ((presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)) != FT_OK
)
227 LOG_ERROR("FT_ListDevices failed: %i", (int)presto
->status
);
228 return ERROR_JTAG_DEVICE_ERROR
;
231 LOG_DEBUG("FTDI devices available: %lu", numdevs
);
232 for (i
= 0; i
< numdevs
; i
++)
234 if ((presto
->status
= FT_Open(i
, &(presto
->handle
))) != FT_OK
)
236 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
237 LOG_DEBUG("FT_Open failed: %i", (int)presto
->status
);
240 LOG_DEBUG("FTDI device %i open", (int)i
);
242 if ((presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
, &vidpid
,
243 presto
->serial
, devname
, NULL
)) == FT_OK
)
245 if (vidpid
== PRESTO_VID_PID
246 && (req_serial
== NULL
|| !strcmp(presto
->serial
, req_serial
)))
250 LOG_DEBUG("FT_GetDeviceInfo failed: %lu", presto
->status
);
252 LOG_DEBUG("FTDI device %i does not match, closing", (int)i
);
253 FT_Close(presto
->handle
);
254 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
257 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
258 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
260 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1)) != FT_OK
)
261 return ERROR_JTAG_DEVICE_ERROR
;
264 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0)) != FT_OK
)
265 return ERROR_JTAG_DEVICE_ERROR
;
267 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
268 return ERROR_JTAG_DEVICE_ERROR
;
271 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
272 return ERROR_JTAG_DEVICE_ERROR
;
274 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
275 probably a bug in library threading */
277 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
278 return ERROR_JTAG_DEVICE_ERROR
;
282 LOG_DEBUG("PRESTO reset");
284 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
285 return ERROR_JTAG_DEVICE_ERROR
;
286 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x80, 1)) != FT_OK
)
287 return ERROR_JTAG_DEVICE_ERROR
;
288 if ((presto
->status
= FT_SetBaudRate(presto
->handle
, 9600)) != FT_OK
)
289 return ERROR_JTAG_DEVICE_ERROR
;
292 for (i
= 0; i
< 4 * 62; i
++)
293 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
294 return ERROR_JTAG_DEVICE_ERROR
;
298 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0)) != FT_OK
)
299 return ERROR_JTAG_DEVICE_ERROR
;
301 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
302 return ERROR_JTAG_DEVICE_ERROR
;
305 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
306 return ERROR_JTAG_DEVICE_ERROR
;
308 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
309 probably a bug in library threading */
311 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
312 return ERROR_JTAG_DEVICE_ERROR
;
316 LOG_DEBUG("PRESTO not responding");
317 return ERROR_JTAG_DEVICE_ERROR
;
321 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0)) != FT_OK
)
322 return ERROR_JTAG_DEVICE_ERROR
;
325 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
326 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
327 return ERROR_JTAG_DEVICE_ERROR
;
332 #elif BUILD_PRESTO_LIBFTDI == 1
333 static int presto_open_libftdi(char *req_serial
)
337 LOG_DEBUG("searching for PRESTO using libftdi");
339 /* initialize FTDI context structure */
340 if (ftdi_init(&presto
->ftdic
) < 0)
342 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
343 return ERROR_JTAG_DEVICE_ERROR
;
346 /* context, vendor id, product id */
347 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0)
349 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
350 return ERROR_JTAG_DEVICE_ERROR
;
353 if (ftdi_usb_reset(&presto
->ftdic
) < 0)
355 LOG_ERROR("unable to reset PRESTO device");
356 return ERROR_JTAG_DEVICE_ERROR
;
359 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0)
361 LOG_ERROR("unable to set latency timer");
362 return ERROR_JTAG_DEVICE_ERROR
;
365 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
367 LOG_ERROR("unable to purge PRESTO buffers");
368 return ERROR_JTAG_DEVICE_ERROR
;
372 if (presto_write(&presto_data
, 1) != ERROR_OK
)
374 LOG_ERROR("error writing to PRESTO");
375 return ERROR_JTAG_DEVICE_ERROR
;
378 if (presto_read(&presto_data
, 1) != ERROR_OK
)
380 LOG_DEBUG("no response from PRESTO, retrying");
382 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
383 return ERROR_JTAG_DEVICE_ERROR
;
386 if (presto_write(&presto_data
, 1) != ERROR_OK
)
387 return ERROR_JTAG_DEVICE_ERROR
;
389 if (presto_read(&presto_data
, 1) != ERROR_OK
)
391 LOG_ERROR("no response from PRESTO, giving up");
392 return ERROR_JTAG_DEVICE_ERROR
;
396 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
)
398 LOG_ERROR("error writing PRESTO init sequence");
399 return ERROR_JTAG_DEVICE_ERROR
;
404 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
406 static int presto_open(char *req_serial
)
408 presto
->buff_out_pos
= 0;
409 presto
->buff_in_pos
= 0;
410 presto
->buff_in_len
= 0;
411 presto
->buff_in_exp
= 0;
413 presto
->total_out
= 0;
414 presto
->total_in
= 0;
416 presto
->jtag_tms
= 0;
417 presto
->jtag_tck
= 0;
418 presto
->jtag_rst
= 0;
419 presto
->jtag_tdi_data
= 0;
420 presto
->jtag_tdi_count
= 0;
422 presto
->jtag_speed
= 0;
424 #if BUILD_PRESTO_FTD2XX == 1
425 return presto_open_ftd2xx(req_serial
);
426 #elif BUILD_PRESTO_LIBFTDI == 1
427 return presto_open_libftdi(req_serial
);
431 static int presto_close(void)
434 int result
= ERROR_OK
;
436 #if BUILD_PRESTO_FTD2XX == 1
437 unsigned long ftbytes
;
439 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
442 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
443 if (presto
->status
!= FT_OK
)
444 result
= ERROR_JTAG_DEVICE_ERROR
;
446 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
447 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
448 result
= ERROR_JTAG_DEVICE_ERROR
;
450 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16)) != FT_OK
)
451 result
= ERROR_JTAG_DEVICE_ERROR
;
453 if ((presto
->status
= FT_Close(presto
->handle
)) != FT_OK
)
454 result
= ERROR_JTAG_DEVICE_ERROR
;
456 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
458 #elif BUILD_PRESTO_LIBFTDI == 1
460 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, presto_init_seq
, sizeof(presto_init_seq
))) != sizeof(presto_init_seq
))
461 result
= ERROR_JTAG_DEVICE_ERROR
;
463 if ((presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16)) < 0)
464 result
= ERROR_JTAG_DEVICE_ERROR
;
466 if ((presto
->retval
= ftdi_usb_close(&presto
->ftdic
)) < 0)
467 result
= ERROR_JTAG_DEVICE_ERROR
;
469 ftdi_deinit(&presto
->ftdic
);
475 static int presto_flush(void)
477 if (presto
->buff_out_pos
== 0)
480 #if BUILD_PRESTO_FTD2XX == 1
481 if (presto
->status
!= FT_OK
)
482 #elif BUILD_PRESTO_LIBFTDI == 1
483 if (presto
->retval
< 0)
486 LOG_DEBUG("error in previous communication, canceling I/O operation");
487 return ERROR_JTAG_DEVICE_ERROR
;
490 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
)
492 presto
->buff_out_pos
= 0;
493 return ERROR_JTAG_DEVICE_ERROR
;
496 presto
->total_out
+= presto
->buff_out_pos
;
497 presto
->buff_out_pos
= 0;
499 if (presto
->buff_in_exp
== 0)
502 presto
->buff_in_pos
= 0;
503 presto
->buff_in_len
= 0;
505 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
)
507 presto
->buff_in_exp
= 0;
508 return ERROR_JTAG_DEVICE_ERROR
;
511 presto
->total_in
+= presto
->buff_in_exp
;
512 presto
->buff_in_len
= presto
->buff_in_exp
;
513 presto
->buff_in_exp
= 0;
518 static int presto_sendbyte(int data
)
520 if (data
== EOF
) return presto_flush();
522 if (presto
->buff_out_pos
< BUFFER_SIZE
)
524 presto
->buff_out
[presto
->buff_out_pos
++] = (uint8_t)data
;
525 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0)== 0xD0))
526 presto
->buff_in_exp
++;
529 return ERROR_JTAG_DEVICE_ERROR
;
531 #if BUILD_PRESTO_FTD2XX == 1
532 if (presto
->buff_out_pos
>= BUFFER_SIZE
)
533 #elif BUILD_PRESTO_LIBFTDI == 1
534 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128 bytes only!) */
535 if (presto
->buff_out_pos
>= BUFFER_SIZE
|| presto
->buff_in_exp
== 128)
537 return presto_flush();
543 static int presto_getbyte(void)
545 if (presto
->buff_in_pos
< presto
->buff_in_len
)
546 return presto
->buff_in
[presto
->buff_in_pos
++];
548 if (presto
->buff_in_exp
== 0)
551 if (presto_flush() != ERROR_OK
)
554 if (presto
->buff_in_pos
< presto
->buff_in_len
)
555 return presto
->buff_in
[presto
->buff_in_pos
++];
561 /* -------------------------------------------------------------------------- */
563 static int presto_tdi_flush(void)
565 if (presto
->jtag_tdi_count
== 0)
568 if (presto
->jtag_tck
== 0)
570 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
574 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
575 presto_sendbyte(presto
->jtag_tdi_data
);
576 presto
->jtag_tdi_count
= 0;
577 presto
->jtag_tdi_data
= 0;
582 static int presto_tck_idle(void)
584 if (presto
->jtag_tck
== 1)
586 presto_sendbyte(0xCA);
587 presto
->jtag_tck
= 0;
593 /* -------------------------------------------------------------------------- */
595 static int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
600 if (presto
->jtag_tck
== 0)
602 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
604 else if (presto
->jtag_speed
== 0 && !tdo_req
&& tms
== presto
->jtag_tms
)
606 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
608 if (++presto
->jtag_tdi_count
== 4)
616 cmd
= tdi
? 0xCB : 0xCA;
617 presto_sendbyte(cmd
);
619 if (tms
!= presto
->jtag_tms
)
621 presto_sendbyte((tms
? 0xEC : 0xE8) | (presto
->jtag_rst
? 0x02 : 0));
622 presto
->jtag_tms
= tms
;
625 /* delay with TCK low */
626 for (i
= presto
->jtag_speed
; i
> 1; i
--)
627 presto_sendbyte(cmd
);
630 presto_sendbyte(cmd
| (tdo_req
? 0x10 : 0));
632 /* delay with TCK high */
633 for (i
= presto
->jtag_speed
; i
> 1; i
--)
634 presto_sendbyte(cmd
);
636 presto
->jtag_tck
= 1;
641 static int presto_bitq_flush(void)
646 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
648 return presto_flush();
651 static int presto_bitq_in_rdy(void)
653 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
655 return presto
->buff_in_len
-presto
->buff_in_pos
;
658 static int presto_bitq_in(void)
660 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
662 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
666 static int presto_bitq_sleep(unsigned long us
)
680 waits
= us
/ 170 + 2;
682 presto_sendbyte(0x80);
687 static int presto_bitq_reset(int trst
, int srst
)
692 /* add a delay after possible TCK transition */
693 presto_sendbyte(0x80);
694 presto_sendbyte(0x80);
696 presto
->jtag_rst
= trst
|| srst
;
697 presto_sendbyte((presto
->jtag_rst
? 0xEA : 0xE8) | (presto
->jtag_tms
? 0x04 : 0));
702 /* -------------------------------------------------------------------------- */
704 static int presto_jtag_khz(int khz
, int *jtag_speed
)
709 return ERROR_INVALID_ARGUMENTS
;
712 if (khz
>= 3000) *jtag_speed
= 0;
713 else *jtag_speed
= (1000 + khz
-1)/khz
;
718 static int presto_jtag_speed_div(int speed
, int *khz
)
720 if ((speed
< 0) || (speed
> 1000))
723 return ERROR_INVALID_ARGUMENTS
;
726 if (speed
== 0) *khz
= 3000;
727 else *khz
= 1000/speed
;
732 static int presto_jtag_speed(int speed
)
736 if (presto_jtag_speed_div(speed
, &khz
))
738 return ERROR_INVALID_ARGUMENTS
;
741 presto
->jtag_speed
= speed
;
744 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed
, khz
/1000);
746 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed
, khz
);
751 static char *presto_serial
;
753 COMMAND_HANDLER(presto_handle_serial_command
)
759 presto_serial
= strdup(args
[0]);
763 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
769 static int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
)
771 register_command(cmd_ctx
, NULL
, "presto_serial", presto_handle_serial_command
,
772 COMMAND_CONFIG
, NULL
);
776 static int presto_jtag_init(void)
778 if (presto_open(presto_serial
) != ERROR_OK
)
781 if (presto_serial
!= NULL
)
782 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
784 LOG_ERROR("Cannot open PRESTO");
785 return ERROR_JTAG_INIT_FAILED
;
787 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
789 /* use JTAG speed setting from configuration file */
790 presto_jtag_speed(jtag_get_speed());
792 bitq_interface
= &presto_bitq
;
796 static int presto_jtag_quit(void)
800 LOG_INFO("PRESTO closed");
805 presto_serial
= NULL
;
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)