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

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)