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);
37 static int buspirate_reset(int trst
, int srst
);
39 static void buspirate_end_state(tap_state_t state
);
40 static void buspirate_state_move(void);
41 static void buspirate_path_move(int num_states
, tap_state_t
*path
);
42 static void buspirate_runtest(int num_cycles
);
43 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
44 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
45 static void buspirate_stableclocks(int num_cycles
);
47 #define CMD_UNKNOWN 0x00
48 #define CMD_PORT_MODE 0x01
49 #define CMD_FEATURE 0x02
50 #define CMD_READ_ADCS 0x03
51 /*#define CMD_TAP_SHIFT 0x04 // old protocol */
52 #define CMD_TAP_SHIFT 0x05
53 #define CMD_ENTER_RWIRE 0x05
54 #define CMD_ENTER_OOCD 0x06
55 #define CMD_UART_SPEED 0x07
56 #define CMD_JTAG_SPEED 0x08
57 #define CMD_RAW_PERIPH 0x40
58 #define CMD_RAW_SPEED 0x60
59 #define CMD_RAW_MODE 0x80
61 /* raw-wire mode configuration */
62 #define CMD_RAW_CONFIG_HIZ 0x00
63 #define CMD_RAW_CONFIG_3V3 0x08
64 #define CMD_RAW_CONFIG_2W 0x00
65 #define CMD_RAW_CONFIG_3W 0x04
66 #define CMD_RAW_CONFIG_MSB 0x00
67 #define CMD_RAW_CONFIG_LSB 0x02
69 /* Not all OSes have this speed defined */
70 #if !defined(B1000000)
71 #define B1000000 0010010
76 MODE_JTAG
= 1, /* push-pull outputs */
77 MODE_JTAG_OD
= 2, /* open-drain outputs */
99 SPEED_RAW_5_KHZ
= 0x0,
100 SPEED_RAW_50_KHZ
= 0x1,
101 SPEED_RAW_100_KHZ
= 0x2,
102 SPEED_RAW_400_KHZ
= 0x3
105 /* SWD mode specific */
106 static bool swd_mode
;
107 static int queued_retval
;
108 static char swd_features
;
110 static const cc_t SHORT_TIMEOUT
= 1; /* Must be at least 1. */
111 static const cc_t NORMAL_TIMEOUT
= 10;
113 static int buspirate_fd
= -1;
114 static int buspirate_pinmode
= MODE_JTAG_OD
;
115 static int buspirate_baudrate
= SERIAL_NORMAL
;
116 static int buspirate_vreg
;
117 static int buspirate_pullup
;
118 static char *buspirate_port
;
120 static enum tap_state last_tap_state
= TAP_RESET
;
123 static int buspirate_swd_init(void);
124 static void buspirate_swd_read_reg(uint8_t cmd
, uint32_t *value
, uint32_t ap_delay_clk
);
125 static void buspirate_swd_write_reg(uint8_t cmd
, uint32_t value
, uint32_t ap_delay_clk
);
126 static int buspirate_swd_switch_seq(enum swd_special_seq seq
);
127 static int buspirate_swd_run_queue(void);
130 static void buspirate_tap_init(void);
131 static int buspirate_tap_execute(void);
132 static void buspirate_tap_append(int tms
, int tdi
);
133 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
134 struct scan_command
*command
);
135 static void buspirate_tap_make_space(int scan
, int bits
);
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("sleep %" PRIu32
, cmd
->cmd
.sleep
->us
);
218 buspirate_tap_execute();
219 jtag_sleep(cmd
->cmd
.sleep
->us
);
221 case JTAG_STABLECLOCKS
:
222 LOG_DEBUG_IO("stable clock %i cycles", cmd
->cmd
.stableclocks
->num_cycles
);
223 buspirate_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
);
226 LOG_ERROR("BUG: unknown JTAG command type encountered");
233 return buspirate_tap_execute();
237 /* Returns true if successful, false if error. */
239 static bool read_and_discard_all_data(const int fd
)
241 /* LOG_INFO("Discarding any stale data from a previous connection..."); */
243 bool was_msg_already_printed
= false;
246 uint8_t buffer
[1024]; /* Any size will do, it's a trade-off between stack size and performance. */
248 const ssize_t read_count
= read(fd
, buffer
, sizeof(buffer
));
250 if (read_count
== 0) {
251 /* This is the "end of file" or "connection closed at the other end" condition. */
255 if (read_count
> 0) {
256 if (!was_msg_already_printed
) {
257 LOG_INFO("Some stale data from a previous connection was discarded.");
258 was_msg_already_printed
= true;
264 assert(read_count
== -1); /* According to the specification. */
266 const int errno_code
= errno
;
268 if (errno_code
== EINTR
)
271 if (errno_code
== EAGAIN
||
272 errno_code
== EWOULDBLOCK
) {
273 /* We know that the file descriptor has been opened with O_NONBLOCK or O_NDELAY,
274 and these codes mean that there is no data to read at present. */
278 /* Some other error has occurred. */
284 static int buspirate_init(void)
286 if (buspirate_port
== NULL
) {
287 LOG_ERROR("You need to specify the serial port!");
288 return ERROR_JTAG_INIT_FAILED
;
291 buspirate_fd
= buspirate_serial_open(buspirate_port
);
292 if (buspirate_fd
== -1) {
293 LOG_ERROR("Could not open serial port");
294 return ERROR_JTAG_INIT_FAILED
;
297 /* The Operating System or the device itself may deliver stale data from the last connection,
298 so discard all available bytes right after the new connection has been established.
299 After all, we are implementing here a master/slave protocol, so the slave should have nothing
300 to say until the master sends the first command.
302 In the past, there was a tcflush() call in buspirate_serial_setspeed(), but that
303 was not enough. I guess you must actively read from the serial port to trigger any
304 data collection from the device and/or lower USB layers. If you disable the serial port
305 read timeout (if you set SHORT_TIMEOUT to 0), then the discarding does not work any more.
307 Note that we are lowering the serial port timeout for this first read operation,
308 otherwise the normal initialisation would be delayed for too long. */
310 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, SHORT_TIMEOUT
)) {
311 LOG_ERROR("Error configuring the serial port.");
312 return ERROR_JTAG_INIT_FAILED
;
315 if (!read_and_discard_all_data(buspirate_fd
)) {
316 LOG_ERROR("Error while attempting to discard any stale data right after establishing the connection.");
317 return ERROR_JTAG_INIT_FAILED
;
320 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, NORMAL_TIMEOUT
)) {
321 LOG_ERROR("Error configuring the serial port.");
322 return ERROR_JTAG_INIT_FAILED
;
325 buspirate_bbio_enable(buspirate_fd
);
327 if (swd_mode
|| buspirate_baudrate
!= SERIAL_NORMAL
)
328 buspirate_set_speed(buspirate_fd
, SERIAL_FAST
);
330 LOG_INFO("Buspirate %s Interface ready!", swd_mode
? "SWD" : "JTAG");
333 buspirate_tap_init();
335 buspirate_set_mode(buspirate_fd
, buspirate_pinmode
);
336 buspirate_set_feature(buspirate_fd
, FEATURE_VREG
,
337 (buspirate_vreg
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
338 buspirate_set_feature(buspirate_fd
, FEATURE_PULLUP
,
339 (buspirate_pullup
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
340 buspirate_reset(0, 0);
345 static int buspirate_quit(void)
347 LOG_INFO("Shutting down buspirate.");
348 buspirate_set_mode(buspirate_fd
, MODE_HIZ
);
349 buspirate_set_speed(buspirate_fd
, SERIAL_NORMAL
);
351 buspirate_jtag_reset(buspirate_fd
);
353 buspirate_serial_close(buspirate_fd
);
355 free(buspirate_port
);
356 buspirate_port
= NULL
;
360 /* openocd command interface */
361 COMMAND_HANDLER(buspirate_handle_adc_command
)
363 if (buspirate_fd
== -1)
366 /* unavailable in SWD mode */
370 /* send the command */
371 buspirate_jtag_get_adcs(buspirate_fd
);
377 COMMAND_HANDLER(buspirate_handle_vreg_command
)
380 return ERROR_COMMAND_SYNTAX_ERROR
;
382 if (atoi(CMD_ARGV
[0]) == 1)
384 else if (atoi(CMD_ARGV
[0]) == 0)
387 LOG_ERROR("usage: buspirate_vreg <1|0>");
393 COMMAND_HANDLER(buspirate_handle_pullup_command
)
396 return ERROR_COMMAND_SYNTAX_ERROR
;
398 if (atoi(CMD_ARGV
[0]) == 1)
399 buspirate_pullup
= 1;
400 else if (atoi(CMD_ARGV
[0]) == 0)
401 buspirate_pullup
= 0;
403 LOG_ERROR("usage: buspirate_pullup <1|0>");
409 COMMAND_HANDLER(buspirate_handle_led_command
)
412 return ERROR_COMMAND_SYNTAX_ERROR
;
414 if (atoi(CMD_ARGV
[0]) == 1) {
416 buspirate_set_feature(buspirate_fd
, FEATURE_LED
,
418 } else if (atoi(CMD_ARGV
[0]) == 0) {
420 buspirate_set_feature(buspirate_fd
, FEATURE_LED
,
423 LOG_ERROR("usage: buspirate_led <1|0>");
430 COMMAND_HANDLER(buspirate_handle_mode_command
)
433 return ERROR_COMMAND_SYNTAX_ERROR
;
435 if (CMD_ARGV
[0][0] == 'n')
436 buspirate_pinmode
= MODE_JTAG
;
437 else if (CMD_ARGV
[0][0] == 'o')
438 buspirate_pinmode
= MODE_JTAG_OD
;
440 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
446 COMMAND_HANDLER(buspirate_handle_speed_command
)
449 return ERROR_COMMAND_SYNTAX_ERROR
;
451 if (CMD_ARGV
[0][0] == 'n')
452 buspirate_baudrate
= SERIAL_NORMAL
;
453 else if (CMD_ARGV
[0][0] == 'f')
454 buspirate_baudrate
= SERIAL_FAST
;
456 LOG_ERROR("usage: buspirate_speed <normal|fast>");
462 COMMAND_HANDLER(buspirate_handle_port_command
)
465 return ERROR_COMMAND_SYNTAX_ERROR
;
467 if (buspirate_port
== NULL
)
468 buspirate_port
= strdup(CMD_ARGV
[0]);
474 static const struct command_registration buspirate_command_handlers
[] = {
476 .name
= "buspirate_adc",
477 .handler
= &buspirate_handle_adc_command
,
478 .mode
= COMMAND_EXEC
,
479 .help
= "reads voltages on adc pins",
483 .name
= "buspirate_vreg",
485 .handler
= &buspirate_handle_vreg_command
,
486 .mode
= COMMAND_CONFIG
,
487 .help
= "changes the state of voltage regulators",
490 .name
= "buspirate_pullup",
492 .handler
= &buspirate_handle_pullup_command
,
493 .mode
= COMMAND_CONFIG
,
494 .help
= "changes the state of pullup",
497 .name
= "buspirate_led",
499 .handler
= &buspirate_handle_led_command
,
500 .mode
= COMMAND_EXEC
,
501 .help
= "changes the state of led",
504 .name
= "buspirate_speed",
505 .usage
= "<normal|fast>",
506 .handler
= &buspirate_handle_speed_command
,
507 .mode
= COMMAND_CONFIG
,
508 .help
= "speed of the interface",
511 .name
= "buspirate_mode",
512 .usage
= "<normal|open-drain>",
513 .handler
= &buspirate_handle_mode_command
,
514 .mode
= COMMAND_CONFIG
,
515 .help
= "pin mode of the interface",
518 .name
= "buspirate_port",
519 .usage
= "/dev/ttyUSB0",
520 .handler
= &buspirate_handle_port_command
,
521 .mode
= COMMAND_CONFIG
,
522 .help
= "name of the serial port to open",
524 COMMAND_REGISTRATION_DONE
527 static const struct swd_driver buspirate_swd
= {
528 .init
= buspirate_swd_init
,
529 .switch_seq
= buspirate_swd_switch_seq
,
530 .read_reg
= buspirate_swd_read_reg
,
531 .write_reg
= buspirate_swd_write_reg
,
532 .run
= buspirate_swd_run_queue
,
535 static const char * const buspirate_transports
[] = { "jtag", "swd", NULL
};
537 static struct jtag_interface buspirate_interface
= {
538 .execute_queue
= buspirate_execute_queue
,
541 struct adapter_driver buspirate_adapter_driver
= {
543 .transports
= buspirate_transports
,
544 .commands
= buspirate_command_handlers
,
546 .init
= buspirate_init
,
547 .quit
= buspirate_quit
,
548 .reset
= buspirate_reset
,
550 .jtag_ops
= &buspirate_interface
,
551 .swd_ops
= &buspirate_swd
,
554 /*************** jtag execute commands **********************/
555 static void buspirate_end_state(tap_state_t state
)
557 if (tap_is_state_stable(state
))
558 tap_set_end_state(state
);
560 LOG_ERROR("BUG: %i is not a valid end state", state
);
565 static void buspirate_state_move(void)
568 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
569 tap_get_end_state());
570 int tms_count
= tap_get_tms_path_len(tap_get_state(),
571 tap_get_end_state());
573 for (i
= 0; i
< tms_count
; i
++) {
574 tms
= (tms_scan
>> i
) & 1;
575 buspirate_tap_append(tms
, 0);
578 tap_set_state(tap_get_end_state());
581 static void buspirate_path_move(int num_states
, tap_state_t
*path
)
585 for (i
= 0; i
< num_states
; i
++) {
586 if (tap_state_transition(tap_get_state(), false) == path
[i
]) {
587 buspirate_tap_append(0, 0);
588 } else if (tap_state_transition(tap_get_state(), true)
590 buspirate_tap_append(1, 0);
592 LOG_ERROR("BUG: %s -> %s isn't a valid "
594 tap_state_name(tap_get_state()),
595 tap_state_name(path
[i
]));
599 tap_set_state(path
[i
]);
602 tap_set_end_state(tap_get_state());
605 static void buspirate_runtest(int num_cycles
)
609 tap_state_t saved_end_state
= tap_get_end_state();
611 /* only do a state_move when we're not already in IDLE */
612 if (tap_get_state() != TAP_IDLE
) {
613 buspirate_end_state(TAP_IDLE
);
614 buspirate_state_move();
617 for (i
= 0; i
< num_cycles
; i
++)
618 buspirate_tap_append(0, 0);
620 LOG_DEBUG_IO("runtest: cur_state %s end_state %s",
621 tap_state_name(tap_get_state()),
622 tap_state_name(tap_get_end_state()));
624 /* finish in end_state */
625 buspirate_end_state(saved_end_state
);
626 if (tap_get_state() != tap_get_end_state())
627 buspirate_state_move();
630 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
631 uint8_t *buffer
, int scan_size
, struct scan_command
*command
)
633 tap_state_t saved_end_state
;
635 buspirate_tap_make_space(1, scan_size
+8);
636 /* is 8 correct ? (2 moves = 16) */
638 saved_end_state
= tap_get_end_state();
640 buspirate_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
642 /* Only move if we're not already there */
643 if (tap_get_state() != tap_get_end_state())
644 buspirate_state_move();
646 buspirate_tap_append_scan(scan_size
, buffer
, command
);
649 buspirate_tap_append(0, 0);
651 /* restore the saved state */
652 buspirate_end_state(saved_end_state
);
653 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
655 if (tap_get_state() != tap_get_end_state())
656 buspirate_state_move();
659 static void buspirate_stableclocks(int num_cycles
)
662 int tms
= (tap_get_state() == TAP_RESET
? 1 : 0);
664 buspirate_tap_make_space(0, num_cycles
);
666 for (i
= 0; i
< num_cycles
; i
++)
667 buspirate_tap_append(tms
, 0);
670 /************************* TAP related stuff **********/
672 /* This buffer size matches the maximum CMD_TAP_SHIFT bit length in the Bus Pirate firmware,
673 look for constant 0x2000 in OpenOCD.c . */
674 #define BUSPIRATE_BUFFER_SIZE 1024
676 /* The old value of 32 scans was not enough to achieve near 100% utilisation ratio
677 for the current BUSPIRATE_BUFFER_SIZE value of 1024.
678 With 128 scans I am getting full USB 2.0 high speed packets (512 bytes long) when
679 using the JtagDue firmware on the Arduino Due instead of the Bus Pirate, which
680 amounts approximately to a 10% overall speed gain. Bigger packets should also
681 benefit the Bus Pirate, but the speed difference is much smaller.
682 Unfortunately, each 512-byte packet is followed by a 329-byte one, which is not ideal.
683 However, increasing BUSPIRATE_BUFFER_SIZE for the benefit of the JtagDue would
684 make it incompatible with the Bus Pirate firmware. */
685 #define BUSPIRATE_MAX_PENDING_SCANS 128
687 static uint8_t tms_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
688 static uint8_t tdi_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
689 static int tap_chain_index
;
691 struct pending_scan_result
/* this was stolen from arm-jtag-ew */
693 int first
; /* First bit position in tdo_buffer to read */
694 int length
; /* Number of bits to read */
695 struct scan_command
*command
; /* Corresponding scan command */
699 static struct pending_scan_result
700 tap_pending_scans
[BUSPIRATE_MAX_PENDING_SCANS
];
701 static int tap_pending_scans_num
;
703 static void buspirate_tap_init(void)
706 tap_pending_scans_num
= 0;
709 static int buspirate_tap_execute(void)
711 static const int CMD_TAP_SHIFT_HEADER_LEN
= 3;
720 if (tap_chain_index
<= 0)
723 LOG_DEBUG("executing tap num bits = %i scans = %i",
724 tap_chain_index
, tap_pending_scans_num
);
726 bytes_to_send
= DIV_ROUND_UP(tap_chain_index
, 8);
728 tmp
[0] = CMD_TAP_SHIFT
; /* this command expects number of bits */
729 tmp
[1] = tap_chain_index
>> 8; /* high */
730 tmp
[2] = tap_chain_index
; /* low */
732 fill_index
= CMD_TAP_SHIFT_HEADER_LEN
;
733 for (i
= 0; i
< bytes_to_send
; i
++) {
734 tmp
[fill_index
] = tdi_chain
[i
];
736 tmp
[fill_index
] = tms_chain
[i
];
740 /* jlink.c calls the routine below, which may be useful for debugging purposes.
741 For example, enabling this allows you to compare the log outputs from jlink.c
742 and from this module for JTAG development or troubleshooting purposes. */
744 last_tap_state
= jtag_debug_state_machine(tms_chain
, tdi_chain
,
745 tap_chain_index
, last_tap_state
);
748 ret
= buspirate_serial_write(buspirate_fd
, tmp
, CMD_TAP_SHIFT_HEADER_LEN
+ bytes_to_send
*2);
749 if (ret
!= bytes_to_send
*2+CMD_TAP_SHIFT_HEADER_LEN
) {
750 LOG_ERROR("error writing :(");
751 return ERROR_JTAG_DEVICE_ERROR
;
754 ret
= buspirate_serial_read(buspirate_fd
, tmp
, bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
);
755 if (ret
!= bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
) {
756 LOG_ERROR("error reading");
759 in_buf
= (uint8_t *)(&tmp
[CMD_TAP_SHIFT_HEADER_LEN
]);
761 /* parse the scans */
762 for (i
= 0; i
< tap_pending_scans_num
; i
++) {
763 uint8_t *buffer
= tap_pending_scans
[i
].buffer
;
764 int length
= tap_pending_scans
[i
].length
;
765 int first
= tap_pending_scans
[i
].first
;
766 struct scan_command
*command
= tap_pending_scans
[i
].command
;
768 /* copy bits from buffer */
769 buf_set_buf(in_buf
, first
, buffer
, 0, length
);
771 /* return buffer to higher level */
772 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
) {
773 buspirate_tap_init();
774 return ERROR_JTAG_QUEUE_FAILED
;
779 buspirate_tap_init();
783 static void buspirate_tap_make_space(int scans
, int bits
)
785 int have_scans
= BUSPIRATE_MAX_PENDING_SCANS
- tap_pending_scans_num
;
786 int have_bits
= BUSPIRATE_BUFFER_SIZE
* 8 - tap_chain_index
;
788 if ((have_scans
< scans
) || (have_bits
< bits
))
789 buspirate_tap_execute();
792 static void buspirate_tap_append(int tms
, int tdi
)
796 buspirate_tap_make_space(0, 1);
797 chain_index
= tap_chain_index
/ 8;
799 if (chain_index
< BUSPIRATE_BUFFER_SIZE
) {
800 int bit_index
= tap_chain_index
% 8;
801 uint8_t bit
= 1 << bit_index
;
803 if (0 == bit_index
) {
804 /* Let's say that the TAP shift operation wants to shift 9 bits,
805 so we will be sending to the Bus Pirate a bit count of 9 but still
806 full 16 bits (2 bytes) of shift data.
807 If we don't clear all bits at this point, the last 7 bits will contain
808 random data from the last buffer contents, which is not pleasant to the eye.
809 Besides, the Bus Pirate (or some clone) may want to assert in debug builds
810 that, after consuming all significant data bits, the rest of them are zero.
811 Therefore, for aesthetic and for assert purposes, we clear all bits below. */
812 tms_chain
[chain_index
] = 0;
813 tdi_chain
[chain_index
] = 0;
817 tms_chain
[chain_index
] |= bit
;
819 tms_chain
[chain_index
] &= ~bit
;
822 tdi_chain
[chain_index
] |= bit
;
824 tdi_chain
[chain_index
] &= ~bit
;
828 LOG_ERROR("tap_chain overflow, bad things will happen");
829 /* Exit abruptly, like jlink.c does. After a buffer overflow we don't want
830 to carry on, as data will be corrupt. Another option would be to return
831 some error code at this point. */
836 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
837 struct scan_command
*command
)
840 tap_pending_scans
[tap_pending_scans_num
].length
= length
;
841 tap_pending_scans
[tap_pending_scans_num
].buffer
= buffer
;
842 tap_pending_scans
[tap_pending_scans_num
].command
= command
;
843 tap_pending_scans
[tap_pending_scans_num
].first
= tap_chain_index
;
845 for (i
= 0; i
< length
; i
++) {
846 int tms
= (i
< length
-1 ? 0 : 1);
847 int tdi
= (buffer
[i
/8] >> (i
%8)) & 1;
848 buspirate_tap_append(tms
, tdi
);
850 tap_pending_scans_num
++;
853 /*************** wrapper functions *********************/
855 /* (1) assert or (0) deassert reset lines */
856 static int buspirate_reset(int trst
, int srst
)
858 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
861 buspirate_set_feature(buspirate_fd
, FEATURE_TRST
, ACTION_DISABLE
);
863 buspirate_set_feature(buspirate_fd
, FEATURE_TRST
, ACTION_ENABLE
);
866 buspirate_set_feature(buspirate_fd
, FEATURE_SRST
, ACTION_DISABLE
);
868 buspirate_set_feature(buspirate_fd
, FEATURE_SRST
, ACTION_ENABLE
);
873 static void buspirate_set_feature(int fd
, char feat
, char action
)
876 buspirate_swd_set_feature(fd
, feat
, action
);
878 buspirate_jtag_set_feature(fd
, feat
, action
);
881 static void buspirate_set_mode(int fd
, char mode
)
884 buspirate_swd_set_mode(fd
, mode
);
886 buspirate_jtag_set_mode(fd
, mode
);
889 static void buspirate_set_speed(int fd
, char speed
)
892 buspirate_swd_set_speed(fd
, speed
);
894 buspirate_jtag_set_speed(fd
, speed
);
898 /*************** swd lowlevel functions ********************/
900 static void buspirate_swd_set_speed(int fd
, char speed
)
905 LOG_DEBUG("Buspirate speed setting in SWD mode defaults to 400 kHz");
908 tmp
[0] = CMD_RAW_SPEED
| SPEED_RAW_400_KHZ
;
909 buspirate_serial_write(fd
, tmp
, 1);
910 ret
= buspirate_serial_read(fd
, tmp
, 1);
912 LOG_ERROR("Buspirate did not answer correctly");
916 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
921 static void buspirate_swd_set_mode(int fd
, char mode
)
926 /* raw-wire mode configuration */
927 if (mode
== MODE_HIZ
)
928 tmp
[0] = CMD_RAW_MODE
| CMD_RAW_CONFIG_LSB
;
930 tmp
[0] = CMD_RAW_MODE
| CMD_RAW_CONFIG_LSB
| CMD_RAW_CONFIG_3V3
;
932 buspirate_serial_write(fd
, tmp
, 1);
933 ret
= buspirate_serial_read(fd
, tmp
, 1);
935 LOG_ERROR("Buspirate did not answer correctly");
939 LOG_ERROR("Buspirate did not reply as expected to the configure command");
944 static void buspirate_swd_set_feature(int fd
, char feat
, char action
)
951 LOG_DEBUG("Buspirate TRST feature not available in SWD mode");
954 LOG_ERROR("Buspirate LED feature not available in SWD mode");
957 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x02 : swd_features
& 0x0D;
960 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x04 : swd_features
& 0x0B;
963 swd_features
= (action
== ACTION_ENABLE
) ? swd_features
| 0x08 : swd_features
& 0x07;
966 LOG_DEBUG("Buspirate unknown feature %d", feat
);
970 tmp
[0] = CMD_RAW_PERIPH
| swd_features
;
971 buspirate_serial_write(fd
, tmp
, 1);
972 ret
= buspirate_serial_read(fd
, tmp
, 1);
974 LOG_DEBUG("Buspirate feature %d not supported in SWD mode", feat
);
975 } else if (tmp
[0] != 1) {
976 LOG_ERROR("Buspirate did not reply as expected to the configure command");
981 /*************** jtag lowlevel functions ********************/
982 static void buspirate_bbio_enable(int fd
)
986 const char *mode_answers
[2] = { "OCD1", "RAW1" };
987 const char *correct_ans
= NULL
;
988 uint8_t tmp
[21] = { [0 ... 20] = 0x00 };
993 command
= CMD_ENTER_RWIRE
;
994 correct_ans
= mode_answers
[1];
996 command
= CMD_ENTER_OOCD
;
997 correct_ans
= mode_answers
[0];
1000 LOG_DEBUG("Entering binary mode, that is %s", correct_ans
);
1001 buspirate_serial_write(fd
, tmp
, 20);
1004 /* reads 1 to n "BBIO1"s and one "OCD1" or "RAW1" */
1006 ret
= buspirate_serial_read(fd
, tmp
, 4);
1008 LOG_ERROR("Buspirate error. Is binary"
1009 "/OpenOCD support enabled?");
1012 if (strncmp((char *)tmp
, "BBIO", 4) == 0) {
1013 ret
= buspirate_serial_read(fd
, tmp
, 1);
1015 LOG_ERROR("Buspirate did not answer correctly! "
1016 "Do you have correct firmware?");
1019 if (tmp
[0] != '1') {
1020 LOG_ERROR("Unsupported binary protocol");
1023 if (cmd_sent
== 0) {
1026 ret
= buspirate_serial_write(fd
, tmp
, 1);
1028 LOG_ERROR("error reading");
1032 } else if (strncmp((char *)tmp
, correct_ans
, 4) == 0)
1035 LOG_ERROR("Buspirate did not answer correctly! "
1036 "Do you have correct firmware?");
1043 static void buspirate_jtag_reset(int fd
)
1047 tmp
[0] = 0x00; /* exit OCD1 mode */
1048 buspirate_serial_write(fd
, tmp
, 1);
1050 /* We ignore the return value here on purpose, nothing we can do */
1051 buspirate_serial_read(fd
, tmp
, 5);
1052 if (strncmp((char *)tmp
, "BBIO1", 5) == 0) {
1053 tmp
[0] = 0x0F; /* reset BP */
1054 buspirate_serial_write(fd
, tmp
, 1);
1056 LOG_ERROR("Unable to restart buspirate!");
1059 static void buspirate_jtag_set_speed(int fd
, char speed
)
1068 tmp
[0] = CMD_UART_SPEED
;
1070 buspirate_jtag_command(fd
, tmp
, 2);
1072 /* here the adapter changes speed, we need follow */
1073 if (-1 == buspirate_serial_setspeed(fd
, speed
, NORMAL_TIMEOUT
)) {
1074 LOG_ERROR("Error configuring the serial port.");
1078 buspirate_serial_write(fd
, ack
, 2);
1079 ret
= buspirate_serial_read(fd
, tmp
, 2);
1081 LOG_ERROR("Buspirate did not ack speed change");
1084 if ((tmp
[0] != CMD_UART_SPEED
) || (tmp
[1] != speed
)) {
1085 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
1088 LOG_INFO("Buspirate switched to %s mode",
1089 (speed
== SERIAL_NORMAL
) ? "normal" : "FAST");
1093 static void buspirate_jtag_set_mode(int fd
, char mode
)
1096 tmp
[0] = CMD_PORT_MODE
;
1098 buspirate_jtag_command(fd
, tmp
, 2);
1101 static void buspirate_jtag_set_feature(int fd
, char feat
, char action
)
1104 tmp
[0] = CMD_FEATURE
;
1105 tmp
[1] = feat
; /* what */
1106 tmp
[2] = action
; /* action */
1107 buspirate_jtag_command(fd
, tmp
, 3);
1110 static void buspirate_jtag_get_adcs(int fd
)
1113 uint16_t a
, b
, c
, d
;
1114 tmp
[0] = CMD_READ_ADCS
;
1115 buspirate_jtag_command(fd
, tmp
, 1);
1116 a
= tmp
[2] << 8 | tmp
[3];
1117 b
= tmp
[4] << 8 | tmp
[5];
1118 c
= tmp
[6] << 8 | tmp
[7];
1119 d
= tmp
[8] << 8 | tmp
[9];
1121 LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f "
1123 ((float)a
)/155.1515, ((float)b
)/155.1515,
1124 ((float)c
)/155.1515, ((float)d
)/155.1515);
1127 static unsigned char buspirate_jtag_command(int fd
,
1128 uint8_t *cmd
, int cmdlen
)
1133 res
= buspirate_serial_write(fd
, cmd
, cmdlen
);
1135 if ((cmd
[0] == CMD_UART_SPEED
)
1136 || (cmd
[0] == CMD_PORT_MODE
)
1137 || (cmd
[0] == CMD_FEATURE
)
1138 || (cmd
[0] == CMD_JTAG_SPEED
))
1141 if (res
== cmdlen
) {
1144 len
= 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */
1150 LOG_INFO("Wrong !");
1152 res
= buspirate_serial_read(fd
, cmd
, len
);
1154 return (unsigned char)cmd
[1];
1162 /* low level serial port */
1163 /* TODO add support for WIN32 and others ! */
1164 static int buspirate_serial_open(char *port
)
1167 fd
= open(buspirate_port
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
1172 /* Returns -1 on error. */
1174 static int buspirate_serial_setspeed(int fd
, char speed
, cc_t timeout
)
1176 struct termios t_opt
;
1177 speed_t baud
= (speed
== SERIAL_FAST
) ? B1000000
: B115200
;
1179 /* set the serial port parameters */
1180 fcntl(fd
, F_SETFL
, 0);
1181 if (0 != tcgetattr(fd
, &t_opt
))
1184 if (0 != cfsetispeed(&t_opt
, baud
))
1187 if (0 != cfsetospeed(&t_opt
, baud
))
1190 t_opt
.c_cflag
|= (CLOCAL
| CREAD
);
1191 t_opt
.c_cflag
&= ~PARENB
;
1192 t_opt
.c_cflag
&= ~CSTOPB
;
1193 t_opt
.c_cflag
&= ~CSIZE
;
1194 t_opt
.c_cflag
|= CS8
;
1195 t_opt
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
);
1197 /* The serial port may have been configured for human interaction with
1198 the Bus Pirate console, but OpenOCD is going to use a binary protocol,
1199 so make sure to turn off any CR/LF translation and the like. */
1200 t_opt
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
| INLCR
| ICRNL
);
1202 t_opt
.c_oflag
&= ~OPOST
;
1203 t_opt
.c_cc
[VMIN
] = 0;
1204 t_opt
.c_cc
[VTIME
] = timeout
;
1206 /* Note that, in the past, TCSANOW was used below instead of TCSADRAIN,
1207 and CMD_UART_SPEED did not work properly then, at least with
1208 the Bus Pirate v3.5 (USB). */
1209 if (0 != tcsetattr(fd
, TCSADRAIN
, &t_opt
)) {
1210 /* According to the Linux documentation, this is actually not enough
1211 to detect errors, you need to call tcgetattr() and check that
1212 all changes have been performed successfully. */
1219 static int buspirate_serial_write(int fd
, uint8_t *buf
, int size
)
1223 ret
= write(fd
, buf
, size
);
1225 LOG_DEBUG("size = %d ret = %d", size
, ret
);
1226 buspirate_print_buffer(buf
, size
);
1229 LOG_ERROR("Error sending data");
1234 static int buspirate_serial_read(int fd
, uint8_t *buf
, int size
)
1240 while (len
< size
) {
1241 ret
= read(fd
, buf
+len
, size
-len
);
1257 LOG_DEBUG("should have read = %d actual size = %d", size
, len
);
1258 buspirate_print_buffer(buf
, len
);
1261 LOG_ERROR("Error reading data");
1266 static void buspirate_serial_close(int fd
)
1271 #define LINE_SIZE 81
1272 #define BYTES_PER_LINE 16
1273 static void buspirate_print_buffer(uint8_t *buf
, int size
)
1275 char line
[LINE_SIZE
];
1280 while (offset
< size
) {
1281 snprintf(tmp
, 5, "%02x ", (uint8_t)buf
[offset
]);
1286 if (offset
% BYTES_PER_LINE
== 0) {
1287 LOG_DEBUG("%s", line
);
1293 LOG_DEBUG("%s", line
);
1296 /************************* SWD related stuff **********/
1298 static int buspirate_swd_init(void)
1300 LOG_INFO("Buspirate SWD mode enabled");
1306 static int buspirate_swd_switch_seq(enum swd_special_seq seq
)
1308 const uint8_t *sequence
;
1310 uint32_t no_bytes
, sequence_offset
;
1314 LOG_DEBUG("SWD line reset");
1315 sequence
= swd_seq_line_reset
;
1316 sequence_len
= DIV_ROUND_UP(swd_seq_line_reset_len
, 8);
1319 LOG_DEBUG("JTAG-to-SWD");
1320 sequence
= swd_seq_jtag_to_swd
;
1321 sequence_len
= DIV_ROUND_UP(swd_seq_jtag_to_swd_len
, 8);
1324 LOG_DEBUG("SWD-to-JTAG");
1325 sequence
= swd_seq_swd_to_jtag
;
1326 sequence_len
= DIV_ROUND_UP(swd_seq_swd_to_jtag_len
, 8);
1329 LOG_ERROR("Sequence %d not supported", seq
);
1333 no_bytes
= sequence_len
;
1334 sequence_offset
= 0;
1340 to_send
= no_bytes
> 16 ? 16 : no_bytes
;
1342 tmp
[0] = 0x10 + ((to_send
- 1) & 0x0F);
1343 memcpy(tmp
+ 1, &sequence
[sequence_offset
], to_send
);
1345 buspirate_serial_write(buspirate_fd
, tmp
, to_send
+ 1);
1346 buspirate_serial_read(buspirate_fd
, tmp
, to_send
+ 1);
1348 no_bytes
-= to_send
;
1349 sequence_offset
+= to_send
;
1355 static uint8_t buspirate_swd_write_header(uint8_t cmd
)
1360 tmp
[0] = 0x10; /* bus pirate: send 1 byte */
1361 tmp
[1] = cmd
; /* swd cmd */
1362 tmp
[2] = 0x07; /* ack __x */
1363 tmp
[3] = 0x07; /* ack _x_ */
1364 tmp
[4] = 0x07; /* ack x__ */
1365 tmp
[5] = 0x07; /* write mode trn_1 */
1366 tmp
[6] = 0x07; /* write mode trn_2 */
1368 to_send
= ((cmd
& SWD_CMD_RNW
) == 0) ? 7 : 5;
1369 buspirate_serial_write(buspirate_fd
, tmp
, to_send
);
1372 buspirate_serial_read(buspirate_fd
, tmp
, 2); /* drop pirate command ret vals */
1373 buspirate_serial_read(buspirate_fd
, tmp
, to_send
- 2); /* ack bits */
1375 return tmp
[2] << 2 | tmp
[1] << 1 | tmp
[0];
1378 static void buspirate_swd_idle_clocks(uint32_t no_bits
)
1383 no_bytes
= (no_bits
+ 7) / 8;
1384 memset(tmp
+ 1, 0x00, sizeof(tmp
) - 1);
1386 /* unfortunately bus pirate misbehaves when clocks are sent in parts
1387 * so we need to limit at 128 clock cycles
1393 uint8_t to_send
= no_bytes
> 16 ? 16 : no_bytes
;
1394 tmp
[0] = 0x10 + ((to_send
- 1) & 0x0F);
1396 buspirate_serial_write(buspirate_fd
, tmp
, to_send
+ 1);
1397 buspirate_serial_read(buspirate_fd
, tmp
, to_send
+ 1);
1399 no_bytes
-= to_send
;
1403 static void buspirate_swd_clear_sticky_errors(void)
1405 buspirate_swd_write_reg(swd_cmd(false, false, DP_ABORT
),
1406 STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
1409 static void buspirate_swd_read_reg(uint8_t cmd
, uint32_t *value
, uint32_t ap_delay_clk
)
1413 LOG_DEBUG("buspirate_swd_read_reg");
1414 assert(cmd
& SWD_CMD_RNW
);
1416 if (queued_retval
!= ERROR_OK
) {
1417 LOG_DEBUG("Skip buspirate_swd_read_reg because queued_retval=%d", queued_retval
);
1421 cmd
|= SWD_CMD_START
| SWD_CMD_PARK
;
1422 uint8_t ack
= buspirate_swd_write_header(cmd
);
1424 /* do a read transaction */
1425 tmp
[0] = 0x06; /* 4 data bytes */
1429 tmp
[4] = 0x07; /* parity bit */
1430 tmp
[5] = 0x21; /* 2 turnaround clocks */
1432 buspirate_serial_write(buspirate_fd
, tmp
, 6);
1433 buspirate_serial_read(buspirate_fd
, tmp
, 6);
1435 /* store the data and parity */
1436 uint32_t data
= (uint8_t) tmp
[0];
1437 data
|= (uint8_t) tmp
[1] << 8;
1438 data
|= (uint8_t) tmp
[2] << 16;
1439 data
|= (uint8_t) tmp
[3] << 24;
1440 int parity
= tmp
[4] ? 0x01 : 0x00;
1442 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32
,
1443 ack
== SWD_ACK_OK
? "OK" : ack
== SWD_ACK_WAIT
? "WAIT" : ack
== SWD_ACK_FAULT
? "FAULT" : "JUNK",
1444 cmd
& SWD_CMD_APNDP
? "AP" : "DP",
1445 cmd
& SWD_CMD_RNW
? "read" : "write",
1446 (cmd
& SWD_CMD_A32
) >> 1,
1451 if (parity
!= parity_u32(data
)) {
1452 LOG_DEBUG("Read data parity mismatch %x %x", parity
, parity_u32(data
));
1453 queued_retval
= ERROR_FAIL
;
1458 if (cmd
& SWD_CMD_APNDP
)
1459 buspirate_swd_idle_clocks(ap_delay_clk
);
1462 LOG_DEBUG("SWD_ACK_WAIT");
1463 buspirate_swd_clear_sticky_errors();
1466 LOG_DEBUG("SWD_ACK_FAULT");
1467 queued_retval
= ack
;
1470 LOG_DEBUG("No valid acknowledge: ack=%d", ack
);
1471 queued_retval
= ack
;
1476 static void buspirate_swd_write_reg(uint8_t cmd
, uint32_t value
, uint32_t ap_delay_clk
)
1480 LOG_DEBUG("buspirate_swd_write_reg");
1481 assert(!(cmd
& SWD_CMD_RNW
));
1483 if (queued_retval
!= ERROR_OK
) {
1484 LOG_DEBUG("Skip buspirate_swd_write_reg because queued_retval=%d", queued_retval
);
1488 cmd
|= SWD_CMD_START
| SWD_CMD_PARK
;
1489 uint8_t ack
= buspirate_swd_write_header(cmd
);
1491 /* do a write transaction */
1492 tmp
[0] = 0x10 + ((4 + 1 - 1) & 0xF); /* bus pirate: send 4+1 bytes */
1493 buf_set_u32((uint8_t *) tmp
+ 1, 0, 32, value
);
1494 /* write sequence ends with parity bit and 7 idle ticks */
1495 tmp
[5] = parity_u32(value
) ? 0x01 : 0x00;
1497 buspirate_serial_write(buspirate_fd
, tmp
, 6);
1498 buspirate_serial_read(buspirate_fd
, tmp
, 6);
1500 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32
,
1501 ack
== SWD_ACK_OK
? "OK" : ack
== SWD_ACK_WAIT
? "WAIT" : ack
== SWD_ACK_FAULT
? "FAULT" : "JUNK",
1502 cmd
& SWD_CMD_APNDP
? "AP" : "DP",
1503 cmd
& SWD_CMD_RNW
? "read" : "write",
1504 (cmd
& SWD_CMD_A32
) >> 1,
1509 if (cmd
& SWD_CMD_APNDP
)
1510 buspirate_swd_idle_clocks(ap_delay_clk
);
1513 LOG_DEBUG("SWD_ACK_WAIT");
1514 buspirate_swd_clear_sticky_errors();
1517 LOG_DEBUG("SWD_ACK_FAULT");
1518 queued_retval
= ack
;
1521 LOG_DEBUG("No valid acknowledge: ack=%d", ack
);
1522 queued_retval
= ack
;
1527 static int buspirate_swd_run_queue(void)
1529 LOG_DEBUG("buspirate_swd_run_queue");
1530 /* A transaction must be followed by another transaction or at least 8 idle cycles to
1531 * ensure that data is clocked through the AP. */
1532 buspirate_swd_idle_clocks(8);
1534 int retval
= queued_retval
;
1535 queued_retval
= ERROR_OK
;
1536 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)