zy1000.c 17.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/***************************************************************************
 *   Copyright (C) 2007-2008 by yvind Harboe                              *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

23
#define INCLUDE_JTAG_INTERFACE_H
24
#include "embeddedice.h"
zwelch's avatar
zwelch committed
25
#include "minidriver.h"
26
27
28
29
30
31
#include "bitbang.h"

#include <cyg/hal/hal_io.h>             // low level i/o
#include <cyg/hal/hal_diag.h>


oharboe's avatar
oharboe committed
32
#define ZYLIN_VERSION "1.52"
33
34
#define ZYLIN_DATE __DATE__
#define ZYLIN_TIME __TIME__
oharboe's avatar
oharboe committed
35
#define ZYLIN_OPENOCD "$Revision$"
36
37
#define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
const char *zylin_config_dir="/config/settings";
38
39
40

/* low level command set
 */
41
42
43
int zy1000_read(void);
static void zy1000_write(int tck, int tms, int tdi);
void zy1000_reset(int trst, int srst);
44
45


46
47
48
49
int zy1000_speed(int speed);
int zy1000_register_commands(struct command_context_s *cmd_ctx);
int zy1000_init(void);
int zy1000_quit(void);
50
51

/* interface commands */
52
int zy1000_handle_zy1000_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53

54
static int zy1000_khz(int khz, int *jtag_speed)
55
56
57
58
59
60
61
62
63
64
65
66
{
	if (khz==0)
	{
		*jtag_speed=0;
	}
	else
	{
		*jtag_speed=64000/khz;
	}
	return ERROR_OK;
}

67
static int zy1000_speed_div(int speed, int *khz)
68
69
70
71
72
73
74
75
76
77
78
79
80
{
	if (speed==0)
	{
		*khz = 0;
	}
	else
	{
		*khz=64000/speed;
	}

	return ERROR_OK;
}

81
static bool readPowerDropout(void)
82
83
84
{
	cyg_uint32 state;
	// sample and clear power dropout
oharboe's avatar
wip    
oharboe committed
85
86
	HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x80);
	HAL_READ_UINT32(ZY1000_JTAG_BASE+0x10, state);
87
88
89
90
	bool powerDropout;
	powerDropout = (state & 0x80) != 0;
	return powerDropout;
}
91

92

93
static bool readSRST(void)
94
95
96
{
	cyg_uint32 state;
	// sample and clear SRST sensing
oharboe's avatar
wip    
oharboe committed
97
98
	HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x00000040);
	HAL_READ_UINT32(ZY1000_JTAG_BASE+0x10, state);
99
100
101
102
103
	bool srstAsserted;
	srstAsserted = (state & 0x40) != 0;
	return srstAsserted;
}

oharboe's avatar
oharboe committed
104
105
106
107
108
109
static int zy1000_srst_asserted(int *srst_asserted)
{
	*srst_asserted=readSRST();
	return ERROR_OK;
}

110
111
static int zy1000_power_dropout(int *dropout)
{
oharboe's avatar
oharboe committed
112
	*dropout=readPowerDropout();
113
114
115
116
117
	return ERROR_OK;
}


jtag_interface_t zy1000_interface =
118
119
120
{
	.name = "ZY1000",
	.execute_queue = bitbang_execute_queue,
121
122
123
124
125
126
127
	.speed = zy1000_speed,
	.register_commands = zy1000_register_commands,
	.init = zy1000_init,
	.quit = zy1000_quit,
	.khz = zy1000_khz,
	.speed_div = zy1000_speed_div,
	.power_dropout = zy1000_power_dropout,
oharboe's avatar
oharboe committed
128
	.srst_asserted = zy1000_srst_asserted,
129
130
};

131
bitbang_interface_t zy1000_bitbang =
132
{
133
134
135
	.read = zy1000_read,
	.write = zy1000_write,
	.reset = zy1000_reset
136
137
138
139
};



