zy1000: keep up with latest changes to command handling
[openocd.git] / src / jtag / zy1000 / zy1000.c
1 /***************************************************************************
2 * Copyright (C) 2007-2009 by Øyvind Harboe *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "embeddedice.h"
24 #include "minidriver.h"
25 #include "interface.h"
26 #include "zy1000_version.h"
27
28 #include <cyg/hal/hal_io.h> // low level i/o
29 #include <cyg/hal/hal_diag.h>
30
31 #include <time.h>
32
33 #define ZYLIN_VERSION GIT_ZY1000_VERSION
34 #define ZYLIN_DATE __DATE__
35 #define ZYLIN_TIME __TIME__
36 #define ZYLIN_OPENOCD GIT_OPENOCD_VERSION
37 #define ZYLIN_OPENOCD_VERSION "ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE
38
39
40 static int zy1000_khz(int khz, int *jtag_speed)
41 {
42 if (khz == 0)
43 {
44 *jtag_speed = 0;
45 }
46 else
47 {
48 *jtag_speed = 64000/khz;
49 }
50 return ERROR_OK;
51 }
52
53 static int zy1000_speed_div(int speed, int *khz)
54 {
55 if (speed == 0)
56 {
57 *khz = 0;
58 }
59 else
60 {
61 *khz = 64000/speed;
62 }
63
64 return ERROR_OK;
65 }
66
67 static bool readPowerDropout(void)
68 {
69 cyg_uint32 state;
70 // sample and clear power dropout
71 HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x80);
72 HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state);
73 bool powerDropout;
74 powerDropout = (state & 0x80) != 0;
75 return powerDropout;
76 }
77
78
79 static bool readSRST(void)
80 {
81 cyg_uint32 state;
82 // sample and clear SRST sensing
83 HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x00000040);
84 HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state);
85 bool srstAsserted;
86 srstAsserted = (state & 0x40) != 0;
87 return srstAsserted;
88 }
89
90 static int zy1000_srst_asserted(int *srst_asserted)
91 {
92 *srst_asserted = readSRST();
93 return ERROR_OK;
94 }
95
96 static int zy1000_power_dropout(int *dropout)
97 {
98 *dropout = readPowerDropout();
99 return ERROR_OK;
100 }
101
102 void zy1000_reset(int trst, int srst)
103 {
104 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
105 if (!srst)
106 {
107 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000001);
108 }
109 else
110 {
111 /* Danger!!! if clk != 0 when in
112 * idle in TAP_IDLE, reset halt on str912 will fail.
113 */
114 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001);
115 }
116
117 if (!trst)
118 {
119 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000002);
120 }
121 else
122 {
123 /* assert reset */
124 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000002);
125 }
126
127 if (trst||(srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
128 {
129 waitIdle();
130 /* we're now in the RESET state until trst is deasserted */
131 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_RESET);
132 } else
133 {
134 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
135 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
136 }
137
138 /* wait for srst to float back up */
139 if (!srst)
140 {
141 int i;
142 for (i = 0; i < 1000; i++)
143 {
144 // We don't want to sense our own reset, so we clear here.
145 // There is of course a timing hole where we could loose
146 // a "real" reset.
147 if (!readSRST())
148 break;
149
150 /* wait 1ms */
151 alive_sleep(1);
152 }
153
154 if (i == 1000)
155 {
156 LOG_USER("SRST didn't deassert after %dms", i);
157 } else if (i > 1)
158 {
159 LOG_USER("SRST took %dms to deassert", i);
160 }
161 }
162 }
163
164 int zy1000_speed(int speed)
165 {
166 if (speed == 0)
167 {
168 /*0 means RCLK*/
169 speed = 0;
170 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x100);
171 LOG_DEBUG("jtag_speed using RCLK");
172 }
173 else
174 {
175 if (speed > 8190 || speed < 2)
176 {
177 LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
178 return ERROR_INVALID_ARGUMENTS;
179 }
180
181 LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
182 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x100);
183 ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed&~1);
184 }
185 return ERROR_OK;
186 }
187
188 static bool savePower;
189
190
191 static void setPower(bool power)
192 {
193 savePower = power;
194 if (power)
195 {
196 HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x14, 0x8);
197 } else
198 {
199 HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x8);
200 }
201 }
202
203 COMMAND_HANDLER(handle_power_command)
204 {
205 switch (CMD_ARGC)
206 {
207 case 1: {
208 bool enable;
209 COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
210 setPower(enable);
211 // fall through
212 }
213 case 0:
214 LOG_INFO("Target power %s", savePower ? "on" : "off");
215 break;
216 default:
217 return ERROR_INVALID_ARGUMENTS;
218 }
219
220 return ERROR_OK;
221 }
222
223
224 /* Give TELNET a way to find out what version this is */
225 static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
226 {
227 if ((argc < 1) || (argc > 3))
228 return JIM_ERR;
229 const char *version_str = NULL;
230
231 if (argc == 1)
232 {
233 version_str = ZYLIN_OPENOCD_VERSION;
234 } else
235 {
236 const char *str = Jim_GetString(argv[1], NULL);
237 const char *str2 = NULL;
238 if (argc > 2)
239 str2 = Jim_GetString(argv[2], NULL);
240 if (strcmp("openocd", str) == 0)
241 {
242 version_str = ZYLIN_OPENOCD;
243 }
244 else if (strcmp("zy1000", str) == 0)
245 {
246 version_str = ZYLIN_VERSION;
247 }
248 else if (strcmp("date", str) == 0)
249 {
250 version_str = ZYLIN_DATE;
251 }
252 else if (strcmp("time", str) == 0)
253 {
254 version_str = ZYLIN_TIME;
255 }
256 else if (strcmp("pcb", str) == 0)
257 {
258 #ifdef CYGPKG_HAL_NIOS2
259 version_str="c";
260 #else
261 version_str="b";
262 #endif
263 }
264 #ifdef CYGPKG_HAL_NIOS2
265 else if (strcmp("fpga", str) == 0)
266 {
267
268 /* return a list of 32 bit integers to describe the expected
269 * and actual FPGA
270 */
271 static char *fpga_id = "0x12345678 0x12345678 0x12345678 0x12345678";
272 cyg_uint32 id, timestamp;
273 HAL_READ_UINT32(SYSID_BASE, id);
274 HAL_READ_UINT32(SYSID_BASE+4, timestamp);
275 sprintf(fpga_id, "0x%08x 0x%08x 0x%08x 0x%08x", id, timestamp, SYSID_ID, SYSID_TIMESTAMP);
276 version_str = fpga_id;
277 if ((argc>2) && (strcmp("time", str2) == 0))
278 {
279 time_t last_mod = timestamp;
280 char * t = ctime (&last_mod) ;
281 t[strlen(t)-1] = 0;
282 version_str = t;
283 }
284 }
285 #endif
286
287 else
288 {
289 return JIM_ERR;
290 }
291 }
292
293 Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1));
294
295 return JIM_OK;
296 }
297
298
299 #ifdef CYGPKG_HAL_NIOS2
300 static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
301 {
302 if (argc != 2)
303 return JIM_ERR;
304
305 int length;
306 int stat;
307 const char *str = Jim_GetString(argv[1], &length);
308
309 /* BUG!!!! skip header! */
310 void *firmware_address=0x4000000;
311 int firmware_length=0x100000;
312
313 if (length>firmware_length)
314 return JIM_ERR;
315
316 void *err_addr;
317
318 if ((stat = flash_erase((void *)firmware_address, firmware_length, (void **)&err_addr)) != 0)
319 {
320 return JIM_ERR;
321 }
322
323 if ((stat = flash_program(firmware_address, str, length, (void **)&err_addr)) != 0)
324 return JIM_ERR;
325
326 return JIM_OK;
327 }
328 #endif
329
330 static int
331 zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
332 int argc,
333 Jim_Obj * const *argv)
334 {
335 if (argc != 1)
336 {
337 Jim_WrongNumArgs(interp, 1, argv, "powerstatus");
338 return JIM_ERR;
339 }
340
341 cyg_uint32 status;
342 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, status);
343
344 Jim_SetResult(interp, Jim_NewIntObj(interp, (status&0x80) != 0));
345
346 return JIM_OK;
347 }
348
349
350
351
352 int zy1000_init(void)
353 {
354 LOG_USER("%s", ZYLIN_OPENOCD_VERSION);
355
356 ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x30); // Turn on LED1 & LED2
357
358 setPower(true); // on by default
359
360
361 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
362 zy1000_reset(0, 0);
363 zy1000_speed(jtag_get_speed());
364
365 return ERROR_OK;
366 }
367
368 int zy1000_quit(void)
369 {
370
371 return ERROR_OK;
372 }
373
374
375
376 int interface_jtag_execute_queue(void)
377 {
378 cyg_uint32 empty;
379
380 waitIdle();
381 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty);
382 /* clear JTAG error register */
383 ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400);
384
385 if ((empty&0x400) != 0)
386 {
387 LOG_WARNING("RCLK timeout");
388 /* the error is informative only as we don't want to break the firmware if there
389 * is a false positive.
390 */
391 // return ERROR_FAIL;
392 }
393 return ERROR_OK;
394 }
395
396
397
398
399
400 static cyg_uint32 getShiftValue(void)
401 {
402 cyg_uint32 value;
403 waitIdle();
404 ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, value);
405 VERBOSE(LOG_INFO("getShiftValue %08x", value));
406 return value;
407 }
408 #if 0
409 static cyg_uint32 getShiftValueFlip(void)
410 {
411 cyg_uint32 value;
412 waitIdle();
413 ZY1000_PEEK(ZY1000_JTAG_BASE + 0x18, value);
414 VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));
415 return value;
416 }
417 #endif
418
419 #if 0
420 static void shiftValueInnerFlip(const tap_state_t state, const tap_state_t endState, int repeat, cyg_uint32 value)
421 {
422 VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_name(state), tap_state_name(endState), repeat, value));
423 cyg_uint32 a,b;
424 a = state;
425 b = endState;
426 ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value);
427 ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 15) | (repeat << 8) | (a << 4) | b);
428 VERBOSE(getShiftValueFlip());
429 }
430 #endif
431
432 static void gotoEndState(tap_state_t end_state)
433 {
434 setCurrentState(end_state);
435 }
436
437 static __inline void scanFields(int num_fields, const struct scan_field *fields, tap_state_t shiftState, int pause)
438 {
439 int i;
440 int j;
441 int k;
442
443 for (i = 0; i < num_fields; i++)
444 {
445 cyg_uint32 value;
446
447 uint8_t *inBuffer = NULL;
448
449
450 // figure out where to store the input data
451 int num_bits = fields[i].num_bits;
452 if (fields[i].in_value != NULL)
453 {
454 inBuffer = fields[i].in_value;
455 }
456
457 // here we shuffle N bits out/in
458 j = 0;
459 while (j < num_bits)
460 {
461 tap_state_t pause_state;
462 int l;
463 k = num_bits-j;
464 pause_state = (shiftState == TAP_DRSHIFT)?TAP_DRSHIFT:TAP_IRSHIFT;
465 if (k > 32)
466 {
467 k = 32;
468 /* we have more to shift out */
469 } else if (pause&&(i == num_fields-1))
470 {
471 /* this was the last to shift out this time */
472 pause_state = (shiftState==TAP_DRSHIFT)?TAP_DRPAUSE:TAP_IRPAUSE;
473 }
474
475 // we have (num_bits + 7)/8 bytes of bits to toggle out.
476 // bits are pushed out LSB to MSB
477 value = 0;
478 if (fields[i].out_value != NULL)
479 {
480 for (l = 0; l < k; l += 8)
481 {
482 value|=fields[i].out_value[(j + l)/8]<<l;
483 }
484 }
485 /* mask away unused bits for easier debugging */
486 if (k < 32)
487 {
488 value&=~(((uint32_t)0xffffffff) << k);
489 } else
490 {
491 /* Shifting by >= 32 is not defined by the C standard
492 * and will in fact shift by &0x1f bits on nios */
493 }
494
495 shiftValueInner(shiftState, pause_state, k, value);
496
497 if (inBuffer != NULL)
498 {
499 // data in, LSB to MSB
500 value = getShiftValue();
501 // we're shifting in data to MSB, shift data to be aligned for returning the value
502 value >>= 32-k;
503
504 for (l = 0; l < k; l += 8)
505 {
506 inBuffer[(j + l)/8]=(value >> l)&0xff;
507 }
508 }
509 j += k;
510 }
511 }
512 }
513
514 int interface_jtag_add_ir_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
515 {
516
517 int j;
518 int scan_size = 0;
519 struct jtag_tap *tap, *nextTap;
520 for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
521 {
522 nextTap = jtag_tap_next_enabled(tap);
523 int pause = (nextTap==NULL);
524
525 int found = 0;
526
527 scan_size = tap->ir_length;
528
529 /* search the list */
530 for (j = 0; j < num_fields; j++)
531 {
532 if (tap == fields[j].tap)
533 {
534 found = 1;
535
536 scanFields(1, fields + j, TAP_IRSHIFT, pause);
537 /* update device information */
538 buf_cpy(fields[j].out_value, tap->cur_instr, scan_size);
539
540 tap->bypass = 0;
541 break;
542 }
543 }
544
545 if (!found)
546 {
547 /* if a device isn't listed, set it to BYPASS */
548 uint8_t ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
549
550 struct scan_field tmp;
551 memset(&tmp, 0, sizeof(tmp));
552 tmp.out_value = ones;
553 tmp.num_bits = scan_size;
554 scanFields(1, &tmp, TAP_IRSHIFT, pause);
555 /* update device information */
556 buf_cpy(tmp.out_value, tap->cur_instr, scan_size);
557 tap->bypass = 1;
558 }
559 }
560 gotoEndState(state);
561
562 return ERROR_OK;
563 }
564
565
566
567
568
569 int interface_jtag_add_plain_ir_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
570 {
571 scanFields(num_fields, fields, TAP_IRSHIFT, 1);
572 gotoEndState(state);
573
574 return ERROR_OK;
575 }
576
577 int interface_jtag_add_dr_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
578 {
579
580 int j;
581 struct jtag_tap *tap, *nextTap;
582 for (tap = jtag_tap_next_enabled(NULL); tap!= NULL; tap = nextTap)
583 {
584 nextTap = jtag_tap_next_enabled(tap);
585 int found = 0;
586 int pause = (nextTap==NULL);
587
588 for (j = 0; j < num_fields; j++)
589 {
590 if (tap == fields[j].tap)
591 {
592 found = 1;
593
594 scanFields(1, fields+j, TAP_DRSHIFT, pause);
595 }
596 }
597 if (!found)
598 {
599 struct scan_field tmp;
600 /* program the scan field to 1 bit length, and ignore it's value */
601 tmp.num_bits = 1;
602 tmp.out_value = NULL;
603 tmp.in_value = NULL;
604
605 scanFields(1, &tmp, TAP_DRSHIFT, pause);
606 }
607 else
608 {
609 }
610 }
611 gotoEndState(state);
612 return ERROR_OK;
613 }
614
615 int interface_jtag_add_plain_dr_scan(int num_fields, const struct scan_field *fields, tap_state_t state)
616 {
617 scanFields(num_fields, fields, TAP_DRSHIFT, 1);
618 gotoEndState(state);
619 return ERROR_OK;
620 }
621
622
623 int interface_jtag_add_tlr()
624 {
625 setCurrentState(TAP_RESET);
626 return ERROR_OK;
627 }
628
629
630
631
632 int interface_jtag_add_reset(int req_trst, int req_srst)
633 {
634 zy1000_reset(req_trst, req_srst);
635 return ERROR_OK;
636 }
637
638 static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate)
639 {
640 /* num_cycles can be 0 */
641 setCurrentState(clockstate);
642
643 /* execute num_cycles, 32 at the time. */
644 int i;
645 for (i = 0; i < num_cycles; i += 32)
646 {
647 int num;
648 num = 32;
649 if (num_cycles-i < num)
650 {
651 num = num_cycles-i;
652 }
653 shiftValueInner(clockstate, clockstate, num, 0);
654 }
655
656 #if !TEST_MANUAL()
657 /* finish in end_state */
658 setCurrentState(state);
659 #else
660 tap_state_t t = TAP_IDLE;
661 /* test manual drive code on any target */
662 int tms;
663 uint8_t tms_scan = tap_get_tms_path(t, state);
664 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
665
666 for (i = 0; i < tms_count; i++)
667 {
668 tms = (tms_scan >> i) & 1;
669 waitIdle();
670 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
671 }
672 waitIdle();
673 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state);
674 #endif
675
676
677 return ERROR_OK;
678 }
679
680 int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
681 {
682 return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE);
683 }
684
685 int interface_jtag_add_clocks(int num_cycles)
686 {
687 return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_cur_state);
688 }
689
690 int interface_jtag_add_sleep(uint32_t us)
691 {
692 jtag_sleep(us);
693 return ERROR_OK;
694 }
695
696 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
697 {
698 int state_count;
699 int tms = 0;
700
701 /*wait for the fifo to be empty*/
702 waitIdle();
703
704 state_count = 0;
705
706 tap_state_t cur_state = cmd_queue_cur_state;
707
708 while (num_states)
709 {
710 if (tap_state_transition(cur_state, false) == path[state_count])
711 {
712 tms = 0;
713 }
714 else if (tap_state_transition(cur_state, true) == path[state_count])
715 {
716 tms = 1;
717 }
718 else
719 {
720 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count]));
721 exit(-1);
722 }
723
724 waitIdle();
725 ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms);
726
727 cur_state = path[state_count];
728 state_count++;
729 num_states--;
730 }
731
732 waitIdle();
733 ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, cur_state);
734 return ERROR_OK;
735 }
736
737
738
739 void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
740 {
741 // static int const reg_addr = 0x5;
742 tap_state_t end_state = jtag_get_end_state();
743 if (jtag_tap_next_enabled(jtag_tap_next_enabled(NULL)) == NULL)
744 {
745 /* better performance via code duplication */
746 if (little)
747 {
748 int i;
749 for (i = 0; i < count; i++)
750 {
751 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 1));
752 shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr | (1 << 5));
753 buffer += 4;
754 }
755 } else
756 {
757 int i;
758 for (i = 0; i < count; i++)
759 {
760 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 0));
761 shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr | (1 << 5));
762 buffer += 4;
763 }
764 }
765 }
766 else
767 {
768 int i;
769 for (i = 0; i < count; i++)
770 {
771 embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
772 buffer += 4;
773 }
774 }
775 }
776
777
778 static const struct command_registration zy1000_commands[] = {
779 {
780 .name = "power",
781 .handler = &handle_power_command,
782 .mode = COMMAND_ANY,
783 .help = "turn power switch to target on/off. No arguments - print status.",
784 .usage = "power <on/off>",
785 },
786 {
787 .name = "zy1000_version",
788 .mode = COMMAND_ANY,
789 .jim_handler = &jim_zy1000_version,
790 .help = "print version info for zy1000",
791 },
792 {
793 .name = "powerstatus",
794 .mode = COMMAND_ANY,
795 .jim_handler = & zylinjtag_Jim_Command_powerstatus,
796 .help = "print power status of target",
797 },
798 #ifdef CYGPKG_HAL_NIOS2
799 {
800 .name = "updatezy1000firmware",
801 .mode = COMMAND_ANY,
802 .jim_handler = &jim_zy1000_writefirmware,
803 .help = "writes firmware to flash",
804 },
805 #endif
806 COMMAND_REGISTRATION_DONE
807 };
808
809
810
811 struct jtag_interface zy1000_interface =
812 {
813 .name = "ZY1000",
814 .execute_queue = NULL,
815 .speed = zy1000_speed,
816 .commands = zy1000_commands,
817 .init = zy1000_init,
818 .quit = zy1000_quit,
819 .khz = zy1000_khz,
820 .speed_div = zy1000_speed_div,
821 .power_dropout = zy1000_power_dropout,
822 .srst_asserted = zy1000_srst_asserted,
823 };
824

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)