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 ***************************************************************************/
22 * @file Holds driver for PRESTO programmer from ASIX.
23 * http://tools.asix.net/prg_presto.htm
33 #include <jtag/interface.h>
34 #include <helper/time_support.h>
38 /* PRESTO access library includes */
39 #if BUILD_PRESTO_FTD2XX == 1
41 #elif BUILD_PRESTO_LIBFTDI == 1
44 #error "BUG: either FTD2XX and LIBFTDI has to be used"
47 /* -------------------------------------------------------------------------- */
49 #define FT_DEVICE_NAME_LEN 64
50 #define FT_DEVICE_SERNUM_LEN 64
52 #define PRESTO_VID_PID 0x0403f1a0
53 #define PRESTO_VID (0x0403)
54 #define PRESTO_PID (0xf1a0)
56 #define BUFFER_SIZE (64*62)
59 #if BUILD_PRESTO_FTD2XX == 1
62 #elif BUILD_PRESTO_LIBFTDI == 1
63 struct ftdi_context ftdic
;
67 char serial
[FT_DEVICE_SERNUM_LEN
];
69 uint8_t buff_out
[BUFFER_SIZE
];
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 */
77 unsigned long total_out
;
78 unsigned long total_in
;
80 int jtag_tms
; /* last tms state */
81 int jtag_tck
; /* last tck state */
82 int jtag_rst
; /* last trst state */
90 static struct presto presto_state
;
91 static struct presto
*presto
= &presto_state
;
93 static uint8_t presto_init_seq
[] =
95 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
98 static int presto_write(uint8_t *buf
, uint32_t size
)
100 #if BUILD_PRESTO_FTD2XX == 1
102 if ((presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
104 LOG_ERROR("FT_Write returned: %lu", presto
->status
);
105 return ERROR_JTAG_DEVICE_ERROR
;
108 #elif BUILD_PRESTO_LIBFTDI == 1
110 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
)) < 0)
112 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
113 return ERROR_JTAG_DEVICE_ERROR
;
115 ftbytes
= presto
->retval
;
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
;
128 static int presto_read(uint8_t* buf
, uint32_t size
)
130 #if BUILD_PRESTO_FTD2XX == 1
132 if ((presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
134 LOG_ERROR("FT_Read returned: %lu", presto
->status
);
135 return ERROR_JTAG_DEVICE_ERROR
;
138 #elif BUILD_PRESTO_LIBFTDI == 1
139 uint32_t ftbytes
= 0;
141 struct timeval timeout
, now
;
142 gettimeofday(&timeout
, NULL
);
143 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
145 while (ftbytes
< size
)
147 if ((presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
)) < 0)
149 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
150 return ERROR_JTAG_DEVICE_ERROR
;
152 ftbytes
+= presto
->retval
;
154 gettimeofday(&now
, NULL
);
155 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
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
;
171 #if BUILD_PRESTO_FTD2XX == 1
172 static int presto_open_ftd2xx(char *req_serial
)
177 char devname
[FT_DEVICE_NAME_LEN
];
183 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
186 /* Add non-standard Vid/Pid to the linux driver */
187 if ((presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
)) != FT_OK
)
189 LOG_ERROR("couldn't add PRESTO VID/PID");
194 if ((presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)) != FT_OK
)
196 LOG_ERROR("FT_ListDevices failed: %i", (int)presto
->status
);
197 return ERROR_JTAG_DEVICE_ERROR
;
200 LOG_DEBUG("FTDI devices available: %lu", numdevs
);
201 for (i
= 0; i
< numdevs
; i
++)
203 if ((presto
->status
= FT_Open(i
, &(presto
->handle
))) != FT_OK
)
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
);
209 LOG_DEBUG("FTDI device %i open", (int)i
);
211 if ((presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
, &vidpid
,
212 presto
->serial
, devname
, NULL
)) == FT_OK
)
214 if (vidpid
== PRESTO_VID_PID
215 && (req_serial
== NULL
|| !strcmp(presto
->serial
, req_serial
)))
219 LOG_DEBUG("FT_GetDeviceInfo failed: %lu", presto
->status
);
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
;
226 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
227 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
229 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1)) != FT_OK
)
230 return ERROR_JTAG_DEVICE_ERROR
;
233 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0)) != FT_OK
)
234 return ERROR_JTAG_DEVICE_ERROR
;
236 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
237 return ERROR_JTAG_DEVICE_ERROR
;
240 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
241 return ERROR_JTAG_DEVICE_ERROR
;
243 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
244 probably a bug in library threading */
246 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
247 return ERROR_JTAG_DEVICE_ERROR
;
251 LOG_DEBUG("PRESTO reset");
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
;
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
;
267 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0)) != FT_OK
)
268 return ERROR_JTAG_DEVICE_ERROR
;
270 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
271 return ERROR_JTAG_DEVICE_ERROR
;
274 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
275 return ERROR_JTAG_DEVICE_ERROR
;
277 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
278 probably a bug in library threading */
280 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
281 return ERROR_JTAG_DEVICE_ERROR
;
285 LOG_DEBUG("PRESTO not responding");
286 return ERROR_JTAG_DEVICE_ERROR
;
290 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0)) != FT_OK
)
291 return ERROR_JTAG_DEVICE_ERROR
;
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
;
301 #elif BUILD_PRESTO_LIBFTDI == 1
302 static int presto_open_libftdi(char *req_serial
)
306 LOG_DEBUG("searching for PRESTO using libftdi");
308 /* initialize FTDI context structure */
309 if (ftdi_init(&presto
->ftdic
) < 0)
311 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
312 return ERROR_JTAG_DEVICE_ERROR
;
315 /* context, vendor id, product id */
316 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0)
318 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
319 return ERROR_JTAG_DEVICE_ERROR
;
322 if (ftdi_usb_reset(&presto
->ftdic
) < 0)
324 LOG_ERROR("unable to reset PRESTO device");
325 return ERROR_JTAG_DEVICE_ERROR
;
328 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0)
330 LOG_ERROR("unable to set latency timer");
331 return ERROR_JTAG_DEVICE_ERROR
;
334 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
336 LOG_ERROR("unable to purge PRESTO buffers");
337 return ERROR_JTAG_DEVICE_ERROR
;
341 if (presto_write(&presto_data
, 1) != ERROR_OK
)
343 LOG_ERROR("error writing to PRESTO");
344 return ERROR_JTAG_DEVICE_ERROR
;
347 if (presto_read(&presto_data
, 1) != ERROR_OK
)
349 LOG_DEBUG("no response from PRESTO, retrying");
351 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
352 return ERROR_JTAG_DEVICE_ERROR
;
355 if (presto_write(&presto_data
, 1) != ERROR_OK
)
356 return ERROR_JTAG_DEVICE_ERROR
;
358 if (presto_read(&presto_data
, 1) != ERROR_OK
)
360 LOG_ERROR("no response from PRESTO, giving up");
361 return ERROR_JTAG_DEVICE_ERROR
;
365 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
)
367 LOG_ERROR("error writing PRESTO init sequence");
368 return ERROR_JTAG_DEVICE_ERROR
;
373 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
375 static int presto_open(char *req_serial
)
377 presto
->buff_out_pos
= 0;
378 presto
->buff_in_pos
= 0;
379 presto
->buff_in_len
= 0;
380 presto
->buff_in_exp
= 0;
382 presto
->total_out
= 0;
383 presto
->total_in
= 0;
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;
391 presto
->jtag_speed
= 0;
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
);
400 static int presto_close(void)
403 int result
= ERROR_OK
;
405 #if BUILD_PRESTO_FTD2XX == 1
406 unsigned long ftbytes
;
408 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
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
;
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
;
419 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16)) != FT_OK
)
420 result
= ERROR_JTAG_DEVICE_ERROR
;
422 if ((presto
->status
= FT_Close(presto
->handle
)) != FT_OK
)
423 result
= ERROR_JTAG_DEVICE_ERROR
;
425 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
427 #elif BUILD_PRESTO_LIBFTDI == 1
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
;
432 if ((presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16)) < 0)
433 result
= ERROR_JTAG_DEVICE_ERROR
;
435 if ((presto
->retval
= ftdi_usb_close(&presto
->ftdic
)) < 0)
436 result
= ERROR_JTAG_DEVICE_ERROR
;
438 ftdi_deinit(&presto
->ftdic
);
444 static int presto_flush(void)
446 if (presto
->buff_out_pos
== 0)
449 #if BUILD_PRESTO_FTD2XX == 1
450 if (presto
->status
!= FT_OK
)
451 #elif BUILD_PRESTO_LIBFTDI == 1
452 if (presto
->retval
< 0)
455 LOG_DEBUG("error in previous communication, canceling I/O operation");
456 return ERROR_JTAG_DEVICE_ERROR
;
459 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
)
461 presto
->buff_out_pos
= 0;
462 return ERROR_JTAG_DEVICE_ERROR
;
465 presto
->total_out
+= presto
->buff_out_pos
;
466 presto
->buff_out_pos
= 0;
468 if (presto
->buff_in_exp
== 0)
471 presto
->buff_in_pos
= 0;
472 presto
->buff_in_len
= 0;
474 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
)
476 presto
->buff_in_exp
= 0;
477 return ERROR_JTAG_DEVICE_ERROR
;
480 presto
->total_in
+= presto
->buff_in_exp
;
481 presto
->buff_in_len
= presto
->buff_in_exp
;
482 presto
->buff_in_exp
= 0;
487 static int presto_sendbyte(int data
)
489 if (data
== EOF
) return presto_flush();
491 if (presto
->buff_out_pos
< BUFFER_SIZE
)
493 presto
->buff_out
[presto
->buff_out_pos
++] = (uint8_t)data
;
494 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0)== 0xD0))
495 presto
->buff_in_exp
++;
498 return ERROR_JTAG_DEVICE_ERROR
;
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)
506 return presto_flush();
512 static int presto_getbyte(void)
514 if (presto
->buff_in_pos
< presto
->buff_in_len
)
515 return presto
->buff_in
[presto
->buff_in_pos
++];
517 if (presto
->buff_in_exp
== 0)
520 if (presto_flush() != ERROR_OK
)
523 if (presto
->buff_in_pos
< presto
->buff_in_len
)
524 return presto
->buff_in
[presto
->buff_in_pos
++];
530 /* -------------------------------------------------------------------------- */
532 static int presto_tdi_flush(void)
534 if (presto
->jtag_tdi_count
== 0)
537 if (presto
->jtag_tck
== 0)
539 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
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;
551 static int presto_tck_idle(void)
553 if (presto
->jtag_tck
== 1)
555 presto_sendbyte(0xCA);
556 presto
->jtag_tck
= 0;
562 /* -------------------------------------------------------------------------- */
564 static int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
569 if (presto
->jtag_tck
== 0)
571 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
573 else if (presto
->jtag_speed
== 0 && !tdo_req
&& tms
== presto
->jtag_tms
)
575 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
577 if (++presto
->jtag_tdi_count
== 4)
585 cmd
= tdi
? 0xCB : 0xCA;
586 presto_sendbyte(cmd
);
588 if (tms
!= presto
->jtag_tms
)
590 presto_sendbyte((tms
? 0xEC : 0xE8) | (presto
->jtag_rst
? 0x02 : 0));
591 presto
->jtag_tms
= tms
;
594 /* delay with TCK low */
595 for (i
= presto
->jtag_speed
; i
> 1; i
--)
596 presto_sendbyte(cmd
);
599 presto_sendbyte(cmd
| (tdo_req
? 0x10 : 0));
601 /* delay with TCK high */
602 for (i
= presto
->jtag_speed
; i
> 1; i
--)
603 presto_sendbyte(cmd
);
605 presto
->jtag_tck
= 1;
610 static int presto_bitq_flush(void)
615 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
617 return presto_flush();
620 static int presto_bitq_in_rdy(void)
622 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
624 return presto
->buff_in_len
-presto
->buff_in_pos
;
627 static int presto_bitq_in(void)
629 if (presto
->buff_in_pos
>= presto
->buff_in_len
)
631 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
635 static int presto_bitq_sleep(unsigned long us
)
649 waits
= us
/ 170 + 2;
651 presto_sendbyte(0x80);
656 static int presto_bitq_reset(int trst
, int srst
)
661 /* add a delay after possible TCK transition */
662 presto_sendbyte(0x80);
663 presto_sendbyte(0x80);
665 presto
->jtag_rst
= trst
|| srst
;
666 presto_sendbyte((presto
->jtag_rst
? 0xEA : 0xE8) | (presto
->jtag_tms
? 0x04 : 0));
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
,
680 /* -------------------------------------------------------------------------- */
682 static int presto_jtag_khz(int khz
, int *jtag_speed
)
687 return ERROR_INVALID_ARGUMENTS
;
690 if (khz
>= 3000) *jtag_speed
= 0;
691 else *jtag_speed
= (1000 + khz
-1)/khz
;
696 static int presto_jtag_speed_div(int speed
, int *khz
)
698 if ((speed
< 0) || (speed
> 1000))
701 return ERROR_INVALID_ARGUMENTS
;
704 if (speed
== 0) *khz
= 3000;
705 else *khz
= 1000/speed
;
710 static int presto_jtag_speed(int speed
)
714 if (presto_jtag_speed_div(speed
, &khz
))
716 return ERROR_INVALID_ARGUMENTS
;
719 presto
->jtag_speed
= speed
;
722 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed
, khz
/1000);
724 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed
, khz
);
729 static char *presto_serial
;
731 COMMAND_HANDLER(presto_handle_serial_command
)
737 presto_serial
= strdup(CMD_ARGV
[0]);
741 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
747 static const struct command_registration presto_command_handlers
[] = {
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",
755 COMMAND_REGISTRATION_DONE
758 static int presto_jtag_init(void)
760 if (presto_open(presto_serial
) != ERROR_OK
)
763 if (presto_serial
!= NULL
)
764 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
766 LOG_ERROR("Cannot open PRESTO");
767 return ERROR_JTAG_INIT_FAILED
;
769 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
771 /* use JTAG speed setting from configuration file */
772 presto_jtag_speed(jtag_get_speed());
774 bitq_interface
= &presto_bitq
;
778 static int presto_jtag_quit(void)
782 LOG_INFO("PRESTO closed");
787 presto_serial
= NULL
;
793 struct jtag_interface presto_interface
= {
795 .commands
= presto_command_handlers
,
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
,
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)