140
static void zy1000_write(int tck, int tms, int tdi)
141
142
143
144
{

}

145
int zy1000_read(void)
146
147
148
149
{
	return -1;
}

150
extern bool readSRST(void);
151

152
void zy1000_reset(int trst, int srst)
153
154
155
156
{
	LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
	if(!srst)
	{
oharboe's avatar
wip    
oharboe committed
157
		ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x00000001);
158
159
160
161
	}
	else
	{
		/* Danger!!! if clk!=0 when in
162
		 * idle in TAP_IDLE, reset halt on str912 will fail.
163
		 */
oharboe's avatar
wip    
oharboe committed
164
		ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x00000001);
165
166
167
168
	}

	if(!trst)
	{
oharboe's avatar
wip    
oharboe committed
169
		ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x00000002);
170
171
172
173
	}
	else
	{
		/* assert reset */
oharboe's avatar
wip    
oharboe committed
174
		ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x00000002);
175
	}
176

177
178
179
	if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))
	{
		waitIdle();
180
		/* we're now in the RESET state until trst is deasserted */
181
		ZY1000_POKE(ZY1000_JTAG_BASE+0x20, TAP_RESET);
182
183
184
	} else
	{
		/* We'll get RCLK failure when we assert TRST, so clear any false positives here */
oharboe's avatar
wip    
oharboe committed
185
		ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x400);
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
	}

	/* wait for srst to float back up */
	if (!srst)
	{
		int i;
		for (i=0; i<1000; i++)
		{
			// We don't want to sense our own reset, so we clear here.
			// There is of course a timing hole where we could loose
			// a "real" reset.
			if (!readSRST())
				break;

			/* wait 1ms */
			alive_sleep(1);
		}

		if (i==1000)
		{
			LOG_USER("SRST didn't deassert after %dms", i);
		} else if (i>1)
		{
			LOG_USER("SRST took %dms to deassert", i);
		}
	}
}

214
int zy1000_speed(int speed)
215
216
217
218
219
{
	if(speed == 0)
	{
		/*0 means RCLK*/
		speed = 0;
oharboe's avatar
wip    
oharboe committed
220
		ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x100);
221
222
223
224
225
226
		LOG_DEBUG("jtag_speed using RCLK");
	}
	else
	{
		if(speed > 8190 || speed < 2)
		{
227
			LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
228
229
230
231
			return ERROR_INVALID_ARGUMENTS;
		}

		LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
oharboe's avatar
wip    
oharboe committed
232
233
		ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x100);
		ZY1000_POKE(ZY1000_JTAG_BASE+0x1c, speed&~1);
234
235
236
237
	}
	return ERROR_OK;
}

238
static bool savePower;
239
240


241
static void setPower(bool power)
242
{
243
244
245
246
247
248
249
250
	savePower = power;
	if (power)
	{
		HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8);
	} else
	{
		HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8);
	}
251
252
}

253
int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
254
{
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
	if (argc > 1)
	{
		return ERROR_INVALID_ARGUMENTS;
	}

	if (argc == 1)
	{
		if (strcmp(args[0], "on") == 0)
		{
			setPower(1);
		}
		else if (strcmp(args[0], "off") == 0)
		{
			setPower(0);
		} else
		{
			command_print(cmd_ctx, "arg is \"on\" or \"off\"");
			return ERROR_INVALID_ARGUMENTS;
		}
	}

	command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
277
278
279
280
281

	return ERROR_OK;
}


