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 ***************************************************************************/
23 * Holds driver for PRESTO programmer from ASIX.
24 * http://tools.asix.net/prg_presto.htm
34 #include <jtag/interface.h>
35 #include <helper/time_support.h>
39 /* PRESTO access library includes */
40 #if BUILD_PRESTO_FTD2XX == 1
42 #include "ftd2xx_common.h"
43 #elif BUILD_PRESTO_LIBFTDI == 1
46 #error "BUG: either FTD2XX and LIBFTDI has to be used"
49 /* -------------------------------------------------------------------------- */
51 #define FT_DEVICE_NAME_LEN 64
52 #define FT_DEVICE_SERNUM_LEN 64
54 #define PRESTO_VID_PID 0x0403f1a0
55 #define PRESTO_VID (0x0403)
56 #define PRESTO_PID (0xf1a0)
58 #define BUFFER_SIZE (64*62)
61 #if BUILD_PRESTO_FTD2XX == 1
64 #elif BUILD_PRESTO_LIBFTDI == 1
65 struct ftdi_context ftdic
;
69 char serial
[FT_DEVICE_SERNUM_LEN
];
71 uint8_t buff_out
[BUFFER_SIZE
];
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 */
79 unsigned long total_out
;
80 unsigned long total_in
;
82 int jtag_tms
; /* last tms state */
83 int jtag_tck
; /* last tck state */
84 int jtag_rst
; /* last trst state */
92 static struct presto presto_state
;
93 static struct presto
*presto
= &presto_state
;
95 static uint8_t presto_init_seq
[] =
97 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
100 static int presto_write(uint8_t *buf
, uint32_t size
)
102 #if BUILD_PRESTO_FTD2XX == 1
104 if ((presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
106 LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto
->status
));
107 return ERROR_JTAG_DEVICE_ERROR
;
110 #elif BUILD_PRESTO_LIBFTDI == 1
112 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
)) < 0)
114 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
115 return ERROR_JTAG_DEVICE_ERROR
;
117 ftbytes
= presto
->retval
;
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
;
130 static int presto_read(uint8_t* buf
, uint32_t size
)
132 #if BUILD_PRESTO_FTD2XX == 1
134 if ((presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
136 LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto
->status
));
137 return ERROR_JTAG_DEVICE_ERROR
;
140 #elif BUILD_PRESTO_LIBFTDI == 1
141 uint32_t ftbytes
= 0;
143 struct timeval timeout
, now
;
144 gettimeofday(&timeout
, NULL
);
145 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
147 while (ftbytes
< size
)
149 if ((presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
)) < 0)
151 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
152 return ERROR_JTAG_DEVICE_ERROR
;
154 ftbytes
+= presto
->retval
;
156 gettimeofday(&now
, NULL
);
157 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
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
;
173 #if BUILD_PRESTO_FTD2XX == 1
174 static int presto_open_ftd2xx(char *req_serial
)
179 char devname
[FT_DEVICE_NAME_LEN
];
185 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
188 /* Add non-standard Vid/Pid to the linux driver */
189 if ((presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
)) != FT_OK
)
191 LOG_ERROR("couldn't add PRESTO VID/PID");
196 if ((presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)) != FT_OK
)
198 LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto
->status
));
199 return ERROR_JTAG_DEVICE_ERROR
;
202 LOG_DEBUG("FTDI devices available: %" PRIu32
, (uint32_t)numdevs
);
203 for (i
= 0; i
< numdevs
; i
++)
205 if ((presto
->status
= FT_Open(i
, &(presto
->handle
))) != FT_OK
)
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
));
211 LOG_DEBUG("FTDI device %i open", (int)i
);
213 if ((presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
, &vidpid
,
214 presto
->serial
, devname
, NULL
)) == FT_OK
)
216 if (vidpid
== PRESTO_VID_PID
217 && (req_serial
== NULL
|| !strcmp(presto
->serial
, req_serial
)))
221 LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(presto
->status
));
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
;
228 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
229 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
231 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1)) != FT_OK
)
232 return ERROR_JTAG_DEVICE_ERROR
;
235 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0)) != FT_OK
)
236 return ERROR_JTAG_DEVICE_ERROR
;
238 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
239 return ERROR_JTAG_DEVICE_ERROR
;
242 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
243 return ERROR_JTAG_DEVICE_ERROR
;
245 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
246 probably a bug in library threading */
248 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
249 return ERROR_JTAG_DEVICE_ERROR
;
253 LOG_DEBUG("PRESTO reset");
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
;
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
;
269 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0)) != FT_OK
)
270 return ERROR_JTAG_DEVICE_ERROR
;
272 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
273 return ERROR_JTAG_DEVICE_ERROR
;
276 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
277 return ERROR_JTAG_DEVICE_ERROR
;
279 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
280 probably a bug in library threading */
282 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
283 return ERROR_JTAG_DEVICE_ERROR
;
287 LOG_DEBUG("PRESTO not responding");
288 return ERROR_JTAG_DEVICE_ERROR
;
292 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0)) != FT_OK
)
293 return ERROR_JTAG_DEVICE_ERROR
;
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
;
303 #elif BUILD_PRESTO_LIBFTDI == 1
304 static int presto_open_libftdi(char *req_serial
)
308 LOG_DEBUG("searching for PRESTO using libftdi");
310 /* initialize FTDI context structure */
311 if (ftdi_init(&presto
->ftdic
) < 0)
313 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
314 return ERROR_JTAG_DEVICE_ERROR
;
317 /* context, vendor id, product id */
318 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0)
320 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
321 return ERROR_JTAG_DEVICE_ERROR
;
324 if (ftdi_usb_reset(&presto
->ftdic
) < 0)
326 LOG_ERROR("unable to reset PRESTO device");
327 return ERROR_JTAG_DEVICE_ERROR
;
330 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0)
332 LOG_ERROR("unable to set latency timer");
333 return ERROR_JTAG_DEVICE_ERROR
;
336 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
338 LOG_ERROR("unable to purge PRESTO buffers");
339 return ERROR_JTAG_DEVICE_ERROR
;
343 if (presto_write(&presto_data
, 1) != ERROR_OK
)
345 LOG_ERROR("error writing to PRESTO");
346 return ERROR_JTAG_DEVICE_ERROR
;
349 if (presto_read(&presto_data
, 1) != ERROR_OK
)
351 LOG_DEBUG("no response from PRESTO, retrying");
353 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
354 return ERROR_JTAG_DEVICE_ERROR
;
357 if (presto_write(&presto_data
, 1) != ERROR_OK
)
358 return ERROR_JTAG_DEVICE_ERROR
;
360 if (presto_read(&presto_data
, 1) != ERROR_OK
)
362 LOG_ERROR("no response from PRESTO, giving up");
363 return ERROR_JTAG_DEVICE_ERROR
;
367 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
)
369 LOG_ERROR("error writing PRESTO init sequence");
370 return ERROR_JTAG_DEVICE_ERROR
;
375 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
377 static int presto_open(char *req_serial
)
379 presto
->buff_out_pos
= 0;
380 presto
->buff_in_pos
= 0;
381 presto
->buff_in_len
= 0;
382 presto
->buff_in_exp
= 0;
384 presto
->total_out
= 0;
385 presto
->total_in
= 0;
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;
393 presto
->jtag_speed
= 0;
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
);
402 static int presto_close(void)
405 int result
= ERROR_OK
;
407 #if BUILD_PRESTO_FTD2XX == 1
410 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
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
;
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
;
421 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16)) != FT_OK
)
422 result
= ERROR_JTAG_DEVICE_ERROR
;
424 if ((presto
->status
= FT_Close(presto
->handle
)) != FT_OK
)
425 result
= ERROR_JTAG_DEVICE_ERROR
;
427 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
429 #elif BUILD_PRESTO_LIBFTDI == 1
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
;
434 if ((presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16)) < 0)
435 result
= ERROR_JTAG_DEVICE_ERROR
;
437 if ((presto
->retval
= ftdi_usb_close(&presto
->ftdic
)) < 0)
438 result
= ERROR_JTAG_DEVICE_ERROR
;
440 ftdi_deinit(&presto
->ftdic
);
446 static int presto_flush(void)
448 if (presto
->buff_out_pos
== 0)
451 #if BUILD_PRESTO_FTD2XX == 1
452 if (presto
->status
!= FT_OK
)
453 #elif BUILD_PRESTO_LIBFTDI == 1
454 if (presto
->retval
< 0)
457 LOG_DEBUG("error in previous communication, canceling I/O operation");
458 return ERROR_JTAG_DEVICE_ERROR
;
461 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
)
463 presto
->buff_out_pos
= 0;
464 return ERROR_JTAG_DEVICE_ERROR
;
467 presto
->total_out
+= presto
->buff_out_pos
;
468 presto
->buff_out_pos
= 0;
470 if (presto
->buff_in_exp
== 0)
473 presto
->buff_in_pos
= 0;
474 presto
->buff_in_len
= 0;
476 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
)
478 presto
->buff_in_exp
= 0;
479 return ERROR_JTAG_DEVICE_ERROR
;
482 presto
->total_in
+= presto
->buff_in_exp
;
483 presto
->buff_in_len
= presto
->buff_in_exp
;
484 presto
->buff_in_exp
= 0;
489 static int presto_sendbyte(int data
)
491 if (data
== EOF
) return presto_flush();
493 if (presto
->buff_out_pos
< BUFFER_SIZE
)
495 presto
->buff_out
[presto
->buff_out_pos
++] = (uint8_t)data
;
496 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0)== 0xD0))
497 presto
->buff_in_exp
++;
500 return ERROR_JTAG_DEVICE_ERROR
;
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)
508 return presto_flush();
514 static int presto_getbyte(void)
516 if (presto
->buff_in_pos
< presto
->buff_in_len
)
517 return presto
->buff_in
[presto
->buff_in_pos
++];
519 if (presto
->buff_in_exp
== 0)
522 if (presto_flush() != ERROR_OK
)
525 if (presto
->buff_in_pos
< presto
->buff_in_len
)
526 return presto
->buff_in
[presto
->buff_in_pos
++];
532 /* -------------------------------------------------------------------------- */
534 static int presto_tdi_flush(void)
536 if (presto
->jtag_tdi_count
== 0)
539 if (presto
->jtag_tck
== 0)
541 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
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;
553 static int presto_tck_idle(void)
555 if (presto
->jtag_tck
== 1)
557 presto_sendbyte(0xCA);
558 presto
->jtag_tck
= 0;
564 /* -------------------------------------------------------------------------- */
566 static int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
571 if (presto
->jtag_tck
== 0)
573 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
575 else if (presto
->jtag_speed
== 0 && !tdo_req
&& tms
== presto
->jtag_tms
)
577 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
579 if (++presto
->jtag_tdi_count
== 4)
587 cmd
= tdi
? 0xCB : 0xCA;
588 presto_sendbyte(cmd
);
590 if (tms
!= presto
->jtag_tms
)
592 presto_sendbyte((tms
? 0xEC : 0xE8) | (presto
->jtag_rst
? 0x02 : 0));
593 presto
->jtag_tms
= tms
;
596 /* delay with TCK low */
597 for (i
= presto
->jtag_speed
; i
> 1; i
--)
598 presto_sendbyte(cmd
);
601 presto_sendbyte(cmd
| (tdo_req
? 0x10 : 0));
603 /* delay with TCK high */
604 for (i
= presto
->jtag_speed
; i
> 1; i
--)
605 presto_sendbyte(cmd
);
607 presto
->jtag_tck
= 1;
612 static int presto_bitq_flush(void)
617 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
619 return presto_flush();
622 static int presto_bitq_in_rdy(void)
624 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
626 return presto
->buff_in_len
-presto
->buff_in_pos
;
629 static int presto_bitq_in(void)
631 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
633 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
637 static int presto_bitq_sleep(unsigned long us
)
651 waits
= us
/ 170 + 2;
653 presto_sendbyte(0x80);
658 static int presto_bitq_reset(int trst
, int srst
)
663 /* add a delay after possible TCK transition */
664 presto_sendbyte(0x80);
665 presto_sendbyte(0x80);
667 presto
->jtag_rst
= trst
|| srst
;
668 presto_sendbyte((presto
->jtag_rst
? 0xEA : 0xE8) | (presto
->jtag_tms
? 0x04 : 0));
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
,
682 /* -------------------------------------------------------------------------- */
684 static int presto_adapter_khz(int khz
, int *jtag_speed
)
689 return ERROR_INVALID_ARGUMENTS
;
692 if (khz
>= 3000) *jtag_speed
= 0;
693 else *jtag_speed
= (1000 + khz
-1)/khz
;
698 static int presto_jtag_speed_div(int speed
, int *khz
)
700 if ((speed
< 0) || (speed
> 1000))
703 return ERROR_INVALID_ARGUMENTS
;
706 if (speed
== 0) *khz
= 3000;
707 else *khz
= 1000/speed
;
712 static int presto_jtag_speed(int speed
)
716 if (presto_jtag_speed_div(speed
, &khz
))
718 return ERROR_INVALID_ARGUMENTS
;
721 presto
->jtag_speed
= speed
;
724 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed
, khz
/1000);
726 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed
, khz
);
731 static char *presto_serial
;
733 COMMAND_HANDLER(presto_handle_serial_command
)
739 presto_serial
= strdup(CMD_ARGV
[0]);
743 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
749 static const struct command_registration presto_command_handlers
[] = {
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",
757 COMMAND_REGISTRATION_DONE
760 static int presto_jtag_init(void)
762 if (presto_open(presto_serial
) != ERROR_OK
)
765 if (presto_serial
!= NULL
)
766 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
768 LOG_ERROR("Cannot open PRESTO");
769 return ERROR_JTAG_INIT_FAILED
;
771 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
773 bitq_interface
= &presto_bitq
;
777 static int presto_jtag_quit(void)
781 LOG_INFO("PRESTO closed");
786 presto_serial
= NULL
;
792 struct jtag_interface presto_interface
= {
794 .commands
= presto_command_handlers
,
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
,
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)