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 "replacements.h"
30 /* project specific includes */
34 #include "configuration.h"
35 #include "time_support.h"
43 /* PRESTO access library includes */
44 #if BUILD_PRESTO_FTD2XX == 1
46 #elif BUILD_PRESTO_LIBFTDI == 1
49 #error "BUG: either FTD2XX and LIBFTDI has to be used"
52 int presto_jtag_speed(int speed
);
53 int presto_jtag_khz(int khz
, int *jtag_speed
);
54 int presto_jtag_speed_div(int speed
, int *khz
);
55 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
);
56 int presto_jtag_init(void);
57 int presto_jtag_quit(void);
59 jtag_interface_t presto_interface
=
62 .execute_queue
= bitq_execute_queue
,
63 .speed
= presto_jtag_speed
,
64 .khz
= presto_jtag_khz
,
65 .speed_div
= presto_jtag_speed_div
,
66 .register_commands
= presto_jtag_register_commands
,
67 .init
= presto_jtag_init
,
68 .quit
= presto_jtag_quit
,
71 int presto_bitq_out(int tms
, int tdi
, int tdo_req
);
72 int presto_bitq_flush(void);
73 int presto_bitq_sleep(unsigned long us
);
74 int presto_bitq_reset(int trst
, int srst
);
75 int presto_bitq_in_rdy(void);
76 int presto_bitq_in(void);
78 bitq_interface_t presto_bitq
=
80 .out
= presto_bitq_out
,
81 .flush
= presto_bitq_flush
,
82 .sleep
= presto_bitq_sleep
,
83 .reset
= presto_bitq_reset
,
84 .in_rdy
= presto_bitq_in_rdy
,
88 /* -------------------------------------------------------------------------- */
90 #define FT_DEVICE_NAME_LEN 64
91 #define FT_DEVICE_SERNUM_LEN 64
93 #define PRESTO_VID_PID 0x0403f1a0
94 #define PRESTO_VID (0x0403)
95 #define PRESTO_PID (0xf1a0)
97 #define BUFFER_SIZE (64*62)
99 typedef struct presto_s
101 #if BUILD_PRESTO_FTD2XX == 1
104 #elif BUILD_PRESTO_LIBFTDI == 1
105 struct ftdi_context ftdic
;
109 char serial
[FT_DEVICE_SERNUM_LEN
];
111 u8 buff_out
[BUFFER_SIZE
];
114 u8 buff_in
[BUFFER_SIZE
];
115 int buff_in_exp
; /* expected in buffer length */
116 int buff_in_len
; /* length of data received */
119 unsigned long total_out
;
120 unsigned long total_in
;
122 int jtag_tms
; /* last tms state */
123 int jtag_tck
; /* last tck state */
124 int jtag_rst
; /* last trst state */
133 presto_t presto_state
;
134 presto_t
*presto
= &presto_state
;
136 u8 presto_init_seq
[] =
138 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0
141 int presto_write(u8
*buf
, int size
)
143 #if BUILD_PRESTO_FTD2XX == 1
145 if ((presto
->status
= FT_Write(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
147 LOG_ERROR("FT_Write returned: %lu", presto
->status
);
148 return ERROR_JTAG_DEVICE_ERROR
;
151 #elif BUILD_PRESTO_LIBFTDI == 1
153 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, buf
, size
)) < 0)
155 LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto
->ftdic
));
156 return ERROR_JTAG_DEVICE_ERROR
;
158 ftbytes
= presto
->retval
;
163 LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%i < %i)", ftbytes
, size
);
164 return ERROR_JTAG_DEVICE_ERROR
;
170 int presto_read(u8
* buf
, int size
)
172 #if BUILD_PRESTO_FTD2XX == 1
174 if ((presto
->status
= FT_Read(presto
->handle
, buf
, size
, &ftbytes
)) != FT_OK
)
176 LOG_ERROR("FT_Read returned: %lu", presto
->status
);
177 return ERROR_JTAG_DEVICE_ERROR
;
180 #elif BUILD_PRESTO_LIBFTDI == 1
183 struct timeval timeout
, now
;
184 gettimeofday(&timeout
, NULL
);
185 timeval_add_time(&timeout
, 1, 0); /* one second timeout */
187 while (ftbytes
< size
)
189 if ((presto
->retval
= ftdi_read_data(&presto
->ftdic
, buf
+ ftbytes
, size
- ftbytes
)) < 0)
191 LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto
->ftdic
));
192 return ERROR_JTAG_DEVICE_ERROR
;
194 ftbytes
+= presto
->retval
;
196 gettimeofday(&now
, NULL
);
197 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
)))
204 /* this is just a warning, there might have been timeout when detecting PRESTO, which is not fatal */
205 LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%i < %i)", ftbytes
, size
);
206 return ERROR_JTAG_DEVICE_ERROR
;
212 #if BUILD_PRESTO_FTD2XX == 1
213 int presto_open_ftd2xx(char *req_serial
)
218 char devname
[FT_DEVICE_NAME_LEN
];
224 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
227 /* Add non-standard Vid/Pid to the linux driver */
228 if ((presto
->status
= FT_SetVIDPID(PRESTO_VID
, PRESTO_PID
)) != FT_OK
)
230 LOG_ERROR("couldn't add PRESTO VID/PID");
235 if ((presto
->status
= FT_ListDevices(&numdevs
, NULL
, FT_LIST_NUMBER_ONLY
)) != FT_OK
)
237 LOG_ERROR("FT_ListDevices failed: %i", (int)presto
->status
);
238 return ERROR_JTAG_DEVICE_ERROR
;
241 LOG_DEBUG("FTDI devices available: %i", numdevs
);
242 for (i
= 0; i
< numdevs
; i
++)
244 if ((presto
->status
= FT_Open(i
, &(presto
->handle
))) != FT_OK
)
246 /* this is not fatal, the device may be legitimately open by other process, hence debug message only */
247 LOG_DEBUG("FT_Open failed: %i", (int)presto
->status
);
250 LOG_DEBUG("FTDI device %i open", i
);
252 if ((presto
->status
= FT_GetDeviceInfo(presto
->handle
, &device
, &vidpid
,
253 presto
->serial
, devname
, NULL
)) == FT_OK
)
255 if (vidpid
== PRESTO_VID_PID
256 && (req_serial
== NULL
|| !strcmp(presto
->serial
, req_serial
)))
260 LOG_DEBUG("FT_GetDeviceInfo failed: %i", presto
->status
);
262 LOG_DEBUG("FTDI device %i does not match, closing", i
);
263 FT_Close(presto
->handle
);
264 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
267 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
268 return ERROR_JTAG_DEVICE_ERROR
; /* presto not open, return */
270 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 1)) != FT_OK
)
271 return ERROR_JTAG_DEVICE_ERROR
;
274 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 100, 0)) != FT_OK
)
275 return ERROR_JTAG_DEVICE_ERROR
;
277 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
278 return ERROR_JTAG_DEVICE_ERROR
;
281 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
282 return ERROR_JTAG_DEVICE_ERROR
;
284 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
285 probably a bug in library threading */
287 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
288 return ERROR_JTAG_DEVICE_ERROR
;
292 LOG_DEBUG("PRESTO reset");
294 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
295 return ERROR_JTAG_DEVICE_ERROR
;
296 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x80, 1)) != FT_OK
)
297 return ERROR_JTAG_DEVICE_ERROR
;
298 if ((presto
->status
= FT_SetBaudRate(presto
->handle
, 9600)) != FT_OK
)
299 return ERROR_JTAG_DEVICE_ERROR
;
302 for (i
= 0; i
< 4 * 62; i
++)
303 if ((presto
->status
=FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
304 return ERROR_JTAG_DEVICE_ERROR
;
308 if ((presto
->status
= FT_SetBitMode(presto
->handle
, 0x00, 0)) != FT_OK
)
309 return ERROR_JTAG_DEVICE_ERROR
;
311 if ((presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
)) != FT_OK
)
312 return ERROR_JTAG_DEVICE_ERROR
;
315 if ((presto
->status
= FT_Write(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
316 return ERROR_JTAG_DEVICE_ERROR
;
318 /* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
319 probably a bug in library threading */
321 if ((presto
->status
= FT_Read(presto
->handle
, &presto_data
, 1, &ftbytes
)) != FT_OK
)
322 return ERROR_JTAG_DEVICE_ERROR
;
326 LOG_DEBUG("PRESTO not responding");
327 return ERROR_JTAG_DEVICE_ERROR
;
331 if ((presto
->status
= FT_SetTimeouts(presto
->handle
, 0, 0)) != FT_OK
)
332 return ERROR_JTAG_DEVICE_ERROR
;
335 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
336 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
337 return ERROR_JTAG_DEVICE_ERROR
;
342 #elif BUILD_PRESTO_LIBFTDI == 1
343 int presto_open_libftdi(char *req_serial
)
347 LOG_DEBUG("searching for PRESTO using libftdi");
349 /* initialize FTDI context structure */
350 if (ftdi_init(&presto
->ftdic
) < 0)
352 LOG_ERROR("unable to init libftdi: %s", presto
->ftdic
.error_str
);
353 return ERROR_JTAG_DEVICE_ERROR
;
356 /* context, vendor id, product id */
357 if (ftdi_usb_open_desc(&presto
->ftdic
, PRESTO_VID
, PRESTO_PID
, NULL
, req_serial
) < 0)
359 LOG_ERROR("unable to open PRESTO: %s", presto
->ftdic
.error_str
);
360 return ERROR_JTAG_DEVICE_ERROR
;
363 if (ftdi_usb_reset(&presto
->ftdic
) < 0)
365 LOG_ERROR("unable to reset PRESTO device");
366 return ERROR_JTAG_DEVICE_ERROR
;
369 if (ftdi_set_latency_timer(&presto
->ftdic
, 1) < 0)
371 LOG_ERROR("unable to set latency timer");
372 return ERROR_JTAG_DEVICE_ERROR
;
375 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
377 LOG_ERROR("unable to purge PRESTO buffers");
378 return ERROR_JTAG_DEVICE_ERROR
;
382 if (presto_write(&presto_data
, 1) != ERROR_OK
)
384 LOG_ERROR("error writing to PRESTO");
385 return ERROR_JTAG_DEVICE_ERROR
;
388 if (presto_read(&presto_data
, 1) != ERROR_OK
)
390 LOG_DEBUG("no response from PRESTO, retrying");
392 if (ftdi_usb_purge_buffers(&presto
->ftdic
) < 0)
393 return ERROR_JTAG_DEVICE_ERROR
;
396 if (presto_write(&presto_data
, 1) != ERROR_OK
)
397 return ERROR_JTAG_DEVICE_ERROR
;
399 if (presto_read(&presto_data
, 1) != ERROR_OK
)
401 LOG_ERROR("no response from PRESTO, giving up");
402 return ERROR_JTAG_DEVICE_ERROR
;
406 if (presto_write(presto_init_seq
, sizeof(presto_init_seq
)) != ERROR_OK
)
408 LOG_ERROR("error writing PRESTO init sequence");
409 return ERROR_JTAG_DEVICE_ERROR
;
414 #endif /* BUILD_PRESTO_LIBFTDI == 1 */
416 int presto_open(char *req_serial
)
418 presto
->buff_out_pos
=0;
419 presto
->buff_in_pos
=0;
420 presto
->buff_in_len
=0;
421 presto
->buff_in_exp
=0;
429 presto
->jtag_tdi_data
=0;
430 presto
->jtag_tdi_count
=0;
432 presto
->jtag_speed
=0;
434 #if BUILD_PRESTO_FTD2XX == 1
435 return presto_open_ftd2xx(req_serial
);
436 #elif BUILD_PRESTO_LIBFTDI == 1
437 return presto_open_libftdi(req_serial
);
441 int presto_close(void)
444 int result
= ERROR_OK
;
446 #if BUILD_PRESTO_FTD2XX == 1
447 unsigned long ftbytes
;
449 if (presto
->handle
== (FT_HANDLE
)INVALID_HANDLE_VALUE
)
452 presto
->status
= FT_Purge(presto
->handle
, FT_PURGE_TX
| FT_PURGE_RX
);
453 if (presto
->status
!= FT_OK
)
454 result
= ERROR_JTAG_DEVICE_ERROR
;
456 presto
->status
= FT_Write(presto
->handle
, &presto_init_seq
, sizeof(presto_init_seq
), &ftbytes
);
457 if (presto
->status
!= FT_OK
|| ftbytes
!= sizeof(presto_init_seq
))
458 result
= ERROR_JTAG_DEVICE_ERROR
;
460 if ((presto
->status
= FT_SetLatencyTimer(presto
->handle
, 16)) != FT_OK
)
461 result
= ERROR_JTAG_DEVICE_ERROR
;
463 if ((presto
->status
= FT_Close(presto
->handle
)) != FT_OK
)
464 result
= ERROR_JTAG_DEVICE_ERROR
;
466 presto
->handle
= (FT_HANDLE
)INVALID_HANDLE_VALUE
;
468 #elif BUILD_PRESTO_LIBFTDI == 1
470 if ((presto
->retval
= ftdi_write_data(&presto
->ftdic
, presto_init_seq
, sizeof(presto_init_seq
))) != sizeof(presto_init_seq
))
471 result
= ERROR_JTAG_DEVICE_ERROR
;
473 if ((presto
->retval
= ftdi_set_latency_timer(&presto
->ftdic
, 16)) < 0)
474 result
= ERROR_JTAG_DEVICE_ERROR
;
476 if ((presto
->retval
= ftdi_usb_close(&presto
->ftdic
)) < 0)
477 result
= ERROR_JTAG_DEVICE_ERROR
;
479 ftdi_deinit(&presto
->ftdic
);
485 int presto_flush(void)
487 if (presto
->buff_out_pos
== 0)
490 #if BUILD_PRESTO_FTD2XX == 1
491 if (presto
->status
!= FT_OK
)
492 #elif BUILD_PRESTO_LIBFTDI == 1
493 if (presto
->retval
< 0)
496 LOG_DEBUG("error in previous communication, canceling I/O operation");
497 return ERROR_JTAG_DEVICE_ERROR
;
500 if (presto_write(presto
->buff_out
, presto
->buff_out_pos
) != ERROR_OK
)
502 presto
->buff_out_pos
= 0;
503 return ERROR_JTAG_DEVICE_ERROR
;
506 presto
->total_out
+= presto
->buff_out_pos
;
507 presto
->buff_out_pos
= 0;
509 if (presto
->buff_in_exp
== 0)
512 presto
->buff_in_pos
= 0;
513 presto
->buff_in_len
= 0;
515 if (presto_read(presto
->buff_in
, presto
->buff_in_exp
) != ERROR_OK
)
517 presto
->buff_in_exp
= 0;
518 return ERROR_JTAG_DEVICE_ERROR
;
521 presto
->total_in
+= presto
->buff_in_exp
;
522 presto
->buff_in_len
= presto
->buff_in_exp
;
523 presto
->buff_in_exp
= 0;
528 int presto_sendbyte(int data
)
530 if (data
== EOF
) return presto_flush();
532 if (presto
->buff_out_pos
< BUFFER_SIZE
)
534 presto
->buff_out
[presto
->buff_out_pos
++] = (u8
)data
;
535 if (((data
& 0xC0) == 0x40) || ((data
& 0xD0)== 0xD0))
536 presto
->buff_in_exp
++;
539 return ERROR_JTAG_DEVICE_ERROR
;
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)
547 return presto_flush();
552 int presto_getbyte(void)
554 if (presto
->buff_in_pos
< presto
->buff_in_len
)
555 return presto
->buff_in
[presto
->buff_in_pos
++];
557 if (presto
->buff_in_exp
== 0)
560 if (presto_flush() != ERROR_OK
)
563 if (presto
->buff_in_pos
<presto
->buff_in_len
)
564 return presto
->buff_in
[presto
->buff_in_pos
++];
569 /* -------------------------------------------------------------------------- */
571 int presto_tdi_flush(void)
573 if (presto
->jtag_tdi_count
== 0)
576 if (presto
->jtag_tck
== 0)
578 LOG_ERROR("BUG: unexpected TAP condition, TCK low");
582 presto
->jtag_tdi_data
|= (presto
->jtag_tdi_count
- 1) << 4;
583 presto_sendbyte(presto
->jtag_tdi_data
);
584 presto
->jtag_tdi_count
= 0;
585 presto
->jtag_tdi_data
= 0;
590 int presto_tck_idle(void)
592 if (presto
->jtag_tck
== 1)
594 presto_sendbyte(0xCA);
595 presto
->jtag_tck
= 0;
601 /* -------------------------------------------------------------------------- */
603 int presto_bitq_out(int tms
, int tdi
, int tdo_req
)
608 if (presto
->jtag_tck
== 0)
610 presto_sendbyte(0xA4); /* LED idicator - JTAG active */
612 else if (presto
->jtag_speed
== 0 && !tdo_req
&& tms
== presto
->jtag_tms
)
614 presto
->jtag_tdi_data
|= (tdi
!= 0) << presto
->jtag_tdi_count
;
616 if (++presto
->jtag_tdi_count
== 4)
624 cmd
= tdi
? 0xCB : 0xCA;
625 presto_sendbyte(cmd
);
627 if (tms
!= presto
->jtag_tms
)
629 presto_sendbyte((tms
? 0xEC : 0xE8) | (presto
->jtag_rst
? 0x02 : 0));
630 presto
->jtag_tms
= tms
;
633 /* delay with TCK low */
634 for (i
=presto
->jtag_speed
; i
>1; i
--)
635 presto_sendbyte(cmd
);
638 presto_sendbyte(cmd
| (tdo_req
? 0x10 : 0));
640 /* delay with TCK high */
641 for (i
=presto
->jtag_speed
; i
>1; i
--)
642 presto_sendbyte(cmd
);
644 presto
->jtag_tck
= 1;
649 int presto_bitq_flush(void)
654 presto_sendbyte(0xA0); /* LED idicator - JTAG idle */
656 return presto_flush();
659 int presto_bitq_in_rdy(void)
661 if (presto
->buff_in_pos
>=presto
->buff_in_len
)
663 return presto
->buff_in_len
-presto
->buff_in_pos
;
666 int presto_bitq_in(void)
668 if (presto
->buff_in_pos
>=presto
->buff_in_len
)
670 if (presto
->buff_in
[presto
->buff_in_pos
++]&0x08) return 1;
674 int presto_bitq_sleep(unsigned long us
)
688 waits
= us
/ 170 + 2;
690 presto_sendbyte(0x80);
695 int presto_bitq_reset(int trst
, int srst
)
700 /* add a delay after possible TCK transition */
701 presto_sendbyte(0x80);
702 presto_sendbyte(0x80);
704 presto
->jtag_rst
= trst
|| srst
;
705 presto_sendbyte((presto
->jtag_rst
? 0xEA : 0xE8) | (presto
->jtag_tms
? 0x04 : 0));
710 /* -------------------------------------------------------------------------- */
712 int presto_jtag_khz(int khz
, int *jtag_speed
)
717 return ERROR_INVALID_ARGUMENTS
;
720 if (khz
>= 3000) *jtag_speed
= 0;
721 else *jtag_speed
= (1000+khz
-1)/khz
;
726 int presto_jtag_speed_div(int speed
, int *khz
)
728 if ((speed
< 0) || (speed
> 1000))
731 return ERROR_INVALID_ARGUMENTS
;
734 if (speed
== 0) *khz
= 3000;
735 else *khz
= 1000/speed
;
740 int presto_jtag_speed(int speed
)
744 if (presto_jtag_speed_div(speed
, &khz
))
746 return ERROR_INVALID_ARGUMENTS
;
749 presto
->jtag_speed
= speed
;
752 LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed
, khz
/1000);
754 LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed
, khz
);
761 int presto_handle_serial_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
767 presto_serial
= strdup(args
[0]);
771 LOG_ERROR("expected exactly one argument to presto_serial <serial-number>");
777 int presto_jtag_register_commands(struct command_context_s
*cmd_ctx
)
779 register_command(cmd_ctx
, NULL
, "presto_serial", presto_handle_serial_command
,
780 COMMAND_CONFIG
, NULL
);
784 int presto_jtag_init(void)
786 if (presto_open(presto_serial
) != ERROR_OK
)
789 if (presto_serial
!= NULL
)
790 LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial
);
792 LOG_ERROR("Cannot open PRESTO");
793 return ERROR_JTAG_INIT_FAILED
;
795 LOG_INFO("PRESTO open, serial number '%s'", presto
->serial
);
797 /* use JTAG speed setting from configuration file */
798 presto_jtag_speed(jtag_speed
);
800 bitq_interface
= &presto_bitq
;
804 int presto_jtag_quit(void)
808 LOG_INFO("PRESTO closed");
813 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)