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

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)