1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
20 /* Versaloon is a programming tool for multiple MCUs.
21 * It's distributed under GPLv3.
22 * You can find it at http://www.Versaloon.com/.
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include "usb_common.h"
33 #include "versaloon/versaloon_include.h"
34 #include "versaloon/versaloon.h"
36 static int vsllink_tms_offset
;
38 struct pending_scan_result
{
41 int length
; /* Number of bits to read */
42 struct scan_command
*command
; /* Corresponding scan command */
45 bool last
; /* indicate the last scan pending */
48 #define MAX_PENDING_SCAN_RESULTS 256
50 static int pending_scan_results_length
;
51 static struct pending_scan_result
52 pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
54 /* Queue command functions */
55 static void vsllink_end_state(tap_state_t state
);
56 static void vsllink_state_move(void);
57 static void vsllink_path_move(int num_states
, tap_state_t
*path
);
58 static void vsllink_tms(int num_bits
, const uint8_t *bits
);
59 static void vsllink_runtest(int num_cycles
);
60 static void vsllink_stableclocks(int num_cycles
, int tms
);
61 static void vsllink_scan(bool ir_scan
, enum scan_type type
,
62 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
63 static void vsllink_reset(int trst
, int srst
);
65 /* VSLLink tap buffer functions */
66 static void vsllink_tap_append_step(int tms
, int tdi
);
67 static void vsllink_tap_init(void);
68 static int vsllink_tap_execute(void);
69 static void vsllink_tap_ensure_pending(int scans
);
70 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
71 struct scan_command
*command
);
73 /* VSLLink lowlevel functions */
75 struct usb_dev_handle
*usb_handle
;
78 static struct vsllink
*vsllink_usb_open(void);
79 static void vsllink_usb_close(struct vsllink
*vsllink
);
81 #if defined _DEBUG_JTAG_IO_
82 static void vsllink_debug_buffer(uint8_t *buffer
, int length
);
85 static int tap_length
;
86 static int tap_buffer_size
;
87 static uint8_t *tms_buffer
;
88 static uint8_t *tdi_buffer
;
89 static uint8_t *tdo_buffer
;
91 struct vsllink
*vsllink_handle
;
93 static int vsllink_execute_queue(void)
95 struct jtag_command
*cmd
= jtag_command_queue
;
100 DEBUG_JTAG_IO("-------------------------------------"
102 "-------------------------------------");
104 while (cmd
!= NULL
) {
107 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
108 cmd
->cmd
.runtest
->num_cycles
,
109 tap_state_name(cmd
->cmd
.runtest
112 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
113 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
117 DEBUG_JTAG_IO("statemove end in %s",
118 tap_state_name(cmd
->cmd
.statemove
121 vsllink_end_state(cmd
->cmd
.statemove
123 vsllink_state_move();
127 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
128 cmd
->cmd
.pathmove
->num_states
,
129 tap_state_name(cmd
->cmd
.pathmove
130 ->path
[cmd
->cmd
.pathmove
134 cmd
->cmd
.pathmove
->num_states
,
135 cmd
->cmd
.pathmove
->path
);
139 DEBUG_JTAG_IO("JTAG Scan...");
141 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
143 scan_size
= jtag_build_buffer(
144 cmd
->cmd
.scan
, &buffer
);
146 if (cmd
->cmd
.scan
->ir_scan
)
148 "JTAG Scan write IR(%d bits), "
151 tap_state_name(cmd
->cmd
.scan
156 "JTAG Scan write DR(%d bits), "
159 tap_state_name(cmd
->cmd
.scan
162 #ifdef _DEBUG_JTAG_IO_
163 vsllink_debug_buffer(buffer
,
164 DIV_ROUND_UP(scan_size
, 8));
167 type
= jtag_scan_type(cmd
->cmd
.scan
);
169 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
170 type
, buffer
, scan_size
,
175 DEBUG_JTAG_IO("reset trst: %i srst %i",
176 cmd
->cmd
.reset
->trst
,
177 cmd
->cmd
.reset
->srst
);
179 vsllink_tap_execute();
181 if (cmd
->cmd
.reset
->trst
== 1)
182 tap_set_state(TAP_RESET
);
184 vsllink_reset(cmd
->cmd
.reset
->trst
,
185 cmd
->cmd
.reset
->srst
);
189 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
190 vsllink_tap_execute();
191 jtag_sleep(cmd
->cmd
.sleep
->us
);
194 case JTAG_STABLECLOCKS
:
195 DEBUG_JTAG_IO("add %d clocks",
196 cmd
->cmd
.stableclocks
->num_cycles
);
198 switch (tap_get_state()) {
200 /* tms must be '1' to stay
210 /* else, tms should be '0' */
213 /* above stable states are OK */
215 LOG_ERROR("jtag_add_clocks() "
216 "in non-stable state \"%s\"",
217 tap_state_name(tap_get_state())
221 vsllink_stableclocks(cmd
->cmd
.stableclocks
222 ->num_cycles
, scan_size
);
226 DEBUG_JTAG_IO("add %d jtag tms",
227 cmd
->cmd
.tms
->num_bits
);
229 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
233 LOG_ERROR("BUG: unknown JTAG command type "
234 "encountered: %d", cmd
->type
);
240 return vsllink_tap_execute();
243 static int vsllink_speed(int speed
)
245 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
246 return versaloon_interface
.adaptors
.peripheral_commit();
249 static int vsllink_khz(int khz
, int *jtag_speed
)
256 static int vsllink_speed_div(int jtag_speed
, int *khz
)
263 static void vsllink_free_buffer(void)
265 if (tdi_buffer
!= NULL
)
270 if (tdo_buffer
!= NULL
)
275 if (tms_buffer
!= NULL
)
282 static int vsllink_quit(void)
284 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
285 0, 0, GPIO_SRST
| GPIO_TRST
);
286 versaloon_interface
.adaptors
.gpio
.fini(0);
287 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
288 versaloon_interface
.adaptors
.peripheral_commit();
289 versaloon_interface
.fini();
291 vsllink_free_buffer();
292 vsllink_usb_close(vsllink_handle
);
297 static int vsllink_init(void)
299 vsllink_handle
= vsllink_usb_open();
300 if (vsllink_handle
== 0) {
301 LOG_ERROR("Can't find USB JTAG Interface!"\
302 "Please check connection and permissions.");
303 return ERROR_JTAG_INIT_FAILED
;
305 LOG_DEBUG("vsllink found on %04X:%04X",
306 versaloon_interface
.usb_setting
.vid
,
307 versaloon_interface
.usb_setting
.pid
);
308 versaloon_usb_device_handle
= vsllink_handle
->usb_handle
;
310 if (ERROR_OK
!= versaloon_interface
.init())
314 if (versaloon_interface
.usb_setting
.buf_size
< 32)
316 versaloon_interface
.fini();
320 // malloc buffer size for tap
321 tap_buffer_size
= versaloon_interface
.usb_setting
.buf_size
- 32;
322 vsllink_free_buffer();
323 tdi_buffer
= (uint8_t *)malloc(tap_buffer_size
);
324 tdo_buffer
= (uint8_t *)malloc(tap_buffer_size
);
325 tms_buffer
= (uint8_t *)malloc(tap_buffer_size
);
326 if ((NULL
== tdi_buffer
) || (NULL
== tdo_buffer
) || (NULL
== tms_buffer
))
332 versaloon_interface
.adaptors
.jtag_raw
.init(0);
333 versaloon_interface
.adaptors
.jtag_raw
.config(0, jtag_get_speed_khz());
334 versaloon_interface
.adaptors
.gpio
.init(0);
335 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
336 GPIO_TRST
, GPIO_SRST
, GPIO_SRST
);
337 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
347 /***************************************************************************/
348 /* Queue command implementations */
350 static void vsllink_end_state(tap_state_t state
)
352 if (tap_is_state_stable(state
))
353 tap_set_end_state(state
);
355 LOG_ERROR("BUG: %i is not a valid end state", state
);
360 /* Goes to the end state. */
361 static void vsllink_state_move(void)
364 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
365 tap_get_end_state());
366 uint8_t tms_scan_bits
= tap_get_tms_path_len(tap_get_state(),
367 tap_get_end_state());
369 for (i
= 0; i
< tms_scan_bits
; i
++)
370 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
372 tap_set_state(tap_get_end_state());
375 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
377 for (int i
= 0; i
< num_states
; i
++) {
378 if (path
[i
] == tap_state_transition(tap_get_state(), false))
379 vsllink_tap_append_step(0, 0);
380 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
381 vsllink_tap_append_step(1, 0);
383 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
384 tap_state_name(tap_get_state()),
385 tap_state_name(path
[i
]));
389 tap_set_state(path
[i
]);
392 tap_set_end_state(tap_get_state());
395 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
397 for (int i
= 0; i
< num_bits
; i
++) {
398 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
402 static void vsllink_stableclocks(int num_cycles
, int tms
)
404 while (num_cycles
> 0) {
405 vsllink_tap_append_step(tms
, 0);
410 static void vsllink_runtest(int num_cycles
)
412 tap_state_t saved_end_state
= tap_get_end_state();
414 if (tap_get_state() != TAP_IDLE
) {
415 /* enter IDLE state */
416 vsllink_end_state(TAP_IDLE
);
417 vsllink_state_move();
420 vsllink_stableclocks(num_cycles
, 0);
424 vsllink_end_state(saved_end_state
);
425 if (tap_get_end_state() != tap_get_end_state())
426 vsllink_state_move();
429 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
430 int scan_size
, struct scan_command
*command
)
432 tap_state_t saved_end_state
;
434 saved_end_state
= tap_get_end_state();
436 /* Move to appropriate scan state */
437 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
439 if (tap_get_state() != tap_get_end_state())
440 vsllink_state_move();
441 vsllink_end_state(saved_end_state
);
444 vsllink_tap_append_scan(scan_size
, buffer
, command
);
446 /* Goto Pause and record position to insert tms:0 */
447 vsllink_tap_append_step(0, 0);
448 vsllink_tms_offset
= tap_length
;
450 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
452 if (tap_get_state() != tap_get_end_state())
453 vsllink_state_move();
456 static void vsllink_reset(int trst
, int srst
)
458 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
461 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
463 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
466 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
468 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
469 versaloon_interface
.adaptors
.peripheral_commit();
472 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
475 return ERROR_COMMAND_SYNTAX_ERROR
;
478 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
479 versaloon_interface
.usb_setting
.vid
);
483 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
486 return ERROR_COMMAND_SYNTAX_ERROR
;
488 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
489 versaloon_interface
.usb_setting
.pid
);
493 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
496 return ERROR_COMMAND_SYNTAX_ERROR
;
499 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
500 versaloon_interface
.usb_setting
.ep_in
);
502 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
507 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
510 return ERROR_COMMAND_SYNTAX_ERROR
;
513 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
514 versaloon_interface
.usb_setting
.ep_out
);
516 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
521 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
524 return ERROR_COMMAND_SYNTAX_ERROR
;
527 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
528 versaloon_interface
.usb_setting
.interface
);
532 /***************************************************************************/
533 /* VSLLink tap functions */
535 static void vsllink_tap_init(void)
538 pending_scan_results_length
= 0;
539 vsllink_tms_offset
= 0;
542 static void vsllink_tap_ensure_pending(int scans
)
544 int available_scans
=
545 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
547 if (scans
> available_scans
)
548 vsllink_tap_execute();
551 static void vsllink_tap_append_step(int tms
, int tdi
)
553 int index_var
= tap_length
/ 8;
555 int bit_index
= tap_length
% 8;
556 uint8_t bit
= 1 << bit_index
;
559 tms_buffer
[index_var
] |= bit
;
561 tms_buffer
[index_var
] &= ~bit
;
564 tdi_buffer
[index_var
] |= bit
;
566 tdi_buffer
[index_var
] &= ~bit
;
570 if (tap_buffer_size
* 8 <= tap_length
)
571 vsllink_tap_execute();
574 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
575 struct scan_command
*command
)
577 struct pending_scan_result
*pending_scan_result
;
578 int len_tmp
, len_all
, i
;
581 while (len_all
< length
) {
582 vsllink_tap_ensure_pending(1);
583 pending_scan_result
=
584 &pending_scan_results_buffer
[
585 pending_scan_results_length
];
587 if ((length
- len_all
) > (tap_buffer_size
* 8 - tap_length
)) {
588 /* Use all memory available
589 vsllink_tap_append_step will commit automatically */
590 len_tmp
= tap_buffer_size
* 8 - tap_length
;
591 pending_scan_result
->last
= false;
593 len_tmp
= length
- len_all
;
594 pending_scan_result
->last
= true;
596 pending_scan_result
->src_offset
= tap_length
;
597 pending_scan_result
->dest_offset
= len_all
;
598 pending_scan_result
->length
= len_tmp
;
599 pending_scan_result
->command
= command
;
600 pending_scan_result
->buffer
= buffer
;
601 pending_scan_results_length
++;
603 for (i
= 0; i
< len_tmp
; i
++) {
604 vsllink_tap_append_step(((len_all
+ i
) < length
-1
606 (buffer
[(len_all
+ i
)/8]
607 >> ((len_all
+ i
)%8)) & 1);
614 static int vsllink_jtag_execute(void)
622 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
623 tdo_buffer
, tap_length
);
625 result
= versaloon_interface
.adaptors
.peripheral_commit();
627 if (result
== ERROR_OK
) {
628 for (i
= 0; i
< pending_scan_results_length
; i
++) {
629 struct pending_scan_result
*pending_scan_result
=
630 &pending_scan_results_buffer
[i
];
631 uint8_t *buffer
= pending_scan_result
->buffer
;
632 int length
= pending_scan_result
->length
;
633 int src_first
= pending_scan_result
->src_offset
;
634 int dest_first
= pending_scan_result
->dest_offset
;
635 bool last
= pending_scan_result
->last
;
637 struct scan_command
*command
;
639 command
= pending_scan_result
->command
;
640 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
642 #ifdef _DEBUG_JTAG_IO_
644 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
645 length
, src_first
, dest_first
);
646 vsllink_debug_buffer(buffer
+ dest_first
/ 8,
647 DIV_ROUND_UP(length
, 7));
651 if (jtag_read_buffer(buffer
, command
)
654 return ERROR_JTAG_QUEUE_FAILED
;
657 if (pending_scan_result
->buffer
!= NULL
)
658 free(pending_scan_result
->buffer
);
662 LOG_ERROR("vsllink_jtag_execute failure");
663 return ERROR_JTAG_QUEUE_FAILED
;
671 static int vsllink_tap_execute(void)
673 return vsllink_jtag_execute();
676 /*****************************************************************************/
677 /* VSLLink USB low-level functions */
679 static uint8_t usb_check_string(usb_dev_handle
*usb
, uint8_t stringidx
,
680 char * string
, char * buff
, uint16_t buf_size
)
689 buff
= (char*)malloc(buf_size
);
693 goto free_and_return
;
699 len
= usb_get_string_simple(usb
, stringidx
, (char *)buff
, buf_size
);
700 if ((len
< 0) || (len
!= ((int)strlen((const char *)buff
))))
703 goto free_and_return
;
707 if ((string
!= NULL
) && strcmp((const char *)buff
, string
))
710 goto free_and_return
;
714 if (alloced
&& (buff
!= NULL
))
722 static usb_dev_handle
* find_usb_device(uint16_t VID
, uint16_t PID
,
723 uint8_t interface
, int8_t serialindex
, char *serialstring
,
724 int8_t productindex
, char *productstring
)
726 usb_dev_handle
*dev_handle
= NULL
;
727 struct usb_bus
*busses
;
729 struct usb_device
*dev
;
734 busses
= usb_get_busses();
736 for (bus
= busses
; bus
; bus
= bus
->next
)
738 for (dev
= bus
->devices
; dev
; dev
= dev
->next
)
740 if ((dev
->descriptor
.idVendor
== VID
)
741 && (dev
->descriptor
.idProduct
== PID
))
743 dev_handle
= usb_open(dev
);
744 if (NULL
== dev_handle
)
746 LOG_ERROR("failed to open %04X:%04X, %s", VID
, PID
,
751 // check description string
752 if (((productstring
!= NULL
) && (productindex
>= 0)
753 && !usb_check_string(dev_handle
, productindex
,
754 productstring
, NULL
, 0))
755 || ((serialstring
!= NULL
) && (serialindex
>= 0)
756 && !usb_check_string(dev_handle
, serialindex
,
757 serialstring
, NULL
, 0)))
759 usb_close(dev_handle
);
764 if (usb_claim_interface(dev_handle
, interface
) != 0)
766 LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE
,
767 "claim interface", usb_strerror());
768 usb_close(dev_handle
);
773 if (dev_handle
!= NULL
)
784 static struct vsllink
*vsllink_usb_open(void)
788 struct usb_dev_handle
*dev
;
790 dev
= find_usb_device(versaloon_interface
.usb_setting
.vid
,
791 versaloon_interface
.usb_setting
.pid
,
792 versaloon_interface
.usb_setting
.interface
,
793 0, NULL
, 2, "Versaloon");
797 struct vsllink
*result
= malloc(sizeof(struct vsllink
));
798 result
->usb_handle
= dev
;
802 static void vsllink_usb_close(struct vsllink
*vsllink
)
806 ret
= usb_release_interface(vsllink
->usb_handle
,
807 versaloon_interface
.usb_setting
.interface
);
809 LOG_ERROR("fail to release interface %d, %d returned",
810 versaloon_interface
.usb_setting
.interface
, ret
);
814 ret
= usb_close(vsllink
->usb_handle
);
816 LOG_ERROR("fail to close usb, %d returned", ret
);
823 #define BYTES_PER_LINE 16
825 #if defined _DEBUG_JTAG_IO_
826 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
833 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
834 snprintf(line
, 5, "%04x", i
);
835 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
836 snprintf(s
, 4, " %02x", buffer
[j
]);
839 LOG_DEBUG("%s", line
);
842 #endif /* _DEBUG_JTAG_IO_ */
844 static const struct command_registration vsllink_command_handlers
[] = {
846 .name
= "vsllink_usb_vid",
847 .handler
= &vsllink_handle_usb_vid_command
,
848 .mode
= COMMAND_CONFIG
,
851 .name
= "vsllink_usb_pid",
852 .handler
= &vsllink_handle_usb_pid_command
,
853 .mode
= COMMAND_CONFIG
,
856 .name
= "vsllink_usb_bulkin",
857 .handler
= &vsllink_handle_usb_bulkin_command
,
858 .mode
= COMMAND_CONFIG
,
861 .name
= "vsllink_usb_bulkout",
862 .handler
= &vsllink_handle_usb_bulkout_command
,
863 .mode
= COMMAND_CONFIG
,
866 .name
= "vsllink_usb_interface",
867 .handler
= &vsllink_handle_usb_interface_command
,
868 .mode
= COMMAND_CONFIG
,
870 COMMAND_REGISTRATION_DONE
873 static const char *vsllink_transports
[] = {"jtag", "swd", NULL
};
875 struct jtag_interface vsllink_interface
= {
877 .supported
= DEBUG_CAP_TMS_SEQ
,
878 .commands
= vsllink_command_handlers
,
879 .transports
= vsllink_transports
,
881 .init
= vsllink_init
,
882 .quit
= vsllink_quit
,
884 .speed
= vsllink_speed
,
885 .speed_div
= vsllink_speed_div
,
886 .execute_queue
= vsllink_execute_queue
,
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)