1 /***************************************************************************
2 * Copyright (C) 2010 by Michal Demin *
3 * based on usbprog.c and arm-jtag-ew.c *
4 * Several fixes by R. Diez in 2013. *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
24 #include <jtag/interface.h>
26 #include <jtag/commands.h>
30 #include <sys/ioctl.h>
33 /*#define DEBUG_SERIAL */
34 static int buspirate_execute_queue(void);
35 static int buspirate_init(void);
36 static int buspirate_quit(void);
38 static void buspirate_end_state(tap_state_t state
);
39 static void buspirate_state_move(void);
40 static void buspirate_path_move(int num_states
, tap_state_t
*path
);
41 static void buspirate_runtest(int num_cycles
);
42 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
43 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
44 static void buspirate_stableclocks(int num_cycles
);
46 #define CMD_UNKNOWN 0x00
47 #define CMD_PORT_MODE 0x01
48 #define CMD_FEATURE 0x02
49 #define CMD_READ_ADCS 0x03
50 /*#define CMD_TAP_SHIFT 0x04 // old protocol */
51 #define CMD_TAP_SHIFT 0x05
52 #define CMD_ENTER_RWIRE 0x05
53 #define CMD_ENTER_OOCD 0x06
54 #define CMD_UART_SPEED 0x07
55 #define CMD_JTAG_SPEED 0x08
56 #define CMD_RAW_PERIPH 0x40
57 #define CMD_RAW_SPEED 0x60
58 #define CMD_RAW_MODE 0x80
60 /* raw-wire mode configuration */
61 #define CMD_RAW_CONFIG_HIZ 0x00
62 #define CMD_RAW_CONFIG_3V3 0x08
63 #define CMD_RAW_CONFIG_2W 0x00
64 #define CMD_RAW_CONFIG_3W 0x04
65 #define CMD_RAW_CONFIG_MSB 0x00
66 #define CMD_RAW_CONFIG_LSB 0x02
68 /* Not all OSes have this speed defined */
69 #if !defined(B1000000)
70 #define B1000000 0010010
75 MODE_JTAG
= 1, /* push-pull outputs */
76 MODE_JTAG_OD
= 2, /* open-drain outputs */
98 SPEED_RAW_5_KHZ
= 0x0,
99 SPEED_RAW_50_KHZ
= 0x1,
100 SPEED_RAW_100_KHZ
= 0x2,
101 SPEED_RAW_400_KHZ
= 0x3
104 /* SWD mode specific */
105 static bool swd_mode
;
106 static int queued_retval
;
107 static char swd_features
;
109 static const cc_t SHORT_TIMEOUT
= 1; /* Must be at least 1. */
110 static const cc_t NORMAL_TIMEOUT
= 10;
112 static int buspirate_fd
= -1;
113 static int buspirate_pinmode
= MODE_JTAG_OD
;
114 static int buspirate_baudrate
= SERIAL_NORMAL
;
115 static int buspirate_vreg
;
116 static int buspirate_pullup
;
117 static char *buspirate_port
;
119 static enum tap_state last_tap_state
= TAP_RESET
;
122 static int buspirate_swd_init(void);
123 static void buspirate_swd_read_reg(uint8_t cmd
, uint32_t *value
, uint32_t ap_delay_clk
);
124 static void buspirate_swd_write_reg(uint8_t cmd
, uint32_t value
, uint32_t ap_delay_clk
);
125 static int buspirate_swd_switch_seq(enum swd_special_seq seq
);
126 static int buspirate_swd_run_queue(void);
129 static void buspirate_tap_init(void);
130 static int buspirate_tap_execute(void);
131 static void buspirate_tap_append(int tms
, int tdi
);
132 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
133 struct scan_command
*command
);
134 static void buspirate_tap_make_space(int scan
, int bits
);
136 static void buspirate_reset(int trst
, int srst
);
137 static void buspirate_set_feature(int, char, char);
138 static void buspirate_set_mode(int, char);
139 static void buspirate_set_speed(int, char);
141 /* low level interface */
142 static void buspirate_bbio_enable(int);
143 static void buspirate_jtag_reset(int);
144 static unsigned char buspirate_jtag_command(int, uint8_t *, int);
145 static void buspirate_jtag_set_speed(int, char);
146 static void buspirate_jtag_set_mode(int, char);
147 static void buspirate_jtag_set_feature(int, char, char);
148 static void buspirate_jtag_get_adcs(int);
150 /* low level two-wire interface */
151 static void buspirate_swd_set_speed(int, char);
152 static void buspirate_swd_set_feature(int, char, char);
153 static void buspirate_swd_set_mode(int, char);
155 /* low level HW communication interface */
156 static int buspirate_serial_open(char *port
);
157 static int buspirate_serial_setspeed(int fd
, char speed
, cc_t timeout
);
158 static int buspirate_serial_write(int fd
, uint8_t *buf
, int size
);
159 static int buspirate_serial_read(int fd
, uint8_t *buf
, int size
);
160 static void buspirate_serial_close(int fd
);
161 static void buspirate_print_buffer(uint8_t *buf
, int size
);
163 static int buspirate_execute_queue(void)
165 /* currently processed command */
166 struct jtag_command
*cmd
= jtag_command_queue
;
174 LOG_DEBUG_IO("runtest %i cycles, end in %s",
175 cmd
->cmd
.runtest
->num_cycles
,
176 tap_state_name(cmd
->cmd
.runtest
178 buspirate_end_state(cmd
->cmd
.runtest
180 buspirate_runtest(cmd
->cmd
.runtest
184 LOG_DEBUG_IO("statemove end in %s",
185 tap_state_name(cmd
->cmd
.statemove
187 buspirate_end_state(cmd
->cmd
.statemove
189 buspirate_state_move();
192 LOG_DEBUG_IO("pathmove: %i states, end in %s",
193 cmd
->cmd
.pathmove
->num_states
,
194 tap_state_name(cmd
->cmd
.pathmove
195 ->path
[cmd
->cmd
.pathmove
197 buspirate_path_move(cmd
->cmd
.pathmove
199 cmd
->cmd
.pathmove
->path
);
202 LOG_DEBUG_IO("scan end in %s",
203 tap_state_name(cmd
->cmd
.scan
206 buspirate_end_state(cmd
->cmd
.scan
209 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
,
211 type
= jtag_scan_type(cmd
->cmd
.scan
);
212 buspirate_scan(cmd
->cmd
.scan
->ir_scan
, type
,
213 buffer
, scan_size
, cmd
->cmd
.scan
);
217 LOG_DEBUG_IO("reset trst: %i srst %i",
218 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
220 /* flush buffers, so we can reset */
221 buspirate_tap_execute();
223 if (cmd
->cmd
.reset
->trst
== 1)
224 tap_set_state(TAP_RESET
);
225 buspirate_reset(cmd
->cmd
.reset
->trst
,
226 cmd
->cmd
.reset
->srst
);
229 LOG_DEBUG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
230 buspirate_tap_execute();
231 jtag_sleep(cmd
->cmd
.sleep
->us
);
233 case JTAG_STABLECLOCKS
:
234 LOG_DEBUG_IO("stable clock %i cycles", cmd
->cmd
.stableclocks
->num_cycles
);
235 buspirate_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
);
238 LOG_ERROR("BUG: unknown JTAG command type encountered");
245 return buspirate_tap_execute();
249 /* Returns true if successful, false if error. */
251 static bool read_and_discard_all_data(const int fd
)
253 /* LOG_INFO("Discarding any stale data from a previous connection..."); */
255 bool was_msg_already_printed
= false;
258 uint8_t buffer
[1024]; /* Any size will do, it's a trade-off between stack size and performance. */
260 const ssize_t read_count
= read(fd
, buffer
, sizeof(buffer
));
262 if (read_count
== 0) {
263 /* This is the "end of file" or "connection closed at the other end" condition. */
267 if (read_count
> 0) {
268 if (!was_msg_already_printed
) {
269 LOG_INFO("Some stale data from a previous connection was discarded.");
270 was_msg_already_printed
= true;
276 assert(read_count
== -1); /* According to the specification. */
278 const int errno_code
= errno
;
280 if (errno_code
== EINTR
)
283 if (errno_code
== EAGAIN
||
284 errno_code
== EWOULDBLOCK
) {
285 /* We know that the file descriptor has been opened with O_NONBLOCK or O_NDELAY,
286 and these codes mean that there is no data to read at present. */
290 /* Some other error has occurred. */
296 static int buspirate_init(void)
298 if (buspirate_port
== NULL
) {
299 LOG_ERROR("You need to specify the serial port!");
300 return ERROR_JTAG_INIT_FAILED
;
303 buspirate_fd
= buspirate_serial_open(buspirate_port
);
304 if (buspirate_fd
== -1) {
305 LOG_ERROR("Could not open serial port");
306 return ERROR_JTAG_INIT_FAILED
;
309 /* The Operating System or the device itself may deliver stale data from the last connection,
310 so discard all available bytes right after the new connection has been established.
311 After all, we are implementing here a master/slave protocol, so the slave should have nothing
312 to say until the master sends the first command.
314 In the past, there was a tcflush() call in buspirate_serial_setspeed(), but that
315 was not enough. I guess you must actively read from the serial port to trigger any
316 data collection from the device and/or lower USB layers. If you disable the serial port
317 read timeout (if you set SHORT_TIMEOUT to 0), then the discarding does not work any more.
319 Note that we are lowering the serial port timeout for this first read operation,
320 otherwise the normal initialisation would be delayed for too long. */
322 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, SHORT_TIMEOUT
)) {
323 LOG_ERROR("Error configuring the serial port.");
324 return ERROR_JTAG_INIT_FAILED
;
327 if (!read_and_discard_all_data(buspirate_fd
)) {
328 LOG_ERROR("Error while attempting to discard any stale data right after establishing the connection.");
329 return ERROR_JTAG_INIT_FAILED
;
332 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, NORMAL_TIMEOUT
)) {
333 LOG_ERROR("Error configuring the serial port.");
334 return ERROR_JTAG_INIT_FAILED
;
337 buspirate_bbio_enable(buspirate_fd
);
339 if (swd_mode
|| buspirate_baudrate
!= SERIAL_NORMAL
)
340 buspirate_set_speed(buspirate_fd
, SERIAL_FAST
);
342 LOG_INFO("Buspirate %s Interface ready!", swd_mode
? "SWD" : "JTAG");
345 buspirate_tap_init();
347 buspirate_set_mode(buspirate_fd
, buspirate_pinmode
);
348 buspirate_set_feature(buspirate_fd
, FEATURE_VREG
,
349 (buspirate_vreg
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
350 buspirate_set_feature(buspirate_fd
, FEATURE_PULLUP
,
351 (buspirate_pullup
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
352 buspirate_reset(0, 0);
357 static int buspirate_quit(void)
359 LOG_INFO("Shutting down buspirate.");
360 buspirate_set_mode(buspirate_fd
, MODE_HIZ
);
361 buspirate_set_speed(buspirate_fd
, SERIAL_NORMAL
);
363 buspirate_jtag_reset(buspirate_fd
);
365 buspirate_serial_close(buspirate_fd
);
367 if (buspirate_port
) {
368 free(buspirate_port
);
369 buspirate_port
= NULL
;
374 /* openocd command interface */
375 COMMAND_HANDLER(buspirate_handle_adc_command
)
377 if (buspirate_fd
== -1)
380 /* unavailable in SWD mode */
384 /* send the command */
385 buspirate_jtag_get_adcs(buspirate_fd
);
391 COMMAND_HANDLER(buspirate_handle_vreg_command
)
394 return ERROR_COMMAND_SYNTAX_ERROR
;
396 if (atoi(CMD_ARGV
[0]) == 1)
398 else if (atoi(CMD_ARGV
[0]) == 0)
401 LOG_ERROR("usage: buspirate_vreg <1|0>");
407 COMMAND_HANDLER(buspirate_handle_pullup_command
)
410 return ERROR_COMMAND_SYNTAX_ERROR
;
412 if (atoi(CMD_ARGV
[0]) == 1)
413 buspirate_pullup
= 1;
414 else if (atoi(CMD_ARGV
[0]) == 0)
415 buspirate_pullup
= 0;
417 LOG_ERROR("usage: buspirate_pullup <1|0>");
423 COMMAND_HANDLER(buspirate_handle_led_command
)
426 return ERROR_COMMAND_SYNTAX_ERROR
;
428 if (atoi(CMD_ARGV
[0]) == 1) {
430 buspirate_set_feature(buspirate_fd
, FEATURE_LED
,
432 } else if (atoi(CMD_ARGV
[0]) == 0) {
434 buspirate_set_feature(buspirate_fd
, FEATURE_LED
,
437 LOG_ERROR("usage: buspirate_led <1|0>");
444 COMMAND_HANDLER(buspirate_handle_mode_command
)
447 return ERROR_COMMAND_SYNTAX_ERROR
;
449 if (CMD_ARGV
[0][0] == 'n')
450 buspirate_pinmode
= MODE_JTAG
;
451 else if (CMD_ARGV
[0][0] == 'o')
452 buspirate_pinmode
= MODE_JTAG_OD
;
454 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
460 COMMAND_HANDLER(buspirate_handle_speed_command
)
463 return ERROR_COMMAND_SYNTAX_ERROR
;
465 if (CMD_ARGV
[0][0] == 'n')
466 buspirate_baudrate
= SERIAL_NORMAL
;
467 else if (CMD_ARGV
[0][0] == 'f')
468 buspirate_baudrate
= SERIAL_FAST
;
470 LOG_ERROR("usage: buspirate_speed <normal|fast>");
476 COMMAND_HANDLER(buspirate_handle_port_command
)
479 return ERROR_COMMAND_SYNTAX_ERROR
;
481 if (buspirate_port
== NULL
)
482 buspirate_port
= strdup(CMD_ARGV
[0]);
488 static const struct command_registration buspirate_command_handlers
[] = {
490 .name
= "buspirate_adc",
491 .handler
= &buspirate_handle_adc_command
,
492 .mode
= COMMAND_EXEC
,
493 .help
= "reads voltages on adc pins",
497 .name
= "buspirate_vreg",
499 .handler
= &buspirate_handle_vreg_command
,
500 .mode
= COMMAND_CONFIG
,
501 .help
= "changes the state of voltage regulators",
504 .name
= "buspirate_pullup",
506 .handler
= &buspirate_handle_pullup_command
,
507 .mode
= COMMAND_CONFIG
,
508 .help
= "changes the state of pullup",
511 .name
= "buspirate_led",
513 .handler
= &buspirate_handle_led_command
,
514 .mode
= COMMAND_EXEC
,
515 .help
= "changes the state of led",
518 .name
= "buspirate_speed",
519 .usage
= "<normal|fast>",
520 .handler
= &buspirate_handle_speed_command
,
521 .mode
= COMMAND_CONFIG
,
522 .help
= "speed of the interface",
525 .name
= "buspirate_mode",
526 .usage
= "<normal|open-drain>",
527 .handler
= &buspirate_handle_mode_command
,
528 .mode
= COMMAND_CONFIG
,
529 .help
= "pin mode of the interface",
532 .name
= "buspirate_port",
533 .usage
= "/dev/ttyUSB0",
534 .handler
= &buspirate_handle_port_command
,
535 .mode
= COMMAND_CONFIG
,
536 .help
= "name of the serial port to open",
538 COMMAND_REGISTRATION_DONE
541 static const struct swd_driver buspirate_swd
= {
542 .init
= buspirate_swd_init
,
543 .switch_seq
= buspirate_swd_switch_seq
,
544 .read_reg
= buspirate_swd_read_reg
,
545 .write_reg
= buspirate_swd_write_reg
,
546 .run
= buspirate_swd_run_queue
,
549 static const char * const buspirate_transports
[] = { "jtag", "swd", NULL
};
551 struct jtag_interface buspirate_interface
= {
553 .execute_queue
= buspirate_execute_queue
,
554 .commands
= buspirate_command_handlers
,
555 .transports
= buspirate_transports
,
556 .swd
= &buspirate_swd
,
557 .init
= buspirate_init
,
558 .quit
= buspirate_quit
561 /*************** jtag execute commands **********************/
562 static void buspirate_end_state(tap_state_t state
)
564 if (tap_is_state_stable(state
))
565 tap_set_end_state(state
);
567 LOG_ERROR("BUG: %i is not a valid end state", state
);
572 static void buspirate_state_move(void)
575 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
576 tap_get_end_state());
577 int tms_count
= tap_get_tms_path_len(tap_get_state(),
578 tap_get_end_state());
580 for (i
= 0; i
< tms_count
; i
++) {
581 tms
= (tms_scan
>> i
) & 1;
582 buspirate_tap_append(tms
, 0);
585 tap_set_state(tap_get_end_state());
588 static void buspirate_path_move(int num_states
, tap_state_t
*path
)
592 for (i
= 0; i
< num_states
; i
++) {
593 if (tap_state_transition(tap_get_state(), false) == path
[i
]) {
594 buspirate_tap_append(0, 0);
595 } else if (tap_state_transition(tap_get_state(), true)
597 buspirate_tap_append(1, 0);
599 LOG_ERROR("BUG: %s -> %s isn't a valid "
601 tap_state_name(tap_get_state()),
602 tap_state_name(path
[i
]));
606 tap_set_state(path
[i
]);
609 tap_set_end_state(tap_get_state());
612 static void buspirate_runtest(int num_cycles
)
616 tap_state_t saved_end_state
= tap_get_end_state();
618 /* only do a state_move when we're not already in IDLE */
619 if (tap_get_state() != TAP_IDLE
) {
620 buspirate_end_state(TAP_IDLE
);
621 buspirate_state_move();
624 for (i
= 0; i
< num_cycles
; i
++)
625 buspirate_tap_append(0, 0);
627 LOG_DEBUG_IO("runtest: cur_state %s end_state %s",
628 tap_state_name(tap_get_state()),
629 tap_state_name(tap_get_end_state()));
631 /* finish in end_state */
632 buspirate_end_state(saved_end_state
);
633 if (tap_get_state() != tap_get_end_state())
634 buspirate_state_move();
637 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
638 uint8_t *buffer
, int scan_size
, struct scan_command
*command
)
640 tap_state_t saved_end_state
;
642 buspirate_tap_make_space(1, scan_size
+8);
643 /* is 8 correct ? (2 moves = 16) */
645 saved_end_state
= tap_get_end_state();
647 buspirate_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
649 /* Only move if we're not already there */
650 if (tap_get_state() != tap_get_end_state())
651 buspirate_state_move();
653 buspirate_tap_append_scan(scan_size
, buffer
, command
);
656 buspirate_tap_append(0, 0);
658 /* restore the saved state */
659 buspirate_end_state(saved_end_state
);
660 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
662 if (tap_get_state() != tap_get_end_state())
663 buspirate_state_move();
666 static void buspirate_stableclocks(int num_cycles
)
669 int tms
= (tap_get_state() == TAP_RESET
? 1 : 0);
671 buspirate_tap_make_space(0, num_cycles
);
673 for (i
= 0; i
< num_cycles
; i
++)
674 buspirate_tap_append(tms
, 0);
677 /************************* TAP related stuff **********/
679 /* This buffer size matches the maximum CMD_TAP_SHIFT bit length in the Bus Pirate firmware,
680 look for constant 0x2000 in OpenOCD.c . */
681 #define BUSPIRATE_BUFFER_SIZE 1024
683 /* The old value of 32 scans was not enough to achieve near 100% utilisation ratio
684 for the current BUSPIRATE_BUFFER_SIZE value of 1024.
685 With 128 scans I am getting full USB 2.0 high speed packets (512 bytes long) when
686 using the JtagDue firmware on the Arduino Due instead of the Bus Pirate, which
687 amounts approximately to a 10% overall speed gain. Bigger packets should also
688 benefit the Bus Pirate, but the speed difference is much smaller.
689 Unfortunately, each 512-byte packet is followed by a 329-byte one, which is not ideal.
690 However, increasing BUSPIRATE_BUFFER_SIZE for the benefit of the JtagDue would
691 make it incompatible with the Bus Pirate firmware. */
692 #define BUSPIRATE_MAX_PENDING_SCANS 128
694 static uint8_t tms_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
695 static uint8_t tdi_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
696 static int tap_chain_index
;
698 struct pending_scan_result
/* this was stolen from arm-jtag-ew */
700 int first
; /* First bit position in tdo_buffer to read */
701 int length
; /* Number of bits to read */
702 struct scan_command
*command
; /* Corresponding scan command */
706 static struct pending_scan_result
707 tap_pending_scans
[BUSPIRATE_MAX_PENDING_SCANS
];
708 static int tap_pending_scans_num
;
710 static void buspirate_tap_init(void)
713 tap_pending_scans_num
= 0;
716 static int buspirate_tap_execute(void)
718 static const int CMD_TAP_SHIFT_HEADER_LEN
= 3;
727 if (tap_chain_index
<= 0)
730 LOG_DEBUG("executing tap num bits = %i scans = %i",
731 tap_chain_index
, tap_pending_scans_num
);
733 bytes_to_send
= DIV_ROUND_UP(tap_chain_index
, 8);
735 tmp
[0] = CMD_TAP_SHIFT
; /* this command expects number of bits */
736 tmp
[1] = tap_chain_index
>> 8; /* high */
737 tmp
[2] = tap_chain_index
; /* low */
739 fill_index
= CMD_TAP_SHIFT_HEADER_LEN
;
740 for (i
= 0; i
< bytes_to_send
; i
++) {
741 tmp
[fill_index
] = tdi_chain
[i
];
743 tmp
[fill_index
] = tms_chain
[i
];
747 /* jlink.c calls the routine below, which may be useful for debugging purposes.
748 For example, enabling this allows you to compare the log outputs from jlink.c
749 and from this module for JTAG development or troubleshooting purposes. */
751 last_tap_state
= jtag_debug_state_machine(tms_chain
, tdi_chain
,
752 tap_chain_index
, last_tap_state
);
755 ret
= buspirate_serial_write(buspirate_fd
, tmp
, CMD_TAP_SHIFT_HEADER_LEN
+ bytes_to_send
*2);
756 if (ret
!= bytes_to_send
*2+CMD_TAP_SHIFT_HEADER_LEN
) {
757 LOG_ERROR("error writing :(");
758 return ERROR_JTAG_DEVICE_ERROR
;
761 ret
= buspirate_serial_read(buspirate_fd
, tmp
, bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
);
762 if (ret
!= bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
) {
763 LOG_ERROR("error reading");
766 in_buf
= (uint8_t *)(&tmp
[CMD_TAP_SHIFT_HEADER_LEN
]);
768 /* parse the scans */
769 for (i
= 0; i
< tap_pending_scans_num
; i
++) {
770 uint8_t *buffer
= tap_pending_scans
[i
].buffer
;
771 int length
= tap_pending_scans
[i
].length
;
772 int first
= tap_pending_scans
[i
].first
;
773 struct scan_command
*command
= tap_pending_scans
[i
].command
;
775 /* copy bits from buffer */
776 buf_set_buf(in_buf
, first
, buffer
, 0, length
);
778 /* return buffer to higher level */
779 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
) {
780 buspirate_tap_init();
781 return ERROR_JTAG_QUEUE_FAILED
;
786 buspirate_tap_init();
790 static void buspirate_tap_make_space(int scans
, int bits
)
792 int have_scans
= BUSPIRATE_MAX_PENDING_SCANS
- tap_pending_scans_num
;
793 int have_bits
= BUSPIRATE_BUFFER_SIZE
* 8 - tap_chain_index
;
795 if ((have_scans
< scans
) || (have_bits
< bits
))
796 buspirate_tap_execute();
799 static void buspirate_tap_append(int tms
, int tdi
)
803 buspirate_tap_make_space(0, 1);
804 chain_index
= tap_chain_index
/ 8;
806 if (chain_index
< BUSPIRATE_BUFFER_SIZE
) {
807 int bit_index
= tap_chain_index
% 8;
808 uint8_t bit
= 1 << bit_index
;
810 if (0 == bit_index
) {
811 /* Let's say that the TAP shift operation wants to shift 9 bits,
812 so we will be sending to the Bus Pirate a bit count of 9 but still
813 full 16 bits (2 bytes) of shift data.
814 If we don't clear all bits at this point, the last 7 bits will contain
815 random data from the last buffer contents, which is not pleasant to the eye.
816 Besides, the Bus Pirate (or some clone) may want to assert in debug builds
817 that, after consuming all significant data bits, the rest of them are zero.
818 Therefore, for aesthetic and for assert purposes, we clear all bits below. */
819 tms_chain
[chain_index
] = 0;
820 tdi_chain
[chain_index
] = 0;
824 tms_chain
[chain_index
] |= bit
;
826 tms_chain
[chain_index
] &= ~bit
;
829 tdi_chain
[chain_index
] |= bit
;
831 tdi_chain
[chain_index
] &= ~bit
;
835 LOG_ERROR("tap_chain overflow, bad things will happen");
836 /* Exit abruptly, like jlink.c does. After a buffer overflow we don't want
837 to carry on, as data will be corrupt. Another option would be to return
838 some error code at this point. */
843 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
844 struct scan_command
*command
)
847 tap_pending_scans
[tap_pending_scans_num
].length
= length
;
848 tap_pending_scans
[tap_pending_scans_num
].buffer
= buffer
;
849 tap_pending_scans
[tap_pending_scans_num
].command
= command
;
850 tap_pending_scans
[tap_pending_scans_num
].first
= tap_chain_index
;
852 for (i
= 0; i
< length
; i
++) {
853 int tms
= (i
< length
-1 ? 0 : 1);
854 int tdi
= (buffer
[i
/8] >> (i
%8)) & 1;
855 buspirate_tap_append(tms
, tdi
);
857 tap_pending_scans_num
++;
860 /*************** wrapper functions *********************/
862 /* (1) assert or (0) deassert reset lines */
863 static void buspirate_reset(int trst
, int srst
)
865 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
868 buspirate_set_feature(buspirate_fd
, FEATURE_TRST
, ACTION_DISABLE
);
870 buspirate_set_feature(buspirate_fd
, FEATURE_TRST
, ACTION_ENABLE
);
873 buspirate_set_feature(buspirate_fd
, FEATURE_SRST
, ACTION_DISABLE
);
875 buspirate_set_feature(buspirate_fd
, FEATURE_SRST
, ACTION_ENABLE
);
878 static void buspirate_set_feature(int fd
, char feat
, char action
)
881 buspirate_swd_set_feature(fd
, feat
, action
);
883 buspirate_jtag_set_feature(fd
, feat
, action
);
886 static void buspirate_set_mode(int fd
, char mode
)
889 buspirate_swd_set_mode(fd
, mode
);
891 buspirate_jtag_set_mode(fd
, mode
);
894 static void buspirate_set_speed(int fd
, char speed
)
897 buspirate_swd_set_speed(fd
, speed
);
899 buspirate_jtag_set_speed(fd
, speed
);
903 /*************** swd lowlevel functions ********************/
905 static void buspirate_swd_set_speed(int fd
, char speed
)
910 LOG_DEBUG("Buspirate speed setting in SWD mode defaults to 400 kHz");
913 tmp
[0] = CMD_RAW_SPEED
| SPEED_RAW_400_KHZ
;
914 buspirate_serial_write(fd
, tmp
, 1);
915 ret
= buspirate_serial_read(fd
, tmp
, 1);
917 LOG_ERROR("Buspirate did not answer correctly");
921 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
926 static void buspirate_swd_set_mode(int fd
, char mode
)
931 /* raw-wire mode configuration */
932 if (mode
== MODE_HIZ
)
933 tmp
[0] = CMD_RAW_MODE
| CMD_RAW_CONFIG_LSB
;
935 tmp
[0] = CMD_RAW_MODE
| CMD_RAW_CONFIG_LSB
| CMD_RAW_CONFIG_3V3
;
937 buspirate_serial_write(fd
, tmp
, 1);
938 ret
= buspirate_serial_read(fd
, tmp
, 1);
940 LOG_ERROR("Buspirate did not answer correctly");
944 LOG_ERROR("Buspirate did not reply as expected to the configure command");
949 static void buspirate_swd_set_feature(int fd
, char feat
, char action
)
956 LOG_DEBUG("Buspirate TRST feature not available in SWD mode");
959 LOG_ERROR("Buspirate LED feature not available in SWD mode");
962 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x02 : swd_features
& 0x0D;
965 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x04 : swd_features
& 0x0B;
968 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x08 : swd_features
& 0x07;
971 LOG_DEBUG("Buspirate unknown feature %d", feat
);
975 tmp
[0] = CMD_RAW_PERIPH
| swd_features
;
976 buspirate_serial_write(fd
, tmp
, 1);
977 ret
= buspirate_serial_read(fd
, tmp
, 1);
979 LOG_DEBUG("Buspirate feature %d not supported in SWD mode", feat
);
980 } else if (tmp
[0] != 1) {
981 LOG_ERROR("Buspirate did not reply as expected to the configure command");
986 /*************** jtag lowlevel functions ********************/
987 static void buspirate_bbio_enable(int fd
)
991 const char *mode_answers
[2] = { "OCD1", "RAW1" };
992 const char *correct_ans
= NULL
;
993 uint8_t tmp
[21] = { [0 ... 20] = 0x00 };
998 command
= CMD_ENTER_RWIRE
;
999 correct_ans
= mode_answers
[1];
1001 command
= CMD_ENTER_OOCD
;
1002 correct_ans
= mode_answers
[0];
1005 LOG_DEBUG("Entering binary mode, that is %s", correct_ans
);
1006 buspirate_serial_write(fd
, tmp
, 20);
1009 /* reads 1 to n "BBIO1"s and one "OCD1" or "RAW1" */
1011 ret
= buspirate_serial_read(fd
, tmp
, 4);
1013 LOG_ERROR("Buspirate error. Is binary"
1014 "/OpenOCD support enabled?");
1017 if (strncmp((char *)tmp
, "BBIO", 4) == 0) {
1018 ret
= buspirate_serial_read(fd
, tmp
, 1);
1020 LOG_ERROR("Buspirate did not answer correctly! "
1021 "Do you have correct firmware?");
1024 if (tmp
[0] != '1') {
1025 LOG_ERROR("Unsupported binary protocol");
1028 if (cmd_sent
== 0) {
1031 ret
= buspirate_serial_write(fd
, tmp
, 1);
1033 LOG_ERROR("error reading");
1037 } else if (strncmp((char *)tmp
, correct_ans
, 4) == 0)
1040 LOG_ERROR("Buspirate did not answer correctly! "
1041 "Do you have correct firmware?");
1048 static void buspirate_jtag_reset(int fd
)
1052 tmp
[0] = 0x00; /* exit OCD1 mode */
1053 buspirate_serial_write(fd
, tmp
, 1);
1055 /* We ignore the return value here purposly, nothing we can do */
1056 buspirate_serial_read(fd
, tmp
, 5);
1057 if (strncmp((char *)tmp
, "BBIO1", 5) == 0) {
1058 tmp
[0] = 0x0F; /* reset BP */
1059 buspirate_serial_write(fd
, tmp
, 1);
1061 LOG_ERROR("Unable to restart buspirate!");
1064 static void buspirate_jtag_set_speed(int fd
, char speed
)
1073 tmp
[0] = CMD_UART_SPEED
;
1075 buspirate_jtag_command(fd
, tmp
, 2);
1077 /* here the adapter changes speed, we need follow */
1078 if (-1 == buspirate_serial_setspeed(fd
, speed
, NORMAL_TIMEOUT
)) {
1079 LOG_ERROR("Error configuring the serial port.");
1083 buspirate_serial_write(fd
, ack
, 2);
1084 ret
= buspirate_serial_read(fd
, tmp
, 2);
1086 LOG_ERROR("Buspirate did not ack speed change");
1089 if ((tmp
[0] != CMD_UART_SPEED
) || (tmp
[1] != speed
)) {
1090 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
1093 LOG_INFO("Buspirate switched to %s mode",
1094 (speed
== SERIAL_NORMAL
) ? "normal" : "FAST");
1098 static void buspirate_jtag_set_mode(int fd
, char mode
)
1101 tmp
[0] = CMD_PORT_MODE
;
1103 buspirate_jtag_command(fd
, tmp
, 2);
1106 static void buspirate_jtag_set_feature(int fd
, char feat
, char action
)
1109 tmp
[0] = CMD_FEATURE
;
1110 tmp
[1] = feat
; /* what */
1111 tmp
[2] = action
; /* action */
1112 buspirate_jtag_command(fd
, tmp
, 3);
1115 static void buspirate_jtag_get_adcs(int fd
)
1118 uint16_t a
, b
, c
, d
;
1119 tmp
[0] = CMD_READ_ADCS
;
1120 buspirate_jtag_command(fd
, tmp
, 1);
1121 a
= tmp
[2] << 8 | tmp
[3];
1122 b
= tmp
[4] << 8 | tmp
[5];
1123 c
= tmp
[6] << 8 | tmp
[7];
1124 d
= tmp
[8] << 8 | tmp
[9];
1126 LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f "
1128 ((float)a
)/155.1515, ((float)b
)/155.1515,
1129 ((float)c
)/155.1515, ((float)d
)/155.1515);
1132 static unsigned char buspirate_jtag_command(int fd
,
1133 uint8_t *cmd
, int cmdlen
)
1138 res
= buspirate_serial_write(fd
, cmd
, cmdlen
);
1140 if ((cmd
[0] == CMD_UART_SPEED
)
1141 || (cmd
[0] == CMD_PORT_MODE
)
1142 || (cmd
[0] == CMD_FEATURE
)
1143 || (cmd
[0] == CMD_JTAG_SPEED
))
1146 if (res
== cmdlen
) {
1149 len
= 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */
1155 LOG_INFO("Wrong !");
1157 res
= buspirate_serial_read(fd
, cmd
, len
);
1159 return (unsigned char)cmd
[1];
1167 /* low level serial port */
1168 /* TODO add support for WIN32 and others ! */
1169 static int buspirate_serial_open(char *port
)
1172 fd
= open(buspirate_port
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
1177 /* Returns -1 on error. */
1179 static int buspirate_serial_setspeed(int fd
, char speed
, cc_t timeout
)
1181 struct termios t_opt
;
1182 speed_t baud
= (speed
== SERIAL_FAST
) ? B1000000
: B115200
;
1184 /* set the serial port parameters */
1185 fcntl(fd
, F_SETFL
, 0);
1186 if (0 != tcgetattr(fd
, &t_opt
))
1189 if (0 != cfsetispeed(&t_opt
, baud
))
1192 if (0 != cfsetospeed(&t_opt
, baud
))
1195 t_opt
.c_cflag
|= (CLOCAL
| CREAD
);
1196 t_opt
.c_cflag
&= ~PARENB
;
1197 t_opt
.c_cflag
&= ~CSTOPB
;
1198 t_opt
.c_cflag
&= ~CSIZE
;
1199 t_opt
.c_cflag
|= CS8
;
1200 t_opt
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
);
1202 /* The serial port may have been configured for human interaction with
1203 the Bus Pirate console, but OpenOCD is going to use a binary protocol,
1204 so make sure to turn off any CR/LF translation and the like. */
1205 t_opt
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
| INLCR
| ICRNL
);
1207 t_opt
.c_oflag
&= ~OPOST
;
1208 t_opt
.c_cc
[VMIN
] = 0;
1209 t_opt
.c_cc
[VTIME
] = timeout
;
1211 /* Note that, in the past, TCSANOW was used below instead of TCSADRAIN,
1212 and CMD_UART_SPEED did not work properly then, at least with
1213 the Bus Pirate v3.5 (USB). */
1214 if (0 != tcsetattr(fd
, TCSADRAIN
, &t_opt
)) {
1215 /* According to the Linux documentation, this is actually not enough
1216 to detect errors, you need to call tcgetattr() and check that
1217 all changes have been performed successfully. */
1224 static int buspirate_serial_write(int fd
, uint8_t *buf
, int size
)
1228 ret
= write(fd
, buf
, size
);
1230 LOG_DEBUG("size = %d ret = %d", size
, ret
);
1231 buspirate_print_buffer(buf
, size
);
1234 LOG_ERROR("Error sending data");
1239 static int buspirate_serial_read(int fd
, uint8_t *buf
, int size
)
1245 while (len
< size
) {
1246 ret
= read(fd
, buf
+len
, size
-len
);
1262 LOG_DEBUG("should have read = %d actual size = %d", size
, len
);
1263 buspirate_print_buffer(buf
, len
);
1266 LOG_ERROR("Error reading data");
1271 static void buspirate_serial_close(int fd
)
1276 #define LINE_SIZE 81
1277 #define BYTES_PER_LINE 16
1278 static void buspirate_print_buffer(uint8_t *buf
, int size
)
1280 char line
[LINE_SIZE
];
1285 while (offset
< size
) {
1286 snprintf(tmp
, 5, "%02x ", (uint8_t)buf
[offset
]);
1291 if (offset
% BYTES_PER_LINE
== 0) {
1292 LOG_DEBUG("%s", line
);
1298 LOG_DEBUG("%s", line
);
1301 /************************* SWD related stuff **********/
1303 static int buspirate_swd_init(void)
1305 LOG_INFO("Buspirate SWD mode enabled");
1311 static int buspirate_swd_switch_seq(enum swd_special_seq seq
)
1313 const uint8_t *sequence
;
1319 LOG_DEBUG("SWD line reset");
1320 sequence
= swd_seq_line_reset
;
1321 sequence_len
= DIV_ROUND_UP(swd_seq_line_reset_len
, 8);
1324 LOG_DEBUG("JTAG-to-SWD");
1325 sequence
= swd_seq_jtag_to_swd
;
1326 sequence_len
= DIV_ROUND_UP(swd_seq_jtag_to_swd_len
, 8);
1329 LOG_DEBUG("SWD-to-JTAG");
1330 sequence
= swd_seq_swd_to_jtag
;
1331 sequence_len
= DIV_ROUND_UP(swd_seq_swd_to_jtag_len
, 8);
1334 LOG_ERROR("Sequence %d not supported", seq
);
1338 /* FIXME: all above sequences fit into one pirate command for now
1339 * but it may cause trouble later
1342 tmp
[0] = 0x10 + ((sequence_len
- 1) & 0x0F);
1343 memcpy(tmp
+ 1, sequence
, sequence_len
);
1345 buspirate_serial_write(buspirate_fd
, tmp
, sequence_len
+ 1);
1346 buspirate_serial_read(buspirate_fd
, tmp
, sequence_len
+ 1);
1351 static uint8_t buspirate_swd_write_header(uint8_t cmd
)
1356 tmp
[0] = 0x10; /* bus pirate: send 1 byte */
1357 tmp
[1] = cmd
; /* swd cmd */
1358 tmp
[2] = 0x07; /* ack __x */
1359 tmp
[3] = 0x07; /* ack _x_ */
1360 tmp
[4] = 0x07; /* ack x__ */
1361 tmp
[5] = 0x07; /* write mode trn_1 */
1362 tmp
[6] = 0x07; /* write mode trn_2 */
1364 to_send
= ((cmd
& SWD_CMD_RnW
) == 0) ? 7 : 5;
1365 buspirate_serial_write(buspirate_fd
, tmp
, to_send
);
1368 buspirate_serial_read(buspirate_fd
, tmp
, 2); /* drop pirate command ret vals */
1369 buspirate_serial_read(buspirate_fd
, tmp
, to_send
- 2); /* ack bits */
1371 return tmp
[2] << 2 | tmp
[1] << 1 | tmp
[0];
1374 static void buspirate_swd_idle_clocks(uint32_t no_bits
)
1379 no_bytes
= (no_bits
+ 7) / 8;
1380 memset(tmp
+ 1, 0x00, sizeof(tmp
) - 1);
1382 /* unfortunately bus pirate misbehaves when clocks are sent in parts
1383 * so we need to limit at 128 clock cycles
1389 uint8_t to_send
= no_bytes
> 16 ? 16 : no_bytes
;
1390 tmp
[0] = 0x10 + ((to_send
- 1) & 0x0F);
1392 buspirate_serial_write(buspirate_fd
, tmp
, to_send
+ 1);
1393 buspirate_serial_read(buspirate_fd
, tmp
, to_send
+ 1);
1395 no_bytes
-= to_send
;
1399 static void buspirate_swd_clear_sticky_errors(void)
1401 buspirate_swd_write_reg(swd_cmd(false, false, DP_ABORT
),
1402 STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
1405 static void buspirate_swd_read_reg(uint8_t cmd
, uint32_t *value
, uint32_t ap_delay_clk
)
1409 LOG_DEBUG("buspirate_swd_read_reg");
1410 assert(cmd
& SWD_CMD_RnW
);
1412 if (queued_retval
!= ERROR_OK
) {
1413 LOG_DEBUG("Skip buspirate_swd_read_reg because queued_retval=%d", queued_retval
);
1417 cmd
|= SWD_CMD_START
| SWD_CMD_PARK
;
1418 uint8_t ack
= buspirate_swd_write_header(cmd
);
1420 /* do a read transaction */
1421 tmp
[0] = 0x06; /* 4 data bytes */
1425 tmp
[4] = 0x07; /* parity bit */
1426 tmp
[5] = 0x21; /* 2 turnaround clocks */
1428 buspirate_serial_write(buspirate_fd
, tmp
, 6);
1429 buspirate_serial_read(buspirate_fd
, tmp
, 6);
1431 /* store the data and parity */
1432 uint32_t data
= (uint8_t) tmp
[0];
1433 data
|= (uint8_t) tmp
[1] << 8;
1434 data
|= (uint8_t) tmp
[2] << 16;
1435 data
|= (uint8_t) tmp
[3] << 24;
1436 int parity
= tmp
[4] ? 0x01 : 0x00;
1438 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32
,
1439 ack
== SWD_ACK_OK
? "OK" : ack
== SWD_ACK_WAIT
? "WAIT" : ack
== SWD_ACK_FAULT
? "FAULT" : "JUNK",
1440 cmd
& SWD_CMD_APnDP
? "AP" : "DP",
1441 cmd
& SWD_CMD_RnW
? "read" : "write",
1442 (cmd
& SWD_CMD_A32
) >> 1,
1447 if (parity
!= parity_u32(data
)) {
1448 LOG_DEBUG("Read data parity mismatch %x %x", parity
, parity_u32(data
));
1449 queued_retval
= ERROR_FAIL
;
1454 if (cmd
& SWD_CMD_APnDP
)
1455 buspirate_swd_idle_clocks(ap_delay_clk
);
1458 LOG_DEBUG("SWD_ACK_WAIT");
1459 buspirate_swd_clear_sticky_errors();
1462 LOG_DEBUG("SWD_ACK_FAULT");
1463 queued_retval
= ack
;
1466 LOG_DEBUG("No valid acknowledge: ack=%d", ack
);
1467 queued_retval
= ack
;
1472 static void buspirate_swd_write_reg(uint8_t cmd
, uint32_t value
, uint32_t ap_delay_clk
)
1476 LOG_DEBUG("buspirate_swd_write_reg");
1477 assert(!(cmd
& SWD_CMD_RnW
));
1479 if (queued_retval
!= ERROR_OK
) {
1480 LOG_DEBUG("Skip buspirate_swd_write_reg because queued_retval=%d", queued_retval
);
1484 cmd
|= SWD_CMD_START
| SWD_CMD_PARK
;
1485 uint8_t ack
= buspirate_swd_write_header(cmd
);
1487 /* do a write transaction */
1488 tmp
[0] = 0x10 + ((4 + 1 - 1) & 0xF); /* bus pirate: send 4+1 bytes */
1489 buf_set_u32((uint8_t *) tmp
+ 1, 0, 32, value
);
1490 /* write sequence ends with parity bit and 7 idle ticks */
1491 tmp
[5] = parity_u32(value
) ? 0x01 : 0x00;
1493 buspirate_serial_write(buspirate_fd
, tmp
, 6);
1494 buspirate_serial_read(buspirate_fd
, tmp
, 6);
1496 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32
,
1497 ack
== SWD_ACK_OK
? "OK" : ack
== SWD_ACK_WAIT
? "WAIT" : ack
== SWD_ACK_FAULT
? "FAULT" : "JUNK",
1498 cmd
& SWD_CMD_APnDP
? "AP" : "DP",
1499 cmd
& SWD_CMD_RnW
? "read" : "write",
1500 (cmd
& SWD_CMD_A32
) >> 1,
1505 if (cmd
& SWD_CMD_APnDP
)
1506 buspirate_swd_idle_clocks(ap_delay_clk
);
1509 LOG_DEBUG("SWD_ACK_WAIT");
1510 buspirate_swd_clear_sticky_errors();
1513 LOG_DEBUG("SWD_ACK_FAULT");
1514 queued_retval
= ack
;
1517 LOG_DEBUG("No valid acknowledge: ack=%d", ack
);
1518 queued_retval
= ack
;
1523 static int buspirate_swd_run_queue(void)
1525 LOG_DEBUG("buspirate_swd_run_queue");
1526 /* A transaction must be followed by another transaction or at least 8 idle cycles to
1527 * ensure that data is clocked through the AP. */
1528 buspirate_swd_idle_clocks(8);
1530 int retval
= queued_retval
;
1531 queued_retval
= ERROR_OK
;
1532 LOG_DEBUG("SWD queue return value: %02x", retval
);
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)