7e843901fe7fbdf0bf2afe708285488c9eafeb22
[openocd.git] / src / jtag / usbprog.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Benedikt Sauter *
3 * sauter@ixbat.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 /*
22 * This file is based on Dominic Rath's amt_jtagaccel.c.
23 *
24 * usbprog is a free programming adapter. You can easily install
25 * different firmware versions from an "online pool" over USB.
26 * The adapter can be used for programming and debugging AVR and ARM
27 * processors, as USB to RS232 converter, as JTAG interface or as
28 * simple I/O interface (5 lines).
29 *
30 * http://www.embedded-projects.net/usbprog
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #define INCLUDE_JTAG_INTERFACE_H
38 #include "jtag.h"
39
40 #include <usb.h>
41
42
43 #define VID 0x1781
44 #define PID 0x0c63
45
46 /* Pins at usbprog */
47 #define TDO_BIT 0
48 #define TDI_BIT 3
49 #define TCK_BIT 2
50 #define TMS_BIT 1
51
52 static int usbprog_execute_queue(void);
53 static int usbprog_speed(int speed);
54 static int usbprog_register_commands(struct command_context_s *cmd_ctx);
55 static int usbprog_init(void);
56 static int usbprog_quit(void);
57
58 static void usbprog_end_state(tap_state_t state);
59 static void usbprog_state_move(void);
60 static void usbprog_path_move(pathmove_command_t *cmd);
61 static void usbprog_runtest(int num_cycles);
62 static void usbprog_scan(bool ir_scan, enum scan_type type, u8 *buffer, int scan_size);
63
64 jtag_interface_t usbprog_interface =
65 {
66 .name = "usbprog",
67 .execute_queue = usbprog_execute_queue,
68 .speed = usbprog_speed,
69 .register_commands = usbprog_register_commands,
70 .init = usbprog_init,
71 .quit = usbprog_quit
72 };
73
74 #define UNKOWN_COMMAND 0x00
75 #define PORT_DIRECTION 0x01
76 #define PORT_SET 0x02
77 #define PORT_GET 0x03
78 #define PORT_SETBIT 0x04
79 #define PORT_GETBIT 0x05
80 #define WRITE_TDI 0x06
81 #define READ_TDO 0x07
82 #define WRITE_AND_READ 0x08
83 #define WRITE_TMS 0x09
84 #define WRITE_TMS_CHAIN 0x0A
85
86 struct usbprog_jtag
87 {
88 struct usb_dev_handle* usb_handle;
89 };
90
91 static struct usbprog_jtag * usbprog_jtag_handle;
92
93 static struct usbprog_jtag* usbprog_jtag_open(void);
94 //static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag);
95 static void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag);
96 static unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen);
97
98 static void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
99 static void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
100 static void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
101 static void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan);
102
103 static char tms_chain[64];
104 static int tms_chain_index;
105
106 static void usbprog_jtag_tms_collect(char tms_scan);
107 static void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag);
108
109 static void usbprog_write(int tck, int tms, int tdi);
110 static void usbprog_reset(int trst, int srst);
111
112 static void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction);
113 static void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag,unsigned char value);
114 //static unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag);
115 static void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag,int bit, int value);
116 //static int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit);
117
118 static int usbprog_speed(int speed)
119 {
120 return ERROR_OK;
121 }
122
123 static int usbprog_register_commands(struct command_context_s *cmd_ctx)
124 {
125 return ERROR_OK;
126 }
127
128 static int usbprog_execute_queue(void)
129 {
130 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
131 int scan_size;
132 enum scan_type type;
133 u8 *buffer;
134
135 while (cmd)
136 {
137 switch (cmd->type)
138 {
139 case JTAG_RESET:
140 #ifdef _DEBUG_JTAG_IO_
141 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
142 #endif
143 if (cmd->cmd.reset->trst == 1)
144 {
145 tap_set_state(TAP_RESET);
146 }
147 usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
148 break;
149 case JTAG_RUNTEST:
150 #ifdef _DEBUG_JTAG_IO_
151 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
152 #endif
153 if (cmd->cmd.runtest->end_state != TAP_INVALID)
154 usbprog_end_state(cmd->cmd.runtest->end_state);
155 usbprog_runtest(cmd->cmd.runtest->num_cycles);
156 break;
157 case JTAG_STATEMOVE:
158 #ifdef _DEBUG_JTAG_IO_
159 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
160 #endif
161 if (cmd->cmd.statemove->end_state != TAP_INVALID)
162 usbprog_end_state(cmd->cmd.statemove->end_state);
163 usbprog_state_move();
164 break;
165 case JTAG_PATHMOVE:
166 #ifdef _DEBUG_JTAG_IO_
167 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
168 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
169 #endif
170 usbprog_path_move(cmd->cmd.pathmove);
171 break;
172 case JTAG_SCAN:
173 #ifdef _DEBUG_JTAG_IO_
174 LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
175 #endif
176 if (cmd->cmd.scan->end_state != TAP_INVALID)
177 usbprog_end_state(cmd->cmd.scan->end_state);
178 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
179 type = jtag_scan_type(cmd->cmd.scan);
180 usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
181 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
182 return ERROR_JTAG_QUEUE_FAILED;
183 if (buffer)
184 free(buffer);
185 break;
186 case JTAG_SLEEP:
187 #ifdef _DEBUG_JTAG_IO_
188 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
189 #endif
190 jtag_sleep(cmd->cmd.sleep->us);
191 break;
192 default:
193 LOG_ERROR("BUG: unknown JTAG command type encountered");
194 exit(-1);
195 }
196
197 cmd = cmd->next;
198 }
199
200 return ERROR_OK;
201 }
202
203 static int usbprog_init(void)
204 {
205 usbprog_jtag_handle = usbprog_jtag_open();
206
207 tms_chain_index = 0;
208 if (usbprog_jtag_handle == 0)
209 {
210 LOG_ERROR("Can't find USB JTAG Interface! Please check connection and permissions.");
211 return ERROR_JTAG_INIT_FAILED;
212 }
213
214 LOG_INFO("USB JTAG Interface ready!");
215
216 usbprog_jtag_init(usbprog_jtag_handle);
217 usbprog_reset(0, 0);
218 usbprog_write(0, 0, 0);
219
220 return ERROR_OK;
221 }
222
223 static int usbprog_quit(void)
224 {
225 return ERROR_OK;
226 }
227
228 /*************** jtag execute commands **********************/
229 static void usbprog_end_state(tap_state_t state)
230 {
231 if (tap_is_state_stable(state))
232 tap_set_end_state(state);
233 else
234 {
235 LOG_ERROR("BUG: %i is not a valid end state", state);
236 exit(-1);
237 }
238 }
239
240 static void usbprog_state_move(void)
241 {
242 int i = 0, tms = 0;
243 u8 tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
244 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
245
246 usbprog_jtag_write_tms(usbprog_jtag_handle, (char)tms_scan);
247 for (i = 0; i < tms_count; i++)
248 {
249 tms = (tms_scan >> i) & 1;
250 }
251
252 tap_set_state(tap_get_end_state());
253 }
254
255 static void usbprog_path_move(pathmove_command_t *cmd)
256 {
257 int num_states = cmd->num_states;
258 int state_count;
259
260 /* There may be queued transitions, and before following a specified
261 path, we must flush those queued transitions */
262 usbprog_jtag_tms_send(usbprog_jtag_handle);
263
264 state_count = 0;
265 while (num_states)
266 {
267 if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
268 {
269 /* LOG_INFO("1"); */
270 usbprog_write(0, 0, 0);
271 usbprog_write(1, 0, 0);
272 }
273 else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])
274 {
275 /* LOG_INFO("2"); */
276 usbprog_write(0, 1, 0);
277 usbprog_write(1, 1, 0);
278 }
279 else
280 {
281 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(cmd->path[state_count]));
282 exit(-1);
283 }
284
285 tap_set_state(cmd->path[state_count]);
286 state_count++;
287 num_states--;
288 }
289
290 tap_set_end_state(tap_get_state());
291 }
292
293 static void usbprog_runtest(int num_cycles)
294 {
295 int i;
296
297 /* only do a state_move when we're not already in IDLE */
298 if (tap_get_state() != TAP_IDLE)
299 {
300 usbprog_end_state(TAP_IDLE);
301 usbprog_state_move();
302 }
303
304 /* execute num_cycles */
305 if (num_cycles > 0)
306 {
307 usbprog_jtag_tms_send(usbprog_jtag_handle);
308 usbprog_write(0, 0, 0);
309 }
310 else
311 {
312 usbprog_jtag_tms_send(usbprog_jtag_handle);
313 /* LOG_INFO("NUM CYCLES %i",num_cycles); */
314 }
315
316 for (i = 0; i < num_cycles; i++)
317 {
318 usbprog_write(1, 0, 0);
319 usbprog_write(0, 0, 0);
320 }
321
322 #ifdef _DEBUG_JTAG_IO_
323 LOG_DEBUG("runtest: cur_state %s end_state %s", tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()));
324 #endif
325
326 /* finish in end_state */
327 /*
328 usbprog_end_state(saved_end_state);
329 if (tap_get_state() != tap_get_end_state())
330 usbprog_state_move();
331 */
332 }
333
334 static void usbprog_scan(bool ir_scan, enum scan_type type, u8 *buffer, int scan_size)
335 {
336 tap_state_t saved_end_state = tap_get_end_state();
337
338 if (ir_scan)
339 usbprog_end_state(TAP_IRSHIFT);
340 else
341 usbprog_end_state(TAP_DRSHIFT);
342
343 /* Only move if we're not already there */
344 if (tap_get_state() != tap_get_end_state())
345 usbprog_state_move();
346
347 usbprog_end_state(saved_end_state);
348
349 usbprog_jtag_tms_send(usbprog_jtag_handle);
350
351 void (*f)(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
352 switch (type) {
353 case SCAN_OUT: f = &usbprog_jtag_write_tdi; break;
354 case SCAN_IN: f = &usbprog_jtag_read_tdo; break;
355 case SCAN_IO: f = &usbprog_jtag_write_and_read; break;
356 default:
357 LOG_ERROR("unknown scan type: %i", type);
358 exit(-1);
359 }
360 f(usbprog_jtag_handle, (char *)buffer, scan_size);
361
362 /* The adapter does the transition to PAUSE internally */
363 if (ir_scan)
364 tap_set_state(TAP_IRPAUSE);
365 else
366 tap_set_state(TAP_DRPAUSE);
367
368 if (tap_get_state() != tap_get_end_state())
369 usbprog_state_move();
370 }
371
372 /*************** jtag wrapper functions *********************/
373
374 static void usbprog_write(int tck, int tms, int tdi)
375 {
376 unsigned char output_value=0x00;
377
378 if (tms)
379 output_value |= (1<<TMS_BIT);
380 if (tdi)
381 output_value |= (1<<TDI_BIT);
382 if (tck)
383 output_value |= (1<<TCK_BIT);
384
385 usbprog_jtag_write_slice(usbprog_jtag_handle,output_value);
386 }
387
388 /* (1) assert or (0) deassert reset lines */
389 static void usbprog_reset(int trst, int srst)
390 {
391 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
392
393 if (trst)
394 usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 0);
395 else
396 usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 1);
397
398 if (srst)
399 usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 0);
400 else
401 usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 1);
402 }
403
404 /*************** jtag lowlevel functions ********************/
405
406 struct usb_bus *busses;
407
408 struct usbprog_jtag* usbprog_jtag_open(void)
409 {
410 struct usb_bus *bus;
411 struct usb_device *dev;
412
413 struct usbprog_jtag *tmp;
414
415 tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag));
416
417 usb_set_debug(10);
418 usb_init();
419 usb_find_busses();
420 usb_find_devices();
421
422 busses = usb_get_busses();
423
424 /* find usbprog_jtag device in usb bus */
425
426 for (bus = busses; bus; bus = bus->next)
427 {
428 for (dev = bus->devices; dev; dev = dev->next)
429 {
430 /* condition for sucessfully hit (too bad, I only check the vendor id)*/
431 if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID)
432 {
433 tmp->usb_handle = usb_open(dev);
434 usb_set_configuration(tmp->usb_handle, 1);
435 usb_claim_interface(tmp->usb_handle, 0);
436 usb_set_altinterface(tmp->usb_handle, 0);
437 return tmp;
438 }
439 }
440 }
441 return 0;
442 }
443
444 #if 0
445 static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag)
446 {
447 usb_close(usbprog_jtag->usb_handle);
448 free(usbprog_jtag);
449 }
450 #endif
451
452 static unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen)
453 {
454 int res = usb_bulk_write(usbprog_jtag->usb_handle, 3, msg,msglen, 100);
455 if ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) || \
456 (msg[0] == 6) || (msg[0] == 0x0A) || (msg[0] == 9))
457 return 1;
458 if (res == msglen)
459 {
460 /* LOG_INFO("HALLLLOOO %i",(int)msg[0]); */
461 res = usb_bulk_read(usbprog_jtag->usb_handle, 0x82, msg, 2, 100);
462 if (res > 0)
463 return (unsigned char)msg[1];
464 else
465 return -1;
466 }
467 else
468 return -1;
469 return 0;
470 }
471
472 static void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag)
473 {
474 usbprog_jtag_set_direction(usbprog_jtag, 0xFE);
475 }
476
477 static void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
478 {
479 char tmp[64]; /* fastes packet size for usb controller */
480 int send_bits, bufindex = 0, fillindex = 0, i, loops;
481
482 char swap;
483 /* 61 byte can be transfered (488 bit) */
484
485 while (size > 0)
486 {
487 if (size > 488)
488 {
489 send_bits = 488;
490 size = size - 488;
491 loops = 61;
492 }
493 else
494 {
495 send_bits = size;
496 loops = size / 8;
497 loops++;
498 size = 0;
499 }
500 tmp[0] = WRITE_AND_READ;
501 tmp[1] = (char)(send_bits >> 8); /* high */
502 tmp[2] = (char)(send_bits); /* low */
503 i = 0;
504
505 for (i = 0; i < loops; i++)
506 {
507 tmp[3 + i] = buffer[bufindex];
508 bufindex++;
509 }
510
511 if (usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000) == 64)
512 {
513 /* LOG_INFO("HALLLLOOO2 %i",(int)tmp[0]); */
514 usleep(1);
515 int timeout = 0;
516 while (usb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 1000) < 1)
517 {
518 timeout++;
519 if (timeout > 10)
520 break;
521 }
522
523 for (i = 0; i < loops; i++)
524 {
525 swap = tmp[3 + i];
526 buffer[fillindex++] = swap;
527 }
528 }
529 }
530 }
531
532 static void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
533 {
534 char tmp[64]; /* fastes packet size for usb controller */
535 int send_bits, fillindex = 0, i, loops;
536
537 char swap;
538 /* 61 byte can be transfered (488 bit) */
539
540 while (size > 0)
541 {
542 if (size > 488)
543 {
544 send_bits = 488;
545 size = size - 488;
546 loops = 61;
547 }
548 else
549 {
550 send_bits = size;
551 loops = size / 8;
552 loops++;
553 size = 0;
554 }
555 tmp[0] = WRITE_AND_READ;
556 tmp[1] = (char)(send_bits >> 8); /* high */
557 tmp[2] = (char)(send_bits); /* low */
558
559 usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 3, 1000);
560
561 /* LOG_INFO("HALLLLOOO3 %i",(int)tmp[0]); */
562 int timeout = 0;
563 usleep(1);
564 while (usb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 10) < 1)
565 {
566 timeout++;
567 if (timeout > 10)
568 break;
569 }
570
571 for (i = 0; i < loops; i++)
572 {
573 swap = tmp[3 + i];
574 buffer[fillindex++] = swap;
575 }
576 }
577 }
578
579 static void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
580 {
581 char tmp[64]; /* fastes packet size for usb controller */
582 int send_bits, bufindex = 0, i, loops;
583
584 /* 61 byte can be transfered (488 bit) */
585 while (size > 0)
586 {
587 if (size > 488)
588 {
589 send_bits = 488;
590 size = size - 488;
591 loops = 61;
592 }
593 else
594 {
595 send_bits = size;
596 loops = size/8;
597 /* if(loops==0) */
598 loops++;
599 size = 0;
600 }
601 tmp[0] = WRITE_TDI;
602 tmp[1] = (char)(send_bits >> 8); /* high */
603 tmp[2] = (char)(send_bits); /* low */
604 i = 0;
605
606 for (i = 0; i < loops; i++)
607 {
608 tmp[3 + i] = buffer[bufindex];
609 bufindex++;
610 }
611 usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000);
612 }
613 }
614
615 static void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan)
616 {
617 usbprog_jtag_tms_collect(tms_scan);
618 }
619
620 static void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction)
621 {
622 char tmp[2];
623 tmp[0] = PORT_DIRECTION;
624 tmp[1] = (char)direction;
625 usbprog_jtag_message(usbprog_jtag, tmp, 2);
626 }
627
628 static void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag,unsigned char value)
629 {
630 char tmp[2];
631 tmp[0] = PORT_SET;
632 tmp[1] = (char)value;
633 usbprog_jtag_message(usbprog_jtag, tmp, 2);
634 }
635
636 #if 0
637 static unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag)
638 {
639 char tmp[2];
640 tmp[0] = PORT_GET;
641 tmp[1] = 0x00;
642 return usbprog_jtag_message(usbprog_jtag, tmp, 2);
643 }
644 #endif
645
646 static void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag,int bit, int value)
647 {
648 char tmp[3];
649 tmp[0] = PORT_SETBIT;
650 tmp[1] = (char)bit;
651 if (value == 1)
652 tmp[2] = 0x01;
653 else
654 tmp[2] = 0x00;
655 usbprog_jtag_message(usbprog_jtag, tmp, 3);
656 }
657
658 #if 0
659 static int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit)
660 {
661 char tmp[2];
662 tmp[0] = PORT_GETBIT;
663 tmp[1] = (char)bit;
664
665 if (usbprog_jtag_message(usbprog_jtag, tmp, 2) > 0)
666 return 1;
667 else
668 return 0;
669 }
670 #endif
671
672 static void usbprog_jtag_tms_collect(char tms_scan)
673 {
674 tms_chain[tms_chain_index] = tms_scan;
675 tms_chain_index++;
676 }
677
678 static void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag)
679 {
680 int i;
681 /* LOG_INFO("TMS SEND"); */
682 if (tms_chain_index > 0)
683 {
684 char tmp[tms_chain_index + 2];
685 tmp[0] = WRITE_TMS_CHAIN;
686 tmp[1] = (char)(tms_chain_index);
687 for (i = 0; i < tms_chain_index + 1; i++)
688 tmp[2 + i] = tms_chain[i];
689 usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, tms_chain_index + 2, 1000);
690 tms_chain_index = 0;
691 }
692 }

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)