282
/* Give TELNET a way to find out what version this is */
oharboe's avatar
oharboe committed
283
static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
284
{
oharboe's avatar
oharboe committed
285
286
287
288
289
290
	if ((argc < 1) || (argc > 2))
		return JIM_ERR;
	char buff[128];
	const char *version_str=NULL;

	if (argc == 1)
291
	{
oharboe's avatar
oharboe committed
292
293
		version_str=ZYLIN_OPENOCD_VERSION;
	} else
294
	{
oharboe's avatar
oharboe committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
		const char *str = Jim_GetString(argv[1], NULL);
		if (strcmp("openocd", str) == 0)
		{
			int revision;
			revision = atol(ZYLIN_OPENOCD+strlen("XRevision: "));
			sprintf(buff, "%d", revision);
			version_str=buff;
		}
		else if (strcmp("zy1000", str) == 0)
		{
			version_str=ZYLIN_VERSION;
		}
		else if (strcmp("date", str) == 0)
		{
			version_str=ZYLIN_DATE;
		}
		else
		{
			return JIM_ERR;
		}
315
	}
316

oharboe's avatar
oharboe committed
317
318
319
	Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1));

	return JIM_OK;
320
321
}

322

oharboe's avatar
oharboe committed
323
324
static int
zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
325
								   int argc,
oharboe's avatar
oharboe committed
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
		Jim_Obj * const *argv)
{
	if (argc != 1)
	{
		Jim_WrongNumArgs(interp, 1, argv, "powerstatus");
		return JIM_ERR;
	}

	cyg_uint32 status;
	ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, status);

	Jim_SetResult(interp, Jim_NewIntObj(interp, (status&0x80)!=0));

	return JIM_OK;
}

342
343
344
345
int zy1000_register_commands(struct command_context_s *cmd_ctx)
{
	register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
			"power <on/off> - turn power switch to target on/off. No arguments - print status.");
oharboe's avatar
oharboe committed
346
347
348

	Jim_CreateCommand(interp, "zy1000_version", jim_zy1000_version, NULL, NULL);

349

oharboe's avatar
oharboe committed
350
	Jim_CreateCommand(interp, "powerstatus", zylinjtag_Jim_Command_powerstatus, NULL, NULL);
351

352
353
354
355
	return ERROR_OK;
}


oharboe's avatar
oharboe committed
356
357


358
359
int zy1000_init(void)
{
oharboe's avatar
oharboe committed
360
	LOG_USER("%s", ZYLIN_OPENOCD_VERSION);
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

	ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x30); // Turn on LED1 & LED2

	setPower(true); // on by default


	 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
	zy1000_reset(0, 0);
	zy1000_speed(jtag_speed);

	bitbang_interface = &zy1000_bitbang;

	return ERROR_OK;
}

int zy1000_quit(void)
{

	return ERROR_OK;
380
381
382
383
384
385
386
387
388
}



int interface_jtag_execute_queue(void)
{
	cyg_uint32 empty;

	waitIdle();
oharboe's avatar
wip    
oharboe committed
389
	ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, empty);
390
	/* clear JTAG error register */
oharboe's avatar
wip    
oharboe committed
391
	ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x400);
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407

	if ((empty&0x400)!=0)
	{
		LOG_WARNING("RCLK timeout");
		/* the error is informative only as we don't want to break the firmware if there
		 * is a false positive.
		 */
//		return ERROR_FAIL;
	}
	return ERROR_OK;
}





408
static cyg_uint32 getShiftValue(void)
409
410
411
{
	cyg_uint32 value;
	waitIdle();
oharboe's avatar
wip    
oharboe committed
412
	ZY1000_PEEK(ZY1000_JTAG_BASE+0xc, value);
413
414
415
416
	VERBOSE(LOG_INFO("getShiftValue %08x", value));
	return value;
}
#if 0
417
static cyg_uint32 getShiftValueFlip(void)
418
419
420
{
	cyg_uint32 value;
	waitIdle();
oharboe's avatar
wip    
oharboe committed
421
	ZY1000_PEEK(ZY1000_JTAG_BASE+0x18, value);
422
423
424
425
426
427
	VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));
	return value;
}
#endif

#if 0
428
static void shiftValueInnerFlip(const tap_state_t state, const tap_state_t endState, int repeat, cyg_uint32 value)
429
{
430
	VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_name(state), tap_state_name(endState), repeat, value));
431
432
433
	cyg_uint32 a,b;
	a=state;
	b=endState;
