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, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 ***************************************************************************/
26 #include <jtag/interface.h>
28 #include <jtag/commands.h>
32 #include <sys/ioctl.h>
35 /*#define DEBUG_SERIAL */
36 static int buspirate_execute_queue(void);
37 static int buspirate_init(void);
38 static int buspirate_quit(void);
40 static void buspirate_end_state(tap_state_t state
);
41 static void buspirate_state_move(void);
42 static void buspirate_path_move(int num_states
, tap_state_t
*path
);
43 static void buspirate_runtest(int num_cycles
);
44 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
45 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
46 static int buspirate_swd_switch_seq(struct adiv5_dap
*dap
,
47 enum swd_special_seq seq
);
49 #define CMD_UNKNOWN 0x00
50 #define CMD_PORT_MODE 0x01
51 #define CMD_FEATURE 0x02
52 #define CMD_READ_ADCS 0x03
53 /*#define CMD_TAP_SHIFT 0x04 // old protocol */
54 #define CMD_TAP_SHIFT 0x05
55 #define CMD_ENTER_RWIRE 0x05
56 #define CMD_ENTER_OOCD 0x06
57 #define CMD_UART_SPEED 0x07
58 #define CMD_JTAG_SPEED 0x08
59 #define CMD_RAW_SPEED 0x60
60 #define CMD_RAW_CONFIG 0x80
61 #define CMD_RAW_FEATURE 0x40
63 /* raw-wire mode configuration */
64 #define CMD_RAW_CONFIG_HIZ 0x00
65 #define CMD_RAW_CONFIG_3V3 0x08
66 #define CMD_RAW_CONFIG_2W 0x00
67 #define CMD_RAW_CONFIG_3W 0x04
68 #define CMD_RAW_CONFIG_MSB 0x00
69 #define CMD_RAW_CONFIG_LSB 0x02
71 /* Not all OSes have this speed defined */
72 #if !defined(B1000000)
73 #define B1000000 0010010
78 MODE_JTAG
= 1, /* push-pull outputs */
79 MODE_JTAG_OD
= 2, /* open-drain outputs */
90 /* feature codes available in SWD mode */
92 SWD_FEATURE_VREG
= 0x08,
93 SWD_FEATURE_PULLUP
= 0x04,
94 SWD_FEATURE_SRST
= 0x02
108 SPEED_RAW_5_KHZ
= 0x0,
109 SPEED_RAW_50_KHZ
= 0x1,
110 SPEED_RAW_100_KHZ
= 0x2,
111 SPEED_RAW_400_KHZ
= 0x3
114 static uint8_t swd_feature_config
;
116 /* SWD mode specific */
117 static bool swd_mode
;
119 /* FIXME: Where to store per-instance data? We need an SWD context. */
120 /* copied from ftdi.c driver */
121 static struct swd_cmd_queue_entry
{
128 static size_t swd_cmd_queue_length
;
129 static size_t swd_cmd_queue_alloced
;
130 static int queued_retval
;
132 static const cc_t SHORT_TIMEOUT
= 1; /* Must be at least 1. */
133 static const cc_t NORMAL_TIMEOUT
= 10;
135 static int buspirate_fd
= -1;
136 static int buspirate_pinmode
= MODE_JTAG_OD
;
137 static int buspirate_baudrate
= SERIAL_NORMAL
;
138 static int buspirate_vreg
;
139 static int buspirate_pullup
;
140 static char *buspirate_port
;
142 static enum tap_state last_tap_state
= TAP_RESET
;
145 static int buspirate_swd_run_queue(struct adiv5_dap
*dap
);
148 static void buspirate_tap_init(void);
149 static int buspirate_tap_execute(void);
150 static void buspirate_tap_append(int tms
, int tdi
);
151 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
152 struct scan_command
*command
);
153 static void buspirate_tap_make_space(int scan
, int bits
);
155 static void buspirate_reset(int trst
, int srst
);
157 /* low level interface */
158 static void buspirate_bbio_enable(int);
159 static void buspirate_jtag_reset(int);
160 static unsigned char buspirate_jtag_command(int, char *, int);
161 static void buspirate_jtag_set_speed(int, char);
162 static void buspirate_jtag_set_mode(int, char);
163 static void buspirate_jtag_set_feature(int, char, char);
164 static void buspirate_jtag_get_adcs(int);
166 /* low level two-wire interface */
167 static void buspirate_swd_set_params(int);
168 static void buspirate_swd_set_feature(int, char, char);
170 /* low level HW communication interface */
171 static int buspirate_serial_open(char *port
);
172 static int buspirate_serial_setspeed(int fd
, char speed
, cc_t timeout
);
173 static int buspirate_serial_write(int fd
, char *buf
, int size
);
174 static int buspirate_serial_read(int fd
, char *buf
, int size
);
175 static void buspirate_serial_close(int fd
);
176 static void buspirate_print_buffer(char *buf
, int size
);
178 static int buspirate_execute_queue(void)
180 /* currently processed command */
181 struct jtag_command
*cmd
= jtag_command_queue
;
189 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
190 cmd
->cmd
.runtest
->num_cycles
,
191 tap_state_name(cmd
->cmd
.runtest
193 buspirate_end_state(cmd
->cmd
.runtest
195 buspirate_runtest(cmd
->cmd
.runtest
199 DEBUG_JTAG_IO("statemove end in %s",
200 tap_state_name(cmd
->cmd
.statemove
202 buspirate_end_state(cmd
->cmd
.statemove
204 buspirate_state_move();
207 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
208 cmd
->cmd
.pathmove
->num_states
,
209 tap_state_name(cmd
->cmd
.pathmove
210 ->path
[cmd
->cmd
.pathmove
212 buspirate_path_move(cmd
->cmd
.pathmove
214 cmd
->cmd
.pathmove
->path
);
217 DEBUG_JTAG_IO("scan end in %s",
218 tap_state_name(cmd
->cmd
.scan
221 buspirate_end_state(cmd
->cmd
.scan
224 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
,
226 type
= jtag_scan_type(cmd
->cmd
.scan
);
227 buspirate_scan(cmd
->cmd
.scan
->ir_scan
, type
,
228 buffer
, scan_size
, cmd
->cmd
.scan
);
232 DEBUG_JTAG_IO("reset trst: %i srst %i",
233 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
235 /* flush buffers, so we can reset */
236 buspirate_tap_execute();
238 if (cmd
->cmd
.reset
->trst
== 1)
239 tap_set_state(TAP_RESET
);
240 buspirate_reset(cmd
->cmd
.reset
->trst
,
241 cmd
->cmd
.reset
->srst
);
244 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
245 buspirate_tap_execute();
246 jtag_sleep(cmd
->cmd
.sleep
->us
);
249 LOG_ERROR("BUG: unknown JTAG command type encountered");
256 return buspirate_tap_execute();
260 /* Returns true if successful, false if error. */
262 static bool read_and_discard_all_data(const int fd
)
264 /* LOG_INFO("Discarding any stale data from a previous connection..."); */
266 bool was_msg_already_printed
= false;
269 char buffer
[1024]; /* Any size will do, it's a trade-off between stack size and performance. */
271 const ssize_t read_count
= read(fd
, buffer
, sizeof(buffer
));
273 if (read_count
== 0) {
274 /* This is the "end of file" or "connection closed at the other end" condition. */
278 if (read_count
> 0) {
279 if (!was_msg_already_printed
) {
280 LOG_INFO("Some stale data from a previous connection was discarded.");
281 was_msg_already_printed
= true;
287 assert(read_count
== -1); /* According to the specification. */
289 const int errno_code
= errno
;
291 if (errno_code
== EINTR
)
294 if (errno_code
== EAGAIN
||
295 errno_code
== EWOULDBLOCK
) {
296 /* We know that the file descriptor has been opened with O_NONBLOCK or O_NDELAY,
297 and these codes mean that there is no data to read at present. */
301 /* Some other error has occurred. */
307 static int buspirate_init(void)
309 if (buspirate_port
== NULL
) {
310 LOG_ERROR("You need to specify the serial port!");
311 return ERROR_JTAG_INIT_FAILED
;
314 buspirate_fd
= buspirate_serial_open(buspirate_port
);
315 if (buspirate_fd
== -1) {
316 LOG_ERROR("Could not open serial port");
317 return ERROR_JTAG_INIT_FAILED
;
320 /* The Operating System or the device itself may deliver stale data from the last connection,
321 so discard all available bytes right after the new connection has been established.
322 After all, we are implementing here a master/slave protocol, so the slave should have nothing
323 to say until the master sends the first command.
325 In the past, there was a tcflush() call in buspirate_serial_setspeed(), but that
326 was not enough. I guess you must actively read from the serial port to trigger any
327 data collection from the device and/or lower USB layers. If you disable the serial port
328 read timeout (if you set SHORT_TIMEOUT to 0), then the discarding does not work any more.
330 Note that we are lowering the serial port timeout for this first read operation,
331 otherwise the normal initialisation would be delayed for too long. */
333 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, SHORT_TIMEOUT
)) {
334 LOG_ERROR("Error configuring the serial port.");
335 return ERROR_JTAG_INIT_FAILED
;
338 if (!read_and_discard_all_data(buspirate_fd
)) {
339 LOG_ERROR("Error while attempting to discard any stale data right after establishing the connection.");
340 return ERROR_JTAG_INIT_FAILED
;
343 if (-1 == buspirate_serial_setspeed(buspirate_fd
, SERIAL_NORMAL
, NORMAL_TIMEOUT
)) {
344 LOG_ERROR("Error configuring the serial port.");
345 return ERROR_JTAG_INIT_FAILED
;
348 buspirate_bbio_enable(buspirate_fd
);
351 buspirate_swd_set_params(buspirate_fd
);
352 else if (buspirate_baudrate
!= SERIAL_NORMAL
)
353 buspirate_jtag_set_speed(buspirate_fd
, SERIAL_FAST
);
355 LOG_INFO("Buspirate %s Interface ready!", swd_mode
? "SWD" : "JTAG");
358 buspirate_tap_init();
359 buspirate_jtag_set_mode(buspirate_fd
, buspirate_pinmode
);
362 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_VREG
,
363 (buspirate_vreg
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
364 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_PULLUP
,
365 (buspirate_pullup
== 1) ? ACTION_ENABLE
: ACTION_DISABLE
);
366 buspirate_reset(0, 0);
371 static int buspirate_quit(void)
373 LOG_INFO("Shutting down buspirate.");
375 buspirate_jtag_set_mode(buspirate_fd
, MODE_HIZ
);
376 buspirate_jtag_set_speed(buspirate_fd
, SERIAL_NORMAL
);
379 buspirate_jtag_reset(buspirate_fd
);
381 buspirate_serial_close(buspirate_fd
);
383 if (buspirate_port
) {
384 free(buspirate_port
);
385 buspirate_port
= NULL
;
388 if (NULL
!= swd_cmd_queue
)
394 /* openocd command interface */
395 COMMAND_HANDLER(buspirate_handle_adc_command
)
397 if (buspirate_fd
== -1)
400 /* send the command */
401 buspirate_jtag_get_adcs(buspirate_fd
);
407 COMMAND_HANDLER(buspirate_handle_vreg_command
)
410 return ERROR_COMMAND_SYNTAX_ERROR
;
412 if (atoi(CMD_ARGV
[0]) == 1)
414 else if (atoi(CMD_ARGV
[0]) == 0)
417 LOG_ERROR("usage: buspirate_vreg <1|0>");
423 COMMAND_HANDLER(buspirate_handle_pullup_command
)
426 return ERROR_COMMAND_SYNTAX_ERROR
;
428 if (atoi(CMD_ARGV
[0]) == 1)
429 buspirate_pullup
= 1;
430 else if (atoi(CMD_ARGV
[0]) == 0)
431 buspirate_pullup
= 0;
433 LOG_ERROR("usage: buspirate_pullup <1|0>");
439 COMMAND_HANDLER(buspirate_handle_led_command
)
442 return ERROR_COMMAND_SYNTAX_ERROR
;
444 if (atoi(CMD_ARGV
[0]) == 1) {
446 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_LED
,
448 } else if (atoi(CMD_ARGV
[0]) == 0) {
450 buspirate_jtag_set_feature(buspirate_fd
, FEATURE_LED
,
453 LOG_ERROR("usage: buspirate_led <1|0>");
460 COMMAND_HANDLER(buspirate_handle_mode_command
)
463 return ERROR_COMMAND_SYNTAX_ERROR
;
465 if (CMD_ARGV
[0][0] == 'n')
466 buspirate_pinmode
= MODE_JTAG
;
467 else if (CMD_ARGV
[0][0] == 'o')
468 buspirate_pinmode
= MODE_JTAG_OD
;
470 LOG_ERROR("usage: buspirate_mode <normal|open-drain>");
476 COMMAND_HANDLER(buspirate_handle_speed_command
)
479 return ERROR_COMMAND_SYNTAX_ERROR
;
481 if (CMD_ARGV
[0][0] == 'n')
482 buspirate_baudrate
= SERIAL_NORMAL
;
483 else if (CMD_ARGV
[0][0] == 'f')
484 buspirate_baudrate
= SERIAL_FAST
;
486 LOG_ERROR("usage: buspirate_speed <normal|fast>");
492 COMMAND_HANDLER(buspirate_handle_port_command
)
495 return ERROR_COMMAND_SYNTAX_ERROR
;
497 if (buspirate_port
== NULL
)
498 buspirate_port
= strdup(CMD_ARGV
[0]);
504 /* all commands except buspirate_port won't work in SWD mode */
505 static const struct command_registration buspirate_command_handlers
[] = {
507 .name
= "buspirate_adc",
508 .handler
= &buspirate_handle_adc_command
,
509 .mode
= COMMAND_EXEC
,
510 .help
= "reads voltages on adc pins",
513 .name
= "buspirate_vreg",
515 .handler
= &buspirate_handle_vreg_command
,
516 .mode
= COMMAND_CONFIG
,
517 .help
= "changes the state of voltage regulators",
520 .name
= "buspirate_pullup",
522 .handler
= &buspirate_handle_pullup_command
,
523 .mode
= COMMAND_CONFIG
,
524 .help
= "changes the state of pullup",
527 .name
= "buspirate_led",
529 .handler
= &buspirate_handle_led_command
,
530 .mode
= COMMAND_EXEC
,
531 .help
= "changes the state of led",
534 .name
= "buspirate_speed",
535 .usage
= "<normal|fast>",
536 .handler
= &buspirate_handle_speed_command
,
537 .mode
= COMMAND_CONFIG
,
538 .help
= "speed of the interface",
541 .name
= "buspirate_mode",
542 .usage
= "<normal|open-drain>",
543 .handler
= &buspirate_handle_mode_command
,
544 .mode
= COMMAND_CONFIG
,
545 .help
= "pin mode of the interface",
548 .name
= "buspirate_port",
549 .usage
= "/dev/ttyUSB0",
550 .handler
= &buspirate_handle_port_command
,
551 .mode
= COMMAND_CONFIG
,
552 .help
= "name of the serial port to open",
554 COMMAND_REGISTRATION_DONE
557 static int buspirate_swd_init(void)
559 LOG_INFO("Buspirate SWD mode enabled");
562 swd_cmd_queue_alloced
= 10;
563 swd_cmd_queue
= malloc(swd_cmd_queue_alloced
* sizeof(*swd_cmd_queue
));
565 return swd_cmd_queue
!= NULL
? ERROR_OK
: ERROR_FAIL
;
568 static int buspirate_swd_switch_seq(struct adiv5_dap
*dap
, enum swd_special_seq seq
)
570 const uint8_t *sequence
;
576 LOG_DEBUG("SWD line reset");
577 sequence
= swd_seq_line_reset
;
578 sequence_len
= DIV_ROUND_UP(swd_seq_line_reset_len
, 8);
581 LOG_DEBUG("JTAG-to-SWD");
582 sequence
= swd_seq_jtag_to_swd
;
583 sequence_len
= DIV_ROUND_UP(swd_seq_jtag_to_swd_len
, 8);
586 LOG_DEBUG("SWD-to-JTAG");
587 sequence
= swd_seq_swd_to_jtag
;
588 sequence_len
= DIV_ROUND_UP(swd_seq_swd_to_jtag_len
, 8);
591 LOG_ERROR("Sequence %d not supported", seq
);
595 /* FIXME: all above sequences fit into one pirate command for now
596 * but it may cause trouble later
599 tmp
[0] = 0x10 + ((sequence_len
- 1) & 0x0F);
600 memcpy(tmp
+ 1, sequence
, sequence_len
);
602 buspirate_serial_write(buspirate_fd
, tmp
, sequence_len
+ 1);
603 buspirate_serial_read(buspirate_fd
, tmp
, sequence_len
+ 1);
608 static void buspirate_swd_queue_cmd(struct adiv5_dap
*dap
, uint8_t cmd
, uint32_t *dst
, uint32_t data
)
610 if (swd_cmd_queue_length
>= swd_cmd_queue_alloced
) {
611 /* Not enough room in the queue. Run the queue and increase its size for next time.
612 * Note that it's not possible to avoid running the queue here, because mpsse contains
613 * pointers into the queue which may be invalid after the realloc. */
614 queued_retval
= buspirate_swd_run_queue(dap
);
615 struct swd_cmd_queue_entry
*q
= realloc(swd_cmd_queue
, swd_cmd_queue_alloced
* 2 * sizeof(*swd_cmd_queue
));
618 swd_cmd_queue_alloced
*= 2;
619 LOG_DEBUG("Increased SWD command queue to %zu elements", swd_cmd_queue_alloced
);
623 if (queued_retval
!= ERROR_OK
)
626 size_t i
= swd_cmd_queue_length
++;
627 swd_cmd_queue
[i
].cmd
= cmd
| SWD_CMD_START
| SWD_CMD_PARK
;
629 if (swd_cmd_queue
[i
].cmd
& SWD_CMD_RnW
) {
630 /* Queue a read transaction */
631 swd_cmd_queue
[i
].dst
= dst
;
633 /* Queue a write transaction */
634 swd_cmd_queue
[i
].data
= data
;
635 swd_cmd_queue
[i
].parity
= parity_u32(data
) ? 0x01 : 0x00;
639 static void buspirate_swd_read_reg(struct adiv5_dap
*dap
, uint8_t cmd
, uint32_t *value
)
641 assert(cmd
& SWD_CMD_RnW
);
642 buspirate_swd_queue_cmd(dap
, cmd
, value
, 0);
645 static void buspirate_swd_write_reg(struct adiv5_dap
*dap
, uint8_t cmd
, uint32_t value
)
647 assert(!(cmd
& SWD_CMD_RnW
));
648 buspirate_swd_queue_cmd(dap
, cmd
, NULL
, value
);
651 static void buspirate_swd_idle_bytes(uint8_t count
)
655 tmp
[0] = 0x10 + ((count
- 1) & 0x0F);
656 memset(tmp
+ 1, 0x00, sizeof(tmp
) - 1);
658 buspirate_serial_write(buspirate_fd
, tmp
, count
+ 1);
659 buspirate_serial_read(buspirate_fd
, tmp
, count
+ 1);
662 static int buspirate_run_cmd(struct adiv5_dap
*dap
, size_t queue_item
)
667 tmp
[0] = 0x10; /* bus pirate: send 1 byte */
668 tmp
[1] = swd_cmd_queue
[queue_item
].cmd
; /* swd cmd */
669 tmp
[2] = 0x07; /* ack __x */
670 tmp
[3] = 0x07; /* ack _x_ */
671 tmp
[4] = 0x07; /* ack x__ */
672 tmp
[5] = 0x07; /* write mode trn_1 */
673 tmp
[6] = 0x07; /* write mode trn_2 */
675 to_send
= (((swd_cmd_queue
[queue_item
].cmd
& SWD_CMD_RnW
) == 0) ? 7 : 5);
676 buspirate_serial_write(buspirate_fd
, tmp
, to_send
);
679 buspirate_serial_read(buspirate_fd
, tmp
, 2); /* drop pirate command ret vals */
680 buspirate_serial_read(buspirate_fd
, tmp
, to_send
- 2); /* ack bits */
682 swd_cmd_queue
[queue_item
].ack
= tmp
[2] << 2 | tmp
[1] << 1 | tmp
[0];
684 if (swd_cmd_queue
[queue_item
].cmd
& SWD_CMD_RnW
) {
685 /* do a read transaction */
686 tmp
[0] = 0x06; /* 4 data bytes */
690 tmp
[4] = 0x07; /* parity bit */
691 tmp
[5] = 0x21; /* 2 turnaround clocks */
693 buspirate_serial_write(buspirate_fd
, tmp
, 6);
694 buspirate_serial_read(buspirate_fd
, tmp
, 6);
696 /* store the data and parity */
697 swd_cmd_queue
[queue_item
].data
= (uint8_t) tmp
[0];
698 swd_cmd_queue
[queue_item
].data
|= (uint8_t) tmp
[1] << 8;
699 swd_cmd_queue
[queue_item
].data
|= (uint8_t) tmp
[2] << 16;
700 swd_cmd_queue
[queue_item
].data
|= (uint8_t) tmp
[3] << 24;
701 swd_cmd_queue
[queue_item
].parity
= tmp
[4] ? 0x01 : 0x00;
703 /* do a write transaction */
704 tmp
[0] = 0x10 + ((4 + 1 - 1) & 0xF); /* bus pirate: send 4+1 bytes */
705 buf_set_u32((uint8_t *) tmp
+ 1, 0, 32, swd_cmd_queue
[queue_item
].data
);
706 /* write sequence ends with parity bit and 7 idle ticks */
707 tmp
[5] = swd_cmd_queue
[queue_item
].parity
;
709 buspirate_serial_write(buspirate_fd
, tmp
, 6);
710 buspirate_serial_read(buspirate_fd
, tmp
, 6);
713 /* Insert idle cycles after AP accesses to avoid WAIT */
714 if (swd_cmd_queue
[queue_item
].cmd
& SWD_CMD_APnDP
)
715 buspirate_swd_idle_bytes(1);
720 static int buspirate_swd_run_queue(struct adiv5_dap
*dap
)
722 LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length
);
725 if (queued_retval
!= ERROR_OK
) {
726 LOG_DEBUG("Skipping due to previous errors: %d", queued_retval
);
730 /* A transaction must be followed by another transaction or at least 8 idle cycles to
731 * ensure that data is clocked through the AP. */
732 buspirate_swd_idle_bytes(1);
734 for (size_t i
= 0; i
< swd_cmd_queue_length
; i
++)
735 buspirate_run_cmd(dap
, i
);
737 for (size_t i
= 0; i
< swd_cmd_queue_length
; i
++) {
738 int ack
= swd_cmd_queue
[i
].ack
;
740 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32
,
741 ack
== SWD_ACK_OK
? "OK" : ack
== SWD_ACK_WAIT
? "WAIT" : ack
== SWD_ACK_FAULT
? "FAULT" : "JUNK",
742 swd_cmd_queue
[i
].cmd
& SWD_CMD_APnDP
? "AP" : "DP",
743 swd_cmd_queue
[i
].cmd
& SWD_CMD_RnW
? "read" : "write",
744 (swd_cmd_queue
[i
].cmd
& SWD_CMD_A32
) >> 1,
745 swd_cmd_queue
[i
].data
);
747 if (ack
!= SWD_ACK_OK
) {
748 queued_retval
= ack
== SWD_ACK_WAIT
? ERROR_WAIT
: ERROR_FAIL
;
751 } else if (swd_cmd_queue
[i
].cmd
& SWD_CMD_RnW
) {
752 uint32_t data
= swd_cmd_queue
[i
].data
;
753 int parity
= swd_cmd_queue
[i
].parity
;
755 if (parity
!= parity_u32(data
)) {
756 LOG_ERROR("SWD Read data parity mismatch %x %x", parity
, parity_u32(data
));
757 queued_retval
= ERROR_FAIL
;
761 if (swd_cmd_queue
[i
].dst
!= NULL
)
762 *swd_cmd_queue
[i
].dst
= data
;
767 swd_cmd_queue_length
= 0;
768 retval
= queued_retval
;
769 queued_retval
= ERROR_OK
;
774 static const struct swd_driver buspirate_swd
= {
775 .init
= buspirate_swd_init
,
776 .switch_seq
= buspirate_swd_switch_seq
,
777 .read_reg
= buspirate_swd_read_reg
,
778 .write_reg
= buspirate_swd_write_reg
,
779 .run
= buspirate_swd_run_queue
,
782 static const char * const buspirate_transports
[] = { "jtag", "swd", NULL
};
784 struct jtag_interface buspirate_interface
= {
786 .execute_queue
= buspirate_execute_queue
,
787 .commands
= buspirate_command_handlers
,
788 .transports
= buspirate_transports
,
789 .swd
= &buspirate_swd
,
791 .init
= buspirate_init
,
792 .quit
= buspirate_quit
795 /*************** jtag execute commands **********************/
796 static void buspirate_end_state(tap_state_t state
)
798 if (tap_is_state_stable(state
))
799 tap_set_end_state(state
);
801 LOG_ERROR("BUG: %i is not a valid end state", state
);
806 static void buspirate_state_move(void)
809 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
810 tap_get_end_state());
811 int tms_count
= tap_get_tms_path_len(tap_get_state(),
812 tap_get_end_state());
814 for (i
= 0; i
< tms_count
; i
++) {
815 tms
= (tms_scan
>> i
) & 1;
816 buspirate_tap_append(tms
, 0);
819 tap_set_state(tap_get_end_state());
822 static void buspirate_path_move(int num_states
, tap_state_t
*path
)
826 for (i
= 0; i
< num_states
; i
++) {
827 if (tap_state_transition(tap_get_state(), false) == path
[i
]) {
828 buspirate_tap_append(0, 0);
829 } else if (tap_state_transition(tap_get_state(), true)
831 buspirate_tap_append(1, 0);
833 LOG_ERROR("BUG: %s -> %s isn't a valid "
835 tap_state_name(tap_get_state()),
836 tap_state_name(path
[i
]));
840 tap_set_state(path
[i
]);
843 tap_set_end_state(tap_get_state());
846 static void buspirate_runtest(int num_cycles
)
850 tap_state_t saved_end_state
= tap_get_end_state();
852 /* only do a state_move when we're not already in IDLE */
853 if (tap_get_state() != TAP_IDLE
) {
854 buspirate_end_state(TAP_IDLE
);
855 buspirate_state_move();
858 for (i
= 0; i
< num_cycles
; i
++)
859 buspirate_tap_append(0, 0);
861 DEBUG_JTAG_IO("runtest: cur_state %s end_state %s",
862 tap_state_name(tap_get_state()),
863 tap_state_name(tap_get_end_state()));
865 /* finish in end_state */
866 buspirate_end_state(saved_end_state
);
867 if (tap_get_state() != tap_get_end_state())
868 buspirate_state_move();
871 static void buspirate_scan(bool ir_scan
, enum scan_type type
,
872 uint8_t *buffer
, int scan_size
, struct scan_command
*command
)
874 tap_state_t saved_end_state
;
876 buspirate_tap_make_space(1, scan_size
+8);
877 /* is 8 correct ? (2 moves = 16) */
879 saved_end_state
= tap_get_end_state();
881 buspirate_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
883 /* Only move if we're not already there */
884 if (tap_get_state() != tap_get_end_state())
885 buspirate_state_move();
887 buspirate_tap_append_scan(scan_size
, buffer
, command
);
890 buspirate_tap_append(0, 0);
892 /* restore the saved state */
893 buspirate_end_state(saved_end_state
);
894 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
896 if (tap_get_state() != tap_get_end_state())
897 buspirate_state_move();
901 /************************* TAP related stuff **********/
903 /* This buffer size matches the maximum CMD_TAP_SHIFT bit length in the Bus Pirate firmware,
904 look for constant 0x2000 in OpenOCD.c . */
905 #define BUSPIRATE_BUFFER_SIZE 1024
907 /* The old value of 32 scans was not enough to achieve near 100% utilisation ratio
908 for the current BUSPIRATE_BUFFER_SIZE value of 1024.
909 With 128 scans I am getting full USB 2.0 high speed packets (512 bytes long) when
910 using the JtagDue firmware on the Arduino Due instead of the Bus Pirate, which
911 amounts approximately to a 10% overall speed gain. Bigger packets should also
912 benefit the Bus Pirate, but the speed difference is much smaller.
913 Unfortunately, each 512-byte packet is followed by a 329-byte one, which is not ideal.
914 However, increasing BUSPIRATE_BUFFER_SIZE for the benefit of the JtagDue would
915 make it incompatible with the Bus Pirate firmware. */
916 #define BUSPIRATE_MAX_PENDING_SCANS 128
918 static char tms_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
919 static char tdi_chain
[BUSPIRATE_BUFFER_SIZE
]; /* send */
920 static int tap_chain_index
;
922 struct pending_scan_result
/* this was stolen from arm-jtag-ew */
924 int first
; /* First bit position in tdo_buffer to read */
925 int length
; /* Number of bits to read */
926 struct scan_command
*command
; /* Corresponding scan command */
930 static struct pending_scan_result
931 tap_pending_scans
[BUSPIRATE_MAX_PENDING_SCANS
];
932 static int tap_pending_scans_num
;
934 static void buspirate_tap_init(void)
937 tap_pending_scans_num
= 0;
940 static int buspirate_tap_execute(void)
942 static const int CMD_TAP_SHIFT_HEADER_LEN
= 3;
951 if (tap_chain_index
<= 0)
954 LOG_DEBUG("executing tap num bits = %i scans = %i",
955 tap_chain_index
, tap_pending_scans_num
);
957 bytes_to_send
= DIV_ROUND_UP(tap_chain_index
, 8);
959 tmp
[0] = CMD_TAP_SHIFT
; /* this command expects number of bits */
960 tmp
[1] = (char)(tap_chain_index
>> 8); /* high */
961 tmp
[2] = (char)(tap_chain_index
); /* low */
963 fill_index
= CMD_TAP_SHIFT_HEADER_LEN
;
964 for (i
= 0; i
< bytes_to_send
; i
++) {
965 tmp
[fill_index
] = tdi_chain
[i
];
967 tmp
[fill_index
] = tms_chain
[i
];
971 /* jlink.c calls the routine below, which may be useful for debugging purposes.
972 For example, enabling this allows you to compare the log outputs from jlink.c
973 and from this module for JTAG development or troubleshooting purposes. */
975 last_tap_state
= jtag_debug_state_machine(tms_chain
, tdi_chain
,
976 tap_chain_index
, last_tap_state
);
979 ret
= buspirate_serial_write(buspirate_fd
, tmp
, CMD_TAP_SHIFT_HEADER_LEN
+ bytes_to_send
*2);
980 if (ret
!= bytes_to_send
*2+CMD_TAP_SHIFT_HEADER_LEN
) {
981 LOG_ERROR("error writing :(");
982 return ERROR_JTAG_DEVICE_ERROR
;
985 ret
= buspirate_serial_read(buspirate_fd
, tmp
, bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
);
986 if (ret
!= bytes_to_send
+ CMD_TAP_SHIFT_HEADER_LEN
) {
987 LOG_ERROR("error reading");
990 in_buf
= (uint8_t *)(&tmp
[CMD_TAP_SHIFT_HEADER_LEN
]);
992 /* parse the scans */
993 for (i
= 0; i
< tap_pending_scans_num
; i
++) {
994 uint8_t *buffer
= tap_pending_scans
[i
].buffer
;
995 int length
= tap_pending_scans
[i
].length
;
996 int first
= tap_pending_scans
[i
].first
;
997 struct scan_command
*command
= tap_pending_scans
[i
].command
;
999 /* copy bits from buffer */
1000 buf_set_buf(in_buf
, first
, buffer
, 0, length
);
1002 /* return buffer to higher level */
1003 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
) {
1004 buspirate_tap_init();
1005 return ERROR_JTAG_QUEUE_FAILED
;
1010 buspirate_tap_init();
1014 static void buspirate_tap_make_space(int scans
, int bits
)
1016 int have_scans
= BUSPIRATE_MAX_PENDING_SCANS
- tap_pending_scans_num
;
1017 int have_bits
= BUSPIRATE_BUFFER_SIZE
* 8 - tap_chain_index
;
1019 if ((have_scans
< scans
) || (have_bits
< bits
))
1020 buspirate_tap_execute();
1023 static void buspirate_tap_append(int tms
, int tdi
)
1027 buspirate_tap_make_space(0, 1);
1028 chain_index
= tap_chain_index
/ 8;
1030 if (chain_index
< BUSPIRATE_BUFFER_SIZE
) {
1031 int bit_index
= tap_chain_index
% 8;
1032 uint8_t bit
= 1 << bit_index
;
1034 if (0 == bit_index
) {
1035 /* Let's say that the TAP shift operation wants to shift 9 bits,
1036 so we will be sending to the Bus Pirate a bit count of 9 but still
1037 full 16 bits (2 bytes) of shift data.
1038 If we don't clear all bits at this point, the last 7 bits will contain
1039 random data from the last buffer contents, which is not pleasant to the eye.
1040 Besides, the Bus Pirate (or some clone) may want to assert in debug builds
1041 that, after consuming all significant data bits, the rest of them are zero.
1042 Therefore, for aesthetic and for assert purposes, we clear all bits below. */
1043 tms_chain
[chain_index
] = 0;
1044 tdi_chain
[chain_index
] = 0;
1048 tms_chain
[chain_index
] |= bit
;
1050 tms_chain
[chain_index
] &= ~bit
;
1053 tdi_chain
[chain_index
] |= bit
;
1055 tdi_chain
[chain_index
] &= ~bit
;
1059 LOG_ERROR("tap_chain overflow, bad things will happen");
1060 /* Exit abruptly, like jlink.c does. After a buffer overflow we don't want
1061 to carry on, as data will be corrupt. Another option would be to return
1062 some error code at this point. */
1067 static void buspirate_tap_append_scan(int length
, uint8_t *buffer
,
1068 struct scan_command
*command
)
1071 tap_pending_scans
[tap_pending_scans_num
].length
= length
;
1072 tap_pending_scans
[tap_pending_scans_num
].buffer
= buffer
;
1073 tap_pending_scans
[tap_pending_scans_num
].command
= command
;
1074 tap_pending_scans
[tap_pending_scans_num
].first
= tap_chain_index
;
1076 for (i
= 0; i
< length
; i
++) {
1077 int tms
= (i
< length
-1 ? 0 : 1);
1078 int tdi
= (buffer
[i
/8] >> (i
%8)) & 1;
1079 buspirate_tap_append(tms
, tdi
);
1081 tap_pending_scans_num
++;
1084 /*************** jtag wrapper functions *********************/
1086 /* (1) assert or (0) deassert reset lines */
1087 static void buspirate_reset(int trst
, int srst
)
1089 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
1091 /* trst is not available in SWD mode */
1094 buspirate_jtag_set_feature(buspirate_fd
,
1095 FEATURE_TRST
, ACTION_DISABLE
);
1097 buspirate_jtag_set_feature(buspirate_fd
,
1098 FEATURE_TRST
, ACTION_ENABLE
);
1102 buspirate_jtag_set_feature(buspirate_fd
,
1103 FEATURE_SRST
, ACTION_DISABLE
);
1105 buspirate_jtag_set_feature(buspirate_fd
,
1106 FEATURE_SRST
, ACTION_ENABLE
);
1109 /*************** jtag lowlevel functions ********************/
1110 static void buspirate_bbio_enable(int fd
)
1114 const char *mode_answers
[2] = { "OCD1", "RAW1" };
1115 const char *correct_ans
= NULL
;
1116 char tmp
[21] = { [0 ... 20] = 0x00 };
1121 command
= CMD_ENTER_RWIRE
;
1122 correct_ans
= mode_answers
[1];
1124 command
= CMD_ENTER_OOCD
;
1125 correct_ans
= mode_answers
[0];
1128 LOG_DEBUG("Entering binary mode, that is %s", correct_ans
);
1129 buspirate_serial_write(fd
, tmp
, 20);
1132 /* reads 1 to n "BBIO1"s and one "OCD1" or "RAW1" */
1134 ret
= buspirate_serial_read(fd
, tmp
, 4);
1136 LOG_ERROR("Buspirate error. Is binary"
1137 "/OpenOCD support enabled?");
1140 if (strncmp(tmp
, "BBIO", 4) == 0) {
1141 ret
= buspirate_serial_read(fd
, tmp
, 1);
1143 LOG_ERROR("Buspirate did not answer correctly! "
1144 "Do you have correct firmware?");
1147 if (tmp
[0] != '1') {
1148 LOG_ERROR("Unsupported binary protocol");
1151 if (cmd_sent
== 0) {
1154 ret
= buspirate_serial_write(fd
, tmp
, 1);
1156 LOG_ERROR("error reading");
1160 } else if (strncmp(tmp
, correct_ans
, 4) == 0)
1163 LOG_ERROR("Buspirate did not answer correctly! "
1164 "Do you have correct firmware?");
1171 static void buspirate_jtag_reset(int fd
)
1175 tmp
[0] = 0x00; /* exit binary mode */
1176 buspirate_serial_write(fd
, tmp
, 1);
1178 /* We ignore the return value here purposly, nothing we can do */
1179 buspirate_serial_read(fd
, tmp
, 5);
1180 if (strncmp(tmp
, "BBIO1", 5) == 0) {
1181 tmp
[0] = 0x0F; /* reset BP */
1182 buspirate_serial_write(fd
, tmp
, 1);
1184 LOG_ERROR("Unable to restart buspirate!");
1187 static void buspirate_swd_set_params(int fd
)
1192 /* raw-wire mode configuration */
1193 tmp
[0] = CMD_RAW_CONFIG
| CMD_RAW_CONFIG_3V3
| CMD_RAW_CONFIG_LSB
;
1194 buspirate_serial_write(fd
, tmp
, 1);
1195 ret
= buspirate_serial_read(fd
, tmp
, 1);
1197 LOG_ERROR("Buspirate did not answer correctly");
1201 LOG_ERROR("Buspirate did not reply as expected to the configure command");
1205 /* speed settings */
1206 tmp
[0] = CMD_RAW_SPEED
| SPEED_RAW_400_KHZ
;
1207 buspirate_serial_write(fd
, tmp
, 1);
1208 ret
= buspirate_serial_read(fd
, tmp
, 1);
1210 LOG_ERROR("Buspirate did not answer correctly");
1214 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
1217 LOG_INFO("Buspirate two-wire mode configured correctly");
1220 static char *buspirate_feature_to_txt(char feat
)
1222 /* simple enum to human-readable text converter */
1225 return "buspirate_led";
1231 return "buspirate_vreg";
1232 case FEATURE_PULLUP
:
1233 return "buspirate_pullup";
1235 return "<unrecognized>";
1239 static void buspirate_swd_set_feature(int fd
, char feat
, char action
)
1242 bool f_enable
= (action
== ACTION_ENABLE
) ? true : false;
1245 new_config
= swd_feature_config
;
1250 new_config
|= SWD_FEATURE_VREG
;
1252 new_config
&= ~SWD_FEATURE_VREG
;
1256 new_config
|= SWD_FEATURE_SRST
;
1258 new_config
&= ~SWD_FEATURE_SRST
;
1260 case FEATURE_PULLUP
:
1262 new_config
|= SWD_FEATURE_PULLUP
;
1264 new_config
&= ~SWD_FEATURE_PULLUP
;
1267 LOG_ERROR("Buspirate feature %s is not available in SWD mode",
1268 buspirate_feature_to_txt(feat
));
1272 tmp
[0] = CMD_RAW_FEATURE
| new_config
;
1273 buspirate_serial_write(fd
, tmp
, 1);
1274 buspirate_serial_read(fd
, tmp
, 1);
1276 if (0x01 != tmp
[0]) {
1277 LOG_ERROR("Buspirate was unable to set feature %s",
1278 buspirate_feature_to_txt(feat
));
1282 swd_feature_config
= new_config
;
1285 static void buspirate_jtag_set_speed(int fd
, char speed
)
1294 tmp
[0] = CMD_UART_SPEED
;
1296 buspirate_jtag_command(fd
, tmp
, 2);
1298 /* here the adapter changes speed, we need follow */
1299 if (-1 == buspirate_serial_setspeed(fd
, speed
, NORMAL_TIMEOUT
)) {
1300 LOG_ERROR("Error configuring the serial port.");
1304 buspirate_serial_write(fd
, ack
, 2);
1305 ret
= buspirate_serial_read(fd
, tmp
, 2);
1307 LOG_ERROR("Buspirate did not ack speed change");
1310 if ((tmp
[0] != CMD_UART_SPEED
) || (tmp
[1] != speed
)) {
1311 LOG_ERROR("Buspirate did not reply as expected to the speed change command");
1314 LOG_INFO("Buspirate switched to %s mode",
1315 (speed
== SERIAL_NORMAL
) ? "normal" : "FAST");
1319 static void buspirate_jtag_set_mode(int fd
, char mode
)
1322 tmp
[0] = CMD_PORT_MODE
;
1324 buspirate_jtag_command(fd
, tmp
, 2);
1327 static void buspirate_jtag_set_feature(int fd
, char feat
, char action
)
1332 buspirate_swd_set_feature(fd
, feat
, action
);
1336 tmp
[0] = CMD_FEATURE
;
1337 tmp
[1] = feat
; /* what */
1338 tmp
[2] = action
; /* action */
1339 buspirate_jtag_command(fd
, tmp
, 3);
1342 static void buspirate_jtag_get_adcs(int fd
)
1345 uint16_t a
, b
, c
, d
;
1346 tmp
[0] = CMD_READ_ADCS
;
1347 buspirate_jtag_command(fd
, (char *)tmp
, 1);
1348 a
= tmp
[2] << 8 | tmp
[3];
1349 b
= tmp
[4] << 8 | tmp
[5];
1350 c
= tmp
[6] << 8 | tmp
[7];
1351 d
= tmp
[8] << 8 | tmp
[9];
1353 LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f "
1355 ((float)a
)/155.1515, ((float)b
)/155.1515,
1356 ((float)c
)/155.1515, ((float)d
)/155.1515);
1359 static unsigned char buspirate_jtag_command(int fd
,
1360 char *cmd
, int cmdlen
)
1365 res
= buspirate_serial_write(fd
, cmd
, cmdlen
);
1367 if ((cmd
[0] == CMD_UART_SPEED
)
1368 || (cmd
[0] == CMD_PORT_MODE
)
1369 || (cmd
[0] == CMD_FEATURE
)
1370 || (cmd
[0] == CMD_JTAG_SPEED
))
1373 if (res
== cmdlen
) {
1376 len
= 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */
1382 LOG_INFO("Wrong !");
1384 res
= buspirate_serial_read(fd
, cmd
, len
);
1386 return (unsigned char)cmd
[1];
1394 /* low level serial port */
1395 /* TODO add support for WIN32 and others ! */
1396 static int buspirate_serial_open(char *port
)
1399 fd
= open(buspirate_port
, O_RDWR
| O_NOCTTY
| O_NDELAY
);
1404 /* Returns -1 on error. */
1406 static int buspirate_serial_setspeed(int fd
, char speed
, cc_t timeout
)
1408 struct termios t_opt
;
1409 speed_t baud
= (speed
== SERIAL_FAST
) ? B1000000
: B115200
;
1411 /* set the serial port parameters */
1412 fcntl(fd
, F_SETFL
, 0);
1413 if (0 != tcgetattr(fd
, &t_opt
))
1416 if (0 != cfsetispeed(&t_opt
, baud
))
1419 if (0 != cfsetospeed(&t_opt
, baud
))
1422 t_opt
.c_cflag
|= (CLOCAL
| CREAD
);
1423 t_opt
.c_cflag
&= ~PARENB
;
1424 t_opt
.c_cflag
&= ~CSTOPB
;
1425 t_opt
.c_cflag
&= ~CSIZE
;
1426 t_opt
.c_cflag
|= CS8
;
1427 t_opt
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
);
1429 /* The serial port may have been configured for human interaction with
1430 the Bus Pirate console, but OpenOCD is going to use a binary protocol,
1431 so make sure to turn off any CR/LF translation and the like. */
1432 t_opt
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
| INLCR
| ICRNL
);
1434 t_opt
.c_oflag
&= ~OPOST
;
1435 t_opt
.c_cc
[VMIN
] = 0;
1436 t_opt
.c_cc
[VTIME
] = timeout
;
1438 /* Note that, in the past, TCSANOW was used below instead of TCSADRAIN,
1439 and CMD_UART_SPEED did not work properly then, at least with
1440 the Bus Pirate v3.5 (USB). */
1441 if (0 != tcsetattr(fd
, TCSADRAIN
, &t_opt
)) {
1442 /* According to the Linux documentation, this is actually not enough
1443 to detect errors, you need to call tcgetattr() and check that
1444 all changes have been performed successfully. */
1451 static int buspirate_serial_write(int fd
, char *buf
, int size
)
1455 ret
= write(fd
, buf
, size
);
1457 LOG_DEBUG("size = %d ret = %d", size
, ret
);
1458 buspirate_print_buffer(buf
, size
);
1461 LOG_ERROR("Error sending data");
1466 static int buspirate_serial_read(int fd
, char *buf
, int size
)
1472 while (len
< size
) {
1473 ret
= read(fd
, buf
+len
, size
-len
);
1489 LOG_DEBUG("should have read = %d actual size = %d", size
, len
);
1490 buspirate_print_buffer(buf
, len
);
1493 LOG_ERROR("Error reading data");
1498 static void buspirate_serial_close(int fd
)
1503 #define LINE_SIZE 81
1504 #define BYTES_PER_LINE 16
1505 static void buspirate_print_buffer(char *buf
, int size
)
1507 char line
[LINE_SIZE
];
1512 while (offset
< size
) {
1513 snprintf(tmp
, 5, "%02x ", (uint8_t)buf
[offset
]);
1518 if (offset
% BYTES_PER_LINE
== 0) {
1519 LOG_DEBUG("%s", line
);
1525 LOG_DEBUG("%s", line
);
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)