1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * Mathias Kuester <kesmtp@freenet.de> *
5 * This code is based on https://github.com/texane/stlink *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
27 /* project specific includes */
28 #include <helper/binarybuffer.h>
29 #include <jtag/interface.h>
30 #include <jtag/stlink/stlink_layout.h>
31 #include <jtag/stlink/stlink_transport.h>
32 #include <jtag/stlink/stlink_interface.h>
33 #include <target/target.h>
35 #include "libusb_common.h"
37 #define ENDPOINT_IN 0x80
38 #define ENDPOINT_OUT 0x00
40 #define STLINK_RX_EP (1|ENDPOINT_IN)
41 #define STLINK_TX_EP (2|ENDPOINT_OUT)
42 #define STLINK_CMD_SIZE (16)
43 #define STLINK_TX_SIZE (4*128)
44 #define STLINK_RX_SIZE (4*128)
47 struct stlink_usb_version
{
57 struct stlink_usb_handle_s
{
59 struct jtag_libusb_device_handle
*fd
;
61 struct libusb_transfer
*trans
;
63 uint8_t txbuf
[STLINK_TX_SIZE
];
65 uint8_t rxbuf
[STLINK_RX_SIZE
];
67 enum stlink_transports transport
;
69 struct stlink_usb_version version
;
76 #define STLINK_OK 0x80
77 #define STLINK_FALSE 0x81
78 #define STLINK_CORE_RUNNING 0x80
79 #define STLINK_CORE_HALTED 0x81
80 #define STLINK_CORE_STAT_UNKNOWN -1
82 #define STLINK_GET_VERSION 0xF1
83 #define STLINK_DEBUG_COMMAND 0xF2
84 #define STLINK_DFU_COMMAND 0xF3
85 #define STLINK_SWIM_COMMAND 0xF4
86 #define STLINK_GET_CURRENT_MODE 0xF5
88 #define STLINK_DEV_DFU_MODE 0x00
89 #define STLINK_DEV_MASS_MODE 0x01
90 #define STLINK_DEV_DEBUG_MODE 0x02
91 #define STLINK_DEV_SWIM_MODE 0x03
92 #define STLINK_DEV_UNKNOWN_MODE -1
94 #define STLINK_DFU_EXIT 0x07
96 #define STLINK_SWIM_ENTER 0x00
97 #define STLINK_SWIM_EXIT 0x01
99 #define STLINK_DEBUG_ENTER_JTAG 0x00
100 #define STLINK_DEBUG_GETSTATUS 0x01
101 #define STLINK_DEBUG_FORCEDEBUG 0x02
102 #define STLINK_DEBUG_RESETSYS 0x03
103 #define STLINK_DEBUG_READALLREGS 0x04
104 #define STLINK_DEBUG_READREG 0x05
105 #define STLINK_DEBUG_WRITEREG 0x06
106 #define STLINK_DEBUG_READMEM_32BIT 0x07
107 #define STLINK_DEBUG_WRITEMEM_32BIT 0x08
108 #define STLINK_DEBUG_RUNCORE 0x09
109 #define STLINK_DEBUG_STEPCORE 0x0a
110 #define STLINK_DEBUG_SETFP 0x0b
111 #define STLINK_DEBUG_READMEM_8BIT 0x0c
112 #define STLINK_DEBUG_WRITEMEM_8BIT 0x0d
113 #define STLINK_DEBUG_CLEARFP 0x0e
114 #define STLINK_DEBUG_WRITEDEBUGREG 0x0f
116 #define STLINK_DEBUG_ENTER_JTAG 0x00
117 #define STLINK_DEBUG_ENTER_SWD 0xa3
119 #define STLINK_DEBUG_ENTER 0x20
120 #define STLINK_DEBUG_EXIT 0x21
121 #define STLINK_DEBUG_READCOREID 0x22
125 STLINK_MODE_UNKNOWN
= 0,
128 STLINK_MODE_DEBUG_JTAG
,
129 STLINK_MODE_DEBUG_SWD
,
130 STLINK_MODE_DEBUG_SWIM
134 static int stlink_usb_recv(void *handle
, const uint8_t *txbuf
, int txsize
, uint8_t *rxbuf
,
137 struct stlink_usb_handle_s
*h
;
139 assert(handle
!= NULL
);
141 h
= (struct stlink_usb_handle_s
*)handle
;
143 if (jtag_libusb_bulk_write(h
->fd
, STLINK_TX_EP
, (char *)txbuf
, txsize
,
147 if (rxsize
&& rxbuf
) {
148 if (jtag_libusb_bulk_read(h
->fd
, STLINK_RX_EP
, (char *)rxbuf
,
149 rxsize
, 1000) != rxsize
) {
157 static void stlink_usb_init_buffer(void *handle
)
159 struct stlink_usb_handle_s
*h
;
161 assert(handle
!= NULL
);
163 h
= (struct stlink_usb_handle_s
*)handle
;
165 memset(h
->txbuf
, 0, STLINK_CMD_SIZE
);
169 static int stlink_usb_version(void *handle
)
173 struct stlink_usb_handle_s
*h
;
175 assert(handle
!= NULL
);
177 h
= (struct stlink_usb_handle_s
*)handle
;
179 stlink_usb_init_buffer(handle
);
181 h
->txbuf
[0] = STLINK_GET_VERSION
;
183 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 6);
188 v
= (h
->rxbuf
[0] << 8) | h
->rxbuf
[1];
190 h
->version
.stlink
= (v
>> 12) & 0x0f;
191 h
->version
.jtag
= (v
>> 6) & 0x3f;
192 h
->version
.swim
= v
& 0x3f;
193 h
->vid
= buf_get_u32(h
->rxbuf
, 16, 16);
194 h
->pid
= buf_get_u32(h
->rxbuf
, 32, 16);
196 LOG_DEBUG("STLINK v%d JTAG v%d SWIM v%d VID %04X PID %04X",
207 static int stlink_usb_current_mode(void *handle
, uint8_t *mode
)
210 struct stlink_usb_handle_s
*h
;
212 assert(handle
!= NULL
);
214 h
= (struct stlink_usb_handle_s
*)handle
;
216 stlink_usb_init_buffer(handle
);
218 h
->txbuf
[0] = STLINK_GET_CURRENT_MODE
;
220 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
231 static int stlink_usb_mode_enter(void *handle
, enum stlink_mode type
)
234 struct stlink_usb_handle_s
*h
;
236 assert(handle
!= NULL
);
238 h
= (struct stlink_usb_handle_s
*)handle
;
240 stlink_usb_init_buffer(handle
);
243 case STLINK_MODE_DEBUG_JTAG
:
244 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
245 h
->txbuf
[1] = STLINK_DEBUG_ENTER
;
246 h
->txbuf
[2] = STLINK_DEBUG_ENTER_JTAG
;
248 case STLINK_MODE_DEBUG_SWD
:
249 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
250 h
->txbuf
[1] = STLINK_DEBUG_ENTER
;
251 h
->txbuf
[2] = STLINK_DEBUG_ENTER_SWD
;
253 case STLINK_MODE_DEBUG_SWIM
:
254 h
->txbuf
[0] = STLINK_SWIM_COMMAND
;
255 h
->txbuf
[1] = STLINK_SWIM_ENTER
;
257 case STLINK_MODE_DFU
:
258 case STLINK_MODE_MASS
:
263 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
271 static int stlink_usb_mode_leave(void *handle
, enum stlink_mode type
)
274 struct stlink_usb_handle_s
*h
;
276 assert(handle
!= NULL
);
278 h
= (struct stlink_usb_handle_s
*)handle
;
280 stlink_usb_init_buffer(handle
);
283 case STLINK_MODE_DEBUG_JTAG
:
284 case STLINK_MODE_DEBUG_SWD
:
285 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
286 h
->txbuf
[1] = STLINK_DEBUG_EXIT
;
288 case STLINK_MODE_DEBUG_SWIM
:
289 h
->txbuf
[0] = STLINK_SWIM_COMMAND
;
290 h
->txbuf
[1] = STLINK_SWIM_EXIT
;
292 case STLINK_MODE_DFU
:
293 h
->txbuf
[0] = STLINK_DFU_COMMAND
;
294 h
->txbuf
[1] = STLINK_DFU_EXIT
;
296 case STLINK_MODE_MASS
:
301 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
309 static int stlink_usb_init_mode(void *handle
)
313 enum stlink_mode emode
;
314 struct stlink_usb_handle_s
*h
;
316 assert(handle
!= NULL
);
318 h
= (struct stlink_usb_handle_s
*)handle
;
320 res
= stlink_usb_current_mode(handle
, &mode
);
325 LOG_DEBUG("MODE: %02X", mode
);
327 /* try to exit current mode */
329 case STLINK_DEV_DFU_MODE
:
330 emode
= STLINK_MODE_DFU
;
332 case STLINK_DEV_DEBUG_MODE
:
333 emode
= STLINK_MODE_DEBUG_SWD
;
335 case STLINK_DEV_SWIM_MODE
:
336 emode
= STLINK_MODE_DEBUG_SWIM
;
339 emode
= STLINK_MODE_UNKNOWN
;
343 if (emode
!= STLINK_MODE_UNKNOWN
) {
344 res
= stlink_usb_mode_leave(handle
, emode
);
350 res
= stlink_usb_current_mode(handle
, &mode
);
355 LOG_DEBUG("MODE: %02X", mode
);
357 /* set selected mode */
358 switch (h
->transport
) {
359 case STLINK_TRANSPORT_SWD
:
360 emode
= STLINK_MODE_DEBUG_SWD
;
362 case STLINK_TRANSPORT_JTAG
:
363 emode
= STLINK_MODE_DEBUG_JTAG
;
365 case STLINK_TRANSPORT_SWIM
:
367 emode
= STLINK_MODE_UNKNOWN
;
371 if (emode
== STLINK_MODE_UNKNOWN
) {
372 LOG_ERROR("selected mode (transport) not supported");
376 res
= stlink_usb_mode_enter(handle
, emode
);
381 res
= stlink_usb_current_mode(handle
, &mode
);
386 LOG_DEBUG("MODE: %02X", mode
);
392 static int stlink_usb_idcode(void *handle
, uint32_t *idcode
)
395 struct stlink_usb_handle_s
*h
;
397 assert(handle
!= NULL
);
399 h
= (struct stlink_usb_handle_s
*)handle
;
401 stlink_usb_init_buffer(handle
);
403 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
404 h
->txbuf
[1] = STLINK_DEBUG_READCOREID
;
406 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 4);
411 *idcode
= le_to_h_u32(h
->rxbuf
);
413 LOG_DEBUG("IDCODE: %08X", *idcode
);
419 static enum target_state
stlink_usb_state(void *handle
)
422 struct stlink_usb_handle_s
*h
;
424 assert(handle
!= NULL
);
426 h
= (struct stlink_usb_handle_s
*)handle
;
428 stlink_usb_init_buffer(handle
);
430 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
431 h
->txbuf
[1] = STLINK_DEBUG_GETSTATUS
;
433 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
436 return TARGET_UNKNOWN
;
438 if (h
->rxbuf
[0] == STLINK_CORE_RUNNING
)
439 return TARGET_RUNNING
;
440 if (h
->rxbuf
[0] == STLINK_CORE_HALTED
)
441 return TARGET_HALTED
;
443 return TARGET_UNKNOWN
;
447 static int stlink_usb_reset(void *handle
)
450 struct stlink_usb_handle_s
*h
;
452 assert(handle
!= NULL
);
454 h
= (struct stlink_usb_handle_s
*)handle
;
456 stlink_usb_init_buffer(handle
);
458 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
459 h
->txbuf
[1] = STLINK_DEBUG_RESETSYS
;
461 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
466 LOG_DEBUG("RESET: %08X", h
->rxbuf
[0]);
472 static int stlink_usb_run(void *handle
)
475 struct stlink_usb_handle_s
*h
;
477 assert(handle
!= NULL
);
479 h
= (struct stlink_usb_handle_s
*)handle
;
481 stlink_usb_init_buffer(handle
);
483 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
484 h
->txbuf
[1] = STLINK_DEBUG_RUNCORE
;
486 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
495 static int stlink_usb_halt(void *handle
)
498 struct stlink_usb_handle_s
*h
;
500 assert(handle
!= NULL
);
502 h
= (struct stlink_usb_handle_s
*)handle
;
504 stlink_usb_init_buffer(handle
);
506 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
507 h
->txbuf
[1] = STLINK_DEBUG_FORCEDEBUG
;
509 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
518 static int stlink_usb_step(void *handle
)
521 struct stlink_usb_handle_s
*h
;
523 assert(handle
!= NULL
);
525 h
= (struct stlink_usb_handle_s
*)handle
;
527 stlink_usb_init_buffer(handle
);
529 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
530 h
->txbuf
[1] = STLINK_DEBUG_STEPCORE
;
532 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
541 static int stlink_usb_read_regs(void *handle
)
544 struct stlink_usb_handle_s
*h
;
546 assert(handle
!= NULL
);
548 h
= (struct stlink_usb_handle_s
*)handle
;
550 stlink_usb_init_buffer(handle
);
552 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
553 h
->txbuf
[1] = STLINK_DEBUG_READALLREGS
;
555 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 84);
564 static int stlink_usb_read_reg(void *handle
, int num
, uint32_t *val
)
567 struct stlink_usb_handle_s
*h
;
569 assert(handle
!= NULL
);
571 h
= (struct stlink_usb_handle_s
*)handle
;
573 stlink_usb_init_buffer(handle
);
575 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
576 h
->txbuf
[1] = STLINK_DEBUG_READREG
;
579 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 4);
584 *val
= le_to_h_u32(h
->rxbuf
);
590 static int stlink_usb_write_reg(void *handle
, int num
, uint32_t val
)
593 struct stlink_usb_handle_s
*h
;
595 assert(handle
!= NULL
);
597 h
= (struct stlink_usb_handle_s
*)handle
;
599 stlink_usb_init_buffer(handle
);
601 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
602 h
->txbuf
[1] = STLINK_DEBUG_WRITEREG
;
604 h_u32_to_le(h
->txbuf
+ 3, val
);
606 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
615 static int stlink_usb_read_mem8(void *handle
, uint32_t addr
, uint16_t len
,
619 uint16_t read_len
= len
;
620 struct stlink_usb_handle_s
*h
;
622 assert(handle
!= NULL
);
624 h
= (struct stlink_usb_handle_s
*)handle
;
626 stlink_usb_init_buffer(handle
);
628 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
629 h
->txbuf
[1] = STLINK_DEBUG_READMEM_8BIT
;
630 h_u32_to_le(h
->txbuf
+ 2, addr
);
631 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
633 /* we need to fix read length for single bytes */
637 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, read_len
);
642 memcpy(buffer
, h
->rxbuf
, len
);
648 static int stlink_usb_write_mem8(void *handle
, uint32_t addr
, uint16_t len
,
649 const uint8_t *buffer
)
652 struct stlink_usb_handle_s
*h
;
654 assert(handle
!= NULL
);
656 h
= (struct stlink_usb_handle_s
*)handle
;
658 stlink_usb_init_buffer(handle
);
660 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
661 h
->txbuf
[1] = STLINK_DEBUG_WRITEMEM_8BIT
;
662 h_u32_to_le(h
->txbuf
+ 2, addr
);
663 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
665 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
670 res
= stlink_usb_recv(handle
, (uint8_t *) buffer
, len
, 0, 0);
679 static int stlink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
683 struct stlink_usb_handle_s
*h
;
685 assert(handle
!= NULL
);
687 h
= (struct stlink_usb_handle_s
*)handle
;
689 stlink_usb_init_buffer(handle
);
693 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
694 h
->txbuf
[1] = STLINK_DEBUG_READMEM_32BIT
;
695 h_u32_to_le(h
->txbuf
+ 2, addr
);
696 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
698 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, len
);
703 memcpy(buffer
, h
->rxbuf
, len
);
709 static int stlink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
710 const uint32_t *buffer
)
713 struct stlink_usb_handle_s
*h
;
715 assert(handle
!= NULL
);
717 h
= (struct stlink_usb_handle_s
*)handle
;
719 stlink_usb_init_buffer(handle
);
723 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
724 h
->txbuf
[1] = STLINK_DEBUG_WRITEMEM_32BIT
;
725 h_u32_to_le(h
->txbuf
+ 2, addr
);
726 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
728 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
733 res
= stlink_usb_recv(handle
, (uint8_t *) buffer
, len
, 0, 0);
742 static int stlink_usb_open(struct stlink_interface_param_s
*param
, void **fd
)
745 struct stlink_usb_handle_s
*h
;
747 LOG_DEBUG("stlink_usb_open");
749 h
= malloc(sizeof(struct stlink_usb_handle_s
));
752 LOG_DEBUG("malloc failed");
756 h
->transport
= param
->transport
;
758 const uint16_t vids
[] = { param
->vid
, 0 };
759 const uint16_t pids
[] = { param
->pid
, 0 };
761 LOG_DEBUG("vid: %04x pid: %04x", param
->vid
,
764 if (jtag_libusb_open(vids
, pids
, &h
->fd
) != ERROR_OK
) {
765 LOG_ERROR("open failed");
769 jtag_libusb_set_configuration(h
->fd
, 0);
771 if (jtag_libusb_claim_interface(h
->fd
, 0) != ERROR_OK
) {
772 LOG_DEBUG("claim interface failed");
776 /* get the device version */
777 err
= stlink_usb_version(h
);
779 if (err
!= ERROR_OK
) {
780 LOG_ERROR("read version failed");
781 jtag_libusb_close(h
->fd
);
786 /* compare usb vid/pid */
787 if ((param
->vid
!= h
->vid
) || (param
->pid
!= h
->pid
))
788 LOG_INFO("vid/pid are not identical: %04X/%04X %04X/%04X",
789 param
->vid
, param
->pid
,
792 /* check if mode is supported */
795 switch (h
->transport
) {
796 case STLINK_TRANSPORT_SWD
:
797 case STLINK_TRANSPORT_JTAG
:
798 if (h
->version
.jtag
== 0)
801 case STLINK_TRANSPORT_SWIM
:
802 if (h
->version
.swim
== 0)
810 if (err
!= ERROR_OK
) {
811 LOG_ERROR("mode (transport) not supported by device");
812 jtag_libusb_close(h
->fd
);
817 err
= stlink_usb_init_mode(h
);
819 if (err
!= ERROR_OK
) {
820 LOG_ERROR("init mode failed");
821 jtag_libusb_close(h
->fd
);
832 static int stlink_usb_close(void *fd
)
838 struct stlink_layout_api_s stlink_usb_layout_api
= {
840 .open
= stlink_usb_open
,
842 .close
= stlink_usb_close
,
844 .idcode
= stlink_usb_idcode
,
846 .state
= stlink_usb_state
,
848 .reset
= stlink_usb_reset
,
850 .run
= stlink_usb_run
,
852 .halt
= stlink_usb_halt
,
854 .step
= stlink_usb_step
,
856 .read_regs
= stlink_usb_read_regs
,
858 .read_reg
= stlink_usb_read_reg
,
860 .write_reg
= stlink_usb_write_reg
,
862 .read_mem8
= stlink_usb_read_mem8
,
864 .write_mem8
= stlink_usb_write_mem8
,
866 .read_mem32
= stlink_usb_read_mem32
,
868 .write_mem32
= stlink_usb_write_mem32
,
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)