oharboe's avatar
wip    
oharboe committed
434
435
	ZY1000_POKE(ZY1000_JTAG_BASE+0xc, value);
	ZY1000_POKE(ZY1000_JTAG_BASE+0x8, (1<<15)|(repeat<<8)|(a<<4)|b);
436
437
438
439
440
441
	VERBOSE(getShiftValueFlip());
}
#endif

extern int jtag_check_value(u8 *captured, void *priv);

442
static void gotoEndState(void)
443
444
445
446
{
	setCurrentState(cmd_queue_end_state);
}

447
static __inline void scanFields(int num_fields, scan_field_t *fields, tap_state_t shiftState, tap_state_t end_state)
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
{
	int i;
	int j;
	int k;

	for (i = 0; i < num_fields; i++)
	{
		cyg_uint32 value;

		static u8 *in_buff=NULL; /* pointer to buffer for scanned data */
		static int in_buff_size=0;
		u8 *inBuffer=NULL;


		// figure out where to store the input data
		int num_bits=fields[i].num_bits;
		if (fields[i].in_value!=NULL)
		{
			inBuffer=fields[i].in_value;
		}

		// here we shuffle N bits out/in
		j=0;
		while (j<num_bits)
		{
473
			tap_state_t pause_state;
474
475
			int l;
			k=num_bits-j;
476
			pause_state=(shiftState==TAP_DRSHIFT)?TAP_DRSHIFT:TAP_IRSHIFT;
477
478
479
480
			if (k>32)
			{
				k=32;
				/* we have more to shift out */
481
			} else if (i == num_fields-1)
482
483
			{
				/* this was the last to shift out this time */
484
				pause_state=end_state;
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
			}

			// we have (num_bits+7)/8 bytes of bits to toggle out.
			// bits are pushed out LSB to MSB
			value=0;
			if (fields[i].out_value!=NULL)
			{
				for (l=0; l<k; l+=8)
				{
					value|=fields[i].out_value[(j+l)/8]<<l;
				}
			}
			/* mask away unused bits for easier debugging */
			value&=~(((u32)0xffffffff)<<k);

			shiftValueInner(shiftState, pause_state, k, value);

			if (inBuffer!=NULL)
			{
				// data in, LSB to MSB
				value=getShiftValue();
				// we're shifting in data to MSB, shift data to be aligned for returning the value
				value >>= 32-k;

				for (l=0; l<k; l+=8)
				{
					inBuffer[(j+l)/8]=(value>>l)&0xff;
				}
			}
			j+=k;
		}
	}
}

519
int interface_jtag_add_end_state(tap_state_t state)
520
521
522
523
524
{
	return ERROR_OK;
}


oharboe's avatar
oharboe committed
525
int interface_jtag_add_ir_scan(int num_fields, const scan_field_t *fields, tap_state_t state)
526
527
{

oharboe's avatar
oharboe committed
528
	int j;
529
	int scan_size = 0;
oharboe's avatar
oharboe committed
530
531
	jtag_tap_t *tap, *nextTap;
	for(tap = jtag_NextEnabledTap(NULL); tap!= NULL; tap=nextTap)
532
	{
oharboe's avatar
oharboe committed
533
		nextTap=jtag_NextEnabledTap(tap);
534
535
536
537
538
539
540
541
		tap_state_t end_state;
		if (nextTap==NULL)
		{
			end_state = cmd_queue_end_state;
		} else
		{
			end_state = TAP_IRSHIFT;
		}
oharboe's avatar
oharboe committed
542

543
		int found = 0;
544

oharboe's avatar
oharboe committed
545
		scan_size = tap->ir_length;
546
547
548
549

		/* search the list */
		for (j=0; j < num_fields; j++)
		{
oharboe's avatar
oharboe committed
550
			if (tap == fields[j].tap)
551
552
553
			{
				found = 1;

554
				scanFields(1, fields+j, TAP_IRSHIFT, end_state);
555
				/* update device information */
oharboe's avatar
oharboe committed
556
				buf_cpy(fields[j].out_value, tap->cur_instr, scan_size);
557

oharboe's avatar
oharboe committed
558
				tap->bypass = 0;
559
560
561
562
563
564
565
566
567
568
569
570
571
				break;
			}
		}

		if (!found)
		{
			/* if a device isn't listed, set it to BYPASS */
			u8 ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

			scan_field_t tmp;
			memset(&tmp, 0, sizeof(tmp));
			tmp.out_value = ones;
			tmp.num_bits = scan_size;
572
			scanFields(1, &tmp, TAP_IRSHIFT, end_state);
573
			/* update device information */
oharboe's avatar
oharboe committed
574
575
			buf_cpy(tmp.out_value, tap->cur_instr, scan_size);
			tap->bypass = 1;
576
577
578
579
580
581
582
583
584
585
		}
	}

	return ERROR_OK;
}





oharboe's avatar
oharboe committed
586
int interface_jtag_add_plain_ir_scan(int num_fields, const scan_field_t *fields, tap_state_t state)
587
{
588
	scanFields(num_fields, fields, TAP_IRSHIFT, cmd_queue_end_state);
589
590
591
592
593
594

	return ERROR_OK;
}

/*extern jtag_command_t **jtag_get_last_command_p(void);*/

oharboe's avatar
oharboe committed
595
int interface_jtag_add_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state)
596
{
oharboe's avatar
oharboe committed
597
598
599
600

	int j;
	jtag_tap_t *tap, *nextTap;
	for(tap = jtag_NextEnabledTap(NULL); tap!= NULL; tap=nextTap)
601
	{
oharboe's avatar
oharboe committed
602
603
		nextTap=jtag_NextEnabledTap(tap);
		int found=0;
604
605
606
607
608
609
610
611
		tap_state_t end_state;
		if (nextTap==NULL)
		{
			end_state = cmd_queue_end_state;
		} else
		{
			end_state = TAP_DRSHIFT;
		}
612
613
614

		for (j=0; j < num_fields; j++)
		{
oharboe's avatar
oharboe committed
615
			if (tap == fields[j].tap)
616
617
618
			{
				found = 1;

619
				scanFields(1, fields+j, TAP_DRSHIFT, end_state);
620
621
622
623
624
625
626
627
628
629
			}
		}
		if (!found)
		{
			scan_field_t tmp;
			/* program the scan field to 1 bit length, and ignore it's value */
			tmp.num_bits = 1;
			tmp.out_value = NULL;
			tmp.in_value = NULL;

630
			scanFields(1, &tmp, TAP_DRSHIFT, end_state);
631
632
633
634
635
636
637
638
		}
		else
		{
		}
	}
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
639
int interface_jtag_add_plain_dr_scan(int num_fields, const scan_field_t *fields, tap_state_t state)
640
{
641
	scanFields(num_fields, fields, TAP_DRSHIFT, cmd_queue_end_state);
642
643
644
645
646
647
	return ERROR_OK;
}


int interface_jtag_add_tlr()
{
648
	setCurrentState(TAP_RESET);
649
650
651
652
653
654
655
656
657
658
659
	return ERROR_OK;
}




extern int jtag_nsrst_delay;
extern int jtag_ntrst_delay;

int interface_jtag_add_reset(int req_trst, int req_srst)
{
660
	zy1000_reset(req_trst, req_srst);
661
662
663
	return ERROR_OK;
}

664
static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate)
665
666
{
	/* num_cycles can be 0 */
667
	setCurrentState(clockstate);
668
669
670
671
672
673
674
675
676
677
678

	/* execute num_cycles, 32 at the time. */
	int i;
	for (i=0; i<num_cycles; i+=32)
	{
		int num;
		num=32;
		if (num_cycles-i<num)
		{
			num=num_cycles-i;
		}
679
		shiftValueInner(clockstate, clockstate, num, 0);
680
681
682
683
684
685
	}

#if !TEST_MANUAL()
	/* finish in end_state */
	setCurrentState(state);
#else
686
	tap_state_t t=TAP_IDLE;
687
688
	/* test manual drive code on any target */
	int tms;
689
	u8 tms_scan = tap_get_tms_path(t, state);
690
	int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
691

692
	for (i = 0; i < tms_count; i++)
693
694
695
	{
		tms = (tms_scan >> i) & 1;
		waitIdle();
oharboe's avatar
wip    
oharboe committed
696
		ZY1000_POKE(ZY1000_JTAG_BASE+0x28,  tms);
697
698
	}
	waitIdle();
oharboe's avatar
wip    
oharboe committed
699
	ZY1000_POKE(ZY1000_JTAG_BASE+0x20, state);
700
701
702
703
704
705
#endif


	return ERROR_OK;
}

706
int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
707
708
709
710
711
712
713
714
715
{
	return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE);
}

int interface_jtag_add_clocks(int num_cycles)
{
	return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_end_state);
}

716
717
718
719
720
721
int interface_jtag_add_sleep(u32 us)
{
	jtag_sleep(us);
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
722
int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
723
724
725
726
727
728
729
730
731
{
	int state_count;
	int tms = 0;

	/*wait for the fifo to be empty*/
	waitIdle();

	state_count = 0;

732
	tap_state_t cur_state=cmd_queue_cur_state;
733
734
735

	while (num_states)
	{
736
		if (tap_state_transition(cur_state, false) == path[state_count])
737
738
739
		{
			tms = 0;
		}
740
		else if (tap_state_transition(cur_state, true) == path[state_count])
741
742
743
744
745
		{
			tms = 1;
		}
		else
		{
746
			LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count]));
747
748
749
750
			exit(-1);
		}

		waitIdle();
oharboe's avatar
wip    
oharboe committed
751
		ZY1000_POKE(ZY1000_JTAG_BASE+0x28,  tms);
752
753
754
755
756
757
758

		cur_state = path[state_count];
		state_count++;
		num_states--;
	}

	waitIdle();
oharboe's avatar
wip    
oharboe committed
759
	ZY1000_POKE(ZY1000_JTAG_BASE+0x20,  cur_state);
760
761
762
763
764
	return ERROR_OK;
}



oharboe's avatar
oharboe committed
765
void embeddedice_write_dcc(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little, int count)
766
767
{
//	static int const reg_addr=0x5;
768
	tap_state_t end_state=cmd_queue_end_state;
oharboe's avatar
oharboe committed
769
	if (jtag_NextEnabledTap(jtag_NextEnabledTap(NULL))==NULL)
770
771
772
773
774
775
776
	{
		/* better performance via code duplication */
		if (little)
		{
			int i;
			for (i = 0; i < count; i++)
			{
777
778
				shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 1));
				shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr|(1<<5));
779
780
781
782
783
784
785
				buffer+=4;
			}
		} else
		{
			int i;
			for (i = 0; i < count; i++)
			{
786
787
				shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 0));
				shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr|(1<<5));
788
789
790
791
792
793
794
795
796
				buffer+=4;
			}
		}
	}
	else
	{
		int i;
		for (i = 0; i < count; i++)
		{
oharboe's avatar
oharboe committed
797
			embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
798
799
800
801
802
			buffer += 4;
		}
	}
}

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
int loadFile(const char *fileName, void **data, int *len);

/* boolean parameter stored on config */
int boolParam(char *var)
{
	bool result = false;
	char *name = alloc_printf("%s/%s", zylin_config_dir, var);
	if (name == NULL)
		return result;

	void *data;
	int len;
	if (loadFile(name, &data, &len) == ERROR_OK)
	{
		if (len > 1)
			len = 1;
		result = strncmp((char *) data, "1", len) == 0;
		free(data);
	}
	free(name);
	return result;
}
825
826