Project

General

Profile

Download (56.5 KB) Statistics
| Branch: | Tag: | Revision:
1
/**************************************************************
2
*
3
* Lattice Semiconductor Corp. Copyright 2008
4
* 
5
*
6
***************************************************************/
7

    
8

    
9
/**************************************************************
10
* 
11
* Revision History of slim_pro.c
12
* 
13
* 
14
* 09/11/07 NN Updated to support version 1.3
15
* This version supported new POLING STATUS LOOP opcodes (LOOP and ENDLOOP) 
16
* for Flash programming of the Lattice FPGA devices
17
* 09/11/07 NN type cast all the mismatch variables
18
***************************************************************/
19

    
20

    
21
#include <stdio.h>
22
#include "opcode.h"
23
#include "hardware.h"
24

    
25
#define xdata
26
#define reentrant
27

    
28
/*************************************************************
29
*                                                            *
30
* PROTOTYPES                                                 *
31
*                                                            *
32
*************************************************************/
33

    
34
static int outofs = 0;
35

    
36
unsigned int ispVMDataSize(int output);
37
short int ispVMShiftExec(unsigned int a_uiDataSize);
38
short int ispVMShift(char a_cCommand);
39
void printData(unsigned char d);
40
unsigned char GetByte(int a_iCurrentIndex, char a_cAlgo, int output);
41
void ispVMStateMachine(char a_cNextState);
42
void ispVMClocks(unsigned int a_usClocks);
43
void ispVMBypass(unsigned int a_siLength);
44
void sclock();
45
short int ispVMRead(unsigned int a_uiDataSize);
46
void ispVMSend(unsigned int a_uiDataSize);
47
void ispVMLCOUNT(unsigned short a_usCountSize);
48
void ispVMLDELAY();
49
/*************************************************************
50
*                                                            *
51
* EXTERNAL FUNCTION                                          *
52
*                                                            *
53
*************************************************************/
54

    
55
extern void ispVMDelay(unsigned int a_usDelay);
56
// extern unsigned char readPort();
57
extern void writePort(unsigned char a_ucPins, unsigned char a_ucValue);
58

    
59
/*************************************************************
60
*                                                            *
61
* GLOBAL VARIABLES                                           *
62
*                                                            *
63
*************************************************************/
64
int g_iMovingAlgoIndex = 0;	    /*** variable to hold the current index in the algo array ***/
65
int g_iMovingDataIndex = 0;		/*** variable to hold the current index in the data array ***/
66
unsigned short g_usDataType = 0x0000; /*** data type register used to hold information ***
67
									 			  **** about the algorithm and data ***/
68
unsigned char g_cEndDR = 0;		/*** used to hold the ENDDR state. ***/
69
unsigned char g_cEndIR = 0;		/*** used to hold the ENDIR state. ***/
70
short int g_siHeadDR = 0;		/*** used to hold the header data register ***/
71
short int g_siHeadIR = 0;		/*** used to hold the header instruction register ***/
72
short int g_siTailDR = 0;		/*** used to hold the trailer data register ***/
73
short int g_siTailIR = 0;		/*** used to hold the trailer instruction register ***/
74

    
75
int g_iMainDataIndex = 0;		/*** forward - only index used as a placed holder in the data array ***/
76
int g_iRepeatIndex = 0;		    /*** Used to point to the location of REPEAT data ***/
77
int g_iTDIIndex = 0;			/*** Used to point to the location of TDI data ***/
78
int g_iTDOIndex = 0;			/*** Used to point to the location of TDO data ***/
79
int g_iMASKIndex = 0;			/*** Used to point to the location of MASK data ***/
80
unsigned char g_ucCompressCounter = 0; /*** used to indicate how many times 0xFF is repeated ***/
81

    
82
short int g_siIspPins = 0x00;   /*** holds the current byte to be sent to the hardware ***/
83
char g_cCurrentJTAGState = 0;	/*** holds the current state of JTAG state machine ***/
84

    
85
int  g_iLoopIndex = 0;			
86
int  g_iLoopMovingIndex = 0;	/*** Used to point to the location of LOOP data ***/
87
int  g_iLoopDataMovingIndex = 0;
88

    
89
unsigned short g_usLCOUNTSize	= 0;
90
unsigned char  g_ucLDELAYState = IDLE;
91
unsigned short int  g_ucLDELAYTCK = 0;
92
unsigned short int  g_ucLDELAYDelay = 0;
93
unsigned short int m_loopState = 0;
94

    
95
/*************************************************************
96
*                                                            *
97
* EXTERNAL VARIABLES                                         *
98
*                                                            *
99
*     If the algorithm does not require the data, then       *
100
*     declare the variables g_pucDataArray and g_iDataSize   *
101
*     as local variables and set them to NULL and 0,         *
102
*     respectively.                                          *
103
*                                                            *
104
*     Example:                                               *
105
*          xdata unsigned char * g_pucDataArray = NULL;      *
106
*          xdata int g_iDataSize = 0;                        *
107
*                                                            *
108
*************************************************************/
109

    
110
xdata const struct iState 
111
{               
112
	/*** JTAG state machine transistion table ***/
113
	unsigned char  CurState;		/*** From this state ***/
114
	unsigned char  NextState;		/*** Step to this state ***/
115
	unsigned char  Pattern;			/*** The pattern of TMS ***/
116
	unsigned char  Pulses;			/*** The number of steps ***/
117
} iStates[25] = 
118
{
119
	{ DRPAUSE,	SHIFTDR,	0x80, 2 },
120
	{ IRPAUSE,	SHIFTIR,	0x80, 2 },
121
	{ SHIFTIR,	IRPAUSE,	0x80, 2 },
122
	{ SHIFTDR,	DRPAUSE,	0x80, 2 },
123
	{ DRPAUSE,	IDLE,		0xC0, 3 },
124
	{ IRPAUSE,	IDLE,		0xC0, 3 },
125
	{ RESET,	IDLE,		0x00, 1 },
126
	{ RESET,	DRPAUSE,	0x50, 5 },
127
	{ RESET,	IRPAUSE,	0x68, 6 },
128
	{ IDLE,		RESET,		0xE0, 3 },
129
	{ IDLE,		DRPAUSE,	0xA0, 4 },
130
	{ IDLE,		IRPAUSE,	0xD0, 5 },
131
	{ DRPAUSE,	RESET,		0xF8, 5 },
132
	{ DRPAUSE,	IRPAUSE,	0xF4, 7 },
133
	{ DRPAUSE,	DRPAUSE,	0xE8, 6 },  /* 06/14/06 Support POLING STATUS LOOP*/
134
	{ IRPAUSE,	RESET,		0xF8, 5 },
135
	{ IRPAUSE,	DRPAUSE,	0xE8, 6 },
136
	{ IRPAUSE,	SHIFTDR,	0xE0, 5 },
137
	{ SHIFTIR,	IDLE,		0xC0, 3 },
138
	{ SHIFTDR,	IDLE,		0xC0, 3 },
139
	{ RESET,	RESET,		0xFC, 6 },
140
	{ DRPAUSE,	DRCAPTURE,	0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/
141
	{ DRCAPTURE, DRPAUSE,	0x80, 2 },
142
	{ IDLE,     DRCAPTURE,	0x80, 2 },
143
	{ IRPAUSE,  DRCAPTURE, 	0xE0, 4 }
144
};
145
/*************************************************************
146
*                                                            *
147
* ISPPROCESSVME                                              *
148
*                                                            *
149
* INPUT:                                                     *
150
*     None.                                                  *
151
*                                                            *
152
* RETURN:                                                    *
153
*     The return value indicates whether the vme was         *
154
*     processed successfully or not.  A return value equal   *
155
*     to or greater than 0 is passing, and less than 0 is    *
156
*     failing.                                               *
157
*                                                            *
158
* DESCRIPTION:                                               *
159
*     This function is the core of the embedded processor.   *
160
*     It extracts the VME file for the high - level tokens     *
161
*     such as SIR, SDR, STATE, etc, and calls the            *
162
*     appropriate functions to process them.                 *
163
*                                                            *
164
*************************************************************/
165

    
166
short int ispProcessVME() reentrant
167
{
168
	unsigned char ucOpcode        = 0;
169
	unsigned char ucState         = 0;
170
	short int siRetCode           = 0;
171
	static char cProgram          = 0;
172
	unsigned int uiDataSize       = 0;
173
	int iLoopCount                = 0;
174
	unsigned int iMovingAlgoIndex = 0;
175
	
176
	/*************************************************************
177
	*                                                            *
178
	* Begin processing the vme algorithm and data files.         *
179
	*                                                            *
180
	*************************************************************/
181
#ifdef DEBUG
182
	fprintf(stderr, ".");
183
#endif
184
	while ((ucOpcode = GetByte(g_iMovingAlgoIndex++, 1, 0)) != 0xFF)
185
	{
186
		/*************************************************************
187
		*                                                            *
188
		* This switch statement is the main switch that represents   *
189
		* the core of the embedded processor.                        *
190
		*                                                            *
191
		*************************************************************/
192
#ifdef DEBUG
193
		fprintf(stderr, "\n%d: ", outofs);
194
#endif
195
		switch (ucOpcode)
196
		{
197
		case STATE:
198
			/*************************************************************
199
			*                                                            *
200
			* Move the state.                                            *
201
			*                                                            *
202
			*************************************************************/	
203
			printData(ucOpcode);
204
			ispVMStateMachine(GetByte(g_iMovingAlgoIndex++, 1, 1));
205
			break;
206
		case SIR:
207
		case SDR:
208
			/*************************************************************
209
			*                                                            *
210
			* Execute SIR/SDR command.                                   *
211
			*                                                            *
212
			*************************************************************/
213
			printData(ucOpcode);
214
			siRetCode = ispVMShift(ucOpcode);
215
			break;
216
		case TCK:
217
			/*************************************************************
218
			*                                                            *
219
			* Pulse TCK signal the specified time.                       *
220
			*                                                            *
221
			*************************************************************/
222
			printData(ucOpcode);
223
			ispVMClocks(ispVMDataSize(1));
224
			break;
225
		case WAIT:
226
			/*************************************************************
227
			*                                                            *
228
			* Issue delay in specified time.                             *
229
			*                                                            *
230
			*************************************************************/
231
			printData(ucOpcode);
232
			ispVMDelay(ispVMDataSize(1));
233
			break;
234
		case ENDDR:
235
			/*************************************************************
236
			*                                                            *
237
			* Get the ENDDR state and store in global variable.          *
238
			*                                                            *
239
			*************************************************************/
240
			printData(ucOpcode);
241
			g_cEndDR = GetByte(g_iMovingAlgoIndex++, 1, 1);
242
			break;
243
		case ENDIR:
244
			/*************************************************************
245
			*                                                            *
246
			* Get the ENDIR state and store in global variable.          *
247
			*                                                            *
248
			*************************************************************/
249
			printData(ucOpcode);
250
			g_cEndIR = GetByte(g_iMovingAlgoIndex++, 1, 1);
251
			break;
252
		case HIR:
253
			printData(ucOpcode);
254
			g_siHeadIR = (short int) ispVMDataSize(1);
255
			break;
256
		case TIR:
257
			printData(ucOpcode);
258
			g_siTailIR = (short int) ispVMDataSize(1);
259
			break;
260
		case HDR:
261
			printData(ucOpcode);
262
			g_siHeadDR = (short int) ispVMDataSize(1);
263
			break;
264
		case TDR:
265
			printData(ucOpcode);
266
			g_siTailDR = (short int) ispVMDataSize(1);
267
			break;
268
		case BEGIN_REPEAT:
269
			/*************************************************************
270
			*                                                            *
271
			* Execute repeat loop.                                       *
272
			*                                                            *
273
			*************************************************************/
274
			
275
			uiDataSize = ispVMDataSize(0);
276
			
277
			switch (GetByte(g_iMovingAlgoIndex++, 1, 0))
278
			{
279
			case PROGRAM:
280
				/*************************************************************
281
				*                                                            *
282
				* Set the main data index to the moving data index.  This    *
283
				* allows the processor to remember the beginning of the      *
284
				* data.  Set the cProgram variable to true to indicate to    *
285
				* the verify flow later that a programming flow has been     *
286
				* completed so the moving data index must return to the      *
287
				* main data index.                                           *
288
				*                                                            *
289
				*************************************************************/
290
				g_iMainDataIndex = g_iMovingDataIndex;
291
				cProgram = 1;
292
#ifdef DEBUG
293
				fprintf(stderr, "BEGIN_REPEAT - PROGRAM (uiDataSize:%d)", uiDataSize);
294
#endif
295
				break;
296
			case VERIFY:
297
				/*************************************************************
298
				*                                                            *
299
				* If the static variable cProgram has been set, then return  *
300
				* the moving data index to the main data index because this  *
301
				* is a erase, program, verify operation.  If the programming *
302
				* flag is not set, then this is a verify only operation thus *
303
				* no need to return the moving data index.                   *
304
				*                                                            *
305
				*************************************************************/
306
				if (cProgram)
307
				{
308
					g_iMovingDataIndex = g_iMainDataIndex;
309
					cProgram = 0;
310
				}
311
#ifdef DEBUG
312
				fprintf(stderr, "BEGIN_REPEAT - VERIFY (uiDataSize:%d)", uiDataSize);
313
#endif
314
				break;
315
			}
316
			
317
			/*************************************************************
318
			*                                                            *
319
			* Set the repeat index to the first byte in the repeat loop. *
320
			*                                                            *
321
			*************************************************************/
322
			
323
			g_iRepeatIndex = g_iMovingAlgoIndex;
324
			
325
			for (; uiDataSize > 0; uiDataSize--)
326
			{
327
				/*************************************************************
328
				*                                                            *
329
				* Initialize the current algorithm index to the beginning of *
330
				* the repeat index before each repeat loop.                  *
331
				*                                                            *
332
				*************************************************************/
333
				
334
				g_iMovingAlgoIndex = g_iRepeatIndex;
335
				
336
				/*************************************************************
337
				*                                                            *
338
				* Make recursive call.                                       *
339
				*                                                            *
340
				*************************************************************/
341
				
342
				siRetCode = ispProcessVME();
343
				if (siRetCode < 0)
344
				{
345
					break;
346
				}
347
			}
348
			break;
349
			case END_REPEAT:
350
				/*************************************************************
351
				*                                                            *
352
				* Exit the current repeat frame.                             *
353
				*                                                            *
354
				*************************************************************/
355
#ifdef DEBUG
356
				fprintf(stderr, "END_REPEAT ");
357
#endif
358
				return siRetCode;
359
				break;
360
			case LOOP:
361
				/*************************************************************
362
				*                                                            *
363
				* Execute repeat loop.                                       *
364
				*                                                            *
365
				*************************************************************/
366
				printData(ucOpcode);
367

    
368
				g_usLCOUNTSize = (short int)ispVMDataSize(1);
369
#ifdef DEBUG
370
				fprintf(stderr, "LOOP %d ", g_usLCOUNTSize);
371
				fprintf(stderr,  "MaxLoopCount %d\n", g_usLCOUNTSize );
372
#endif
373
				/*************************************************************
374
				*                                                            *
375
				* Set the repeat index to the first byte in the repeat loop. *
376
				*                                                            *
377
				*************************************************************/
378

    
379
				g_iLoopMovingIndex = g_iMovingAlgoIndex;
380
				g_iLoopDataMovingIndex = g_iMovingDataIndex;
381

    
382

    
383
				for ( g_iLoopIndex = 0 ; g_iLoopIndex < g_usLCOUNTSize; g_iLoopIndex++ ) {
384
					m_loopState = 1;
385
					/*************************************************************
386
					*                                                            *
387
					* Initialize the current algorithm index to the beginning of *
388
					* the repeat index before each repeat loop.                  *
389
					*                                                            *
390
					*************************************************************/
391

    
392
					g_iMovingAlgoIndex = g_iLoopMovingIndex;
393
					g_iMovingDataIndex = g_iLoopDataMovingIndex;
394

    
395

    
396
					/*************************************************************
397
					*                                                            *
398
					* Make recursive call.                                       *
399
					*                                                            *
400
					*************************************************************/
401
#ifdef DEBUG
402
					fprintf(stderr, "I:%d ", g_iLoopIndex);
403
#endif
404
					siRetCode = ispProcessVME();
405
					if (!siRetCode) {
406
#ifdef DEBUG
407
						fprintf(stderr, "OK ");
408
#endif
409
						/*************************************************************
410
						*                                                            *
411
						* Stop if the complete status matched.                       *
412
						*                                                            *
413
						*************************************************************/
414

    
415
						break;
416
					}
417
				}
418
				m_loopState = 0;
419

    
420
				if (siRetCode != 0) {
421
					/*************************************************************
422
					*                                                            *
423
					* Return if the complete status error.                       *
424
					*                                                            *
425
					*************************************************************/
426
#ifdef DEBUG
427
					fprintf(stderr, "ERR2 ");
428
#endif
429
					return (siRetCode);
430
				}
431
				break;
432
			case ENDLOOP:
433
				/*************************************************************
434
				*                                                            *
435
				* End the current loop.                                      *
436
				*                                                            *
437
				*************************************************************/
438
#ifdef DEBUG
439
				fprintf(stderr, "ENDLOOP ");
440
#endif
441
				printData(ucOpcode);
442
				if(m_loopState)
443
					return siRetCode;
444
				break;
445
			case ENDVME:
446
				/*************************************************************
447
				*                                                            *
448
				* If the ENDVME token is found and g_iMovingAlgoIndex is     *
449
				* greater than or equal to g_iAlgoSize, then that indicates  *
450
				* the end of the chain.  If g_iMovingAlgoIndex is less than  *
451
				* g_iAlgoSize, then that indicates that there are still more *
452
				* devices to be processed.                                   *
453
				*                                                            *
454
				*************************************************************/
455
				printData(ucOpcode);
456
				if (g_iMovingAlgoIndex >= g_ispAlgoSize)
457
				{
458
					return siRetCode;
459
				}
460
				break;
461
			case LCOUNT:
462
				/*************************************************************
463
				*                                                            *
464
				* Get the Maximum LoopCount and store in global variable.    *
465
				*                                                            *
466
				*************************************************************/
467
				printData(ucOpcode);
468
				ispVMLCOUNT((unsigned short) ispVMDataSize(1));
469
				break;
470
			case LDELAY:
471
				/*************************************************************
472
				*                                                            *
473
				* Get the State,TCK number and Delay time for the poling loop*
474
				* and store in global variable.                              *
475
				*                                                            *
476
				*************************************************************/
477
				printData(ucOpcode);
478
				ispVMLDELAY();
479
				break;
480
			case LSDR:
481
				/*************************************************************
482
				*                                                            *
483
				* Execute repeat poling status loop.                         *
484
				*                                                            *
485
				*************************************************************/
486
				printData(ucOpcode);
487
				iMovingAlgoIndex = g_iMovingAlgoIndex;
488
				for (iLoopCount = 0; iLoopCount < g_usLCOUNTSize; iLoopCount++)
489
				{
490
					siRetCode = ispVMShift(SDR);
491
					if (!siRetCode)
492
					{
493
						break;
494
					}
495
					/*************************************************************
496
					*                                                            *
497
					* If the status is not done, then move to the setting State  *
498
					* execute the delay and come back and do the checking again  *
499
					*                                                            *
500
					*************************************************************/
501
					g_iMovingAlgoIndex = iMovingAlgoIndex;
502
					ispVMStateMachine(DRPAUSE);
503
					m_loopState = 1;
504
					ispVMStateMachine(g_ucLDELAYState);
505
					m_loopState = 0;
506
					ispVMClocks(g_ucLDELAYTCK);
507
					ispVMDelay(g_ucLDELAYDelay);	
508
				}
509
				if (siRetCode != 0)
510
				{
511
					return (siRetCode);
512
				}
513
				break;
514
			case signalENABLE:
515
				/******************************************************************
516
				* Toggle ispENABLE signal                                         *
517
				*                                                                 *
518
				******************************************************************/
519
				printData(ucOpcode);
520
				ucState = GetByte(g_iMovingAlgoIndex++, 1, 1);
521
				if (ucState == 0x01)
522
					writePort(pinENABLE, 0x01);
523
				else
524
					writePort(pinENABLE, 0x00);
525
				ispVMDelay(1);
526
				break;	
527
			case signalTRST:
528
				/******************************************************************
529
				* Toggle TRST signal                                              *
530
				*                                                                 *
531
				******************************************************************/
532
				printData(ucOpcode);
533
				ucState = GetByte(g_iMovingAlgoIndex++, 1, 1);
534
				if (ucState == 0x01)
535
					writePort(pinTRST, 0x01);
536
				else
537
					writePort(pinTRST, 0x00);
538
				ispVMDelay(1);
539
				break;
540
			default:
541
				/*************************************************************
542
				*                                                            *
543
				* Unrecognized opcode.  Return with file error.              *
544
				*                                                            *
545
				*************************************************************/
546
				return ERR_ALGO_FILE_ERROR;
547
		}
548
		
549
		if (siRetCode < 0)
550
		{
551
			return siRetCode;
552
		}
553
	}
554
	
555
	return ERR_ALGO_FILE_ERROR;
556
}
557

    
558
/*************************************************************
559
*                                                            *
560
* ISPVMDATASIZE                                              *
561
*                                                            *
562
* INPUT:                                                     *
563
*                                                            *
564
* RETURN:                                                    *
565
*     This function returns a number indicating the size of  *
566
*     the instruction.                                       *
567
*                                                            *
568
* DESCRIPTION:                                               *
569
*     This function returns a number.  The number is the     *
570
*     value found in SVF commands such as SDR, SIR, HIR, and *
571
*     etc.  For example:                                     *
572
*               SDR 200 TDI(FFF..F);                         *
573
*     The return value would be 200.                         *
574
*                                                            *
575
*************************************************************/
576

    
577
unsigned int ispVMDataSize(int output)
578
{
579
	unsigned int uiSize = 0;
580
	unsigned char ucCurrentByte = 0;
581
	unsigned char ucIndex = 0;
582
	
583
	while ((ucCurrentByte = GetByte(g_iMovingAlgoIndex++, 1, output)) & 0x80)
584
	{
585
		uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
586
		ucIndex += 7;
587
	}
588
	uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
589
	return uiSize;
590
}
591

    
592
/*************************************************************
593
*                                                            *
594
* ISPVMSHIFTEXEC                                             *
595
*                                                            *
596
* INPUT:                                                     *
597
*     a_uiDataSize: this holds the size of the command.      *
598
*                                                            *
599
* RETURN:                                                    *
600
*     Returns 0 if passing, -1 if failing.                   *
601
*                                                            *
602
* DESCRIPTION:                                               *
603
*     This function handles the data in the SIR/SDR commands *
604
*     by either decompressing the data or setting the        *
605
*     respective indexes to point to the appropriate         *
606
*     location in the algo or data array.  Note that data    *
607
*     only comes after TDI, DTDI, TDO, DTDO, and MASK.       *
608
*                                                            *
609
*************************************************************/
610

    
611
short int ispVMShiftExec(unsigned int a_uiDataSize)
612
{
613
	unsigned char ucDataByte = 0;
614
	
615
	/*************************************************************
616
	*                                                            *
617
	* Reset the data type register.                              *
618
	*                                                            *
619
	*************************************************************/
620
	
621
	g_usDataType &= ~(TDI_DATA + TDO_DATA + MASK_DATA + DTDI_DATA + DTDO_DATA + COMPRESS_FRAME);
622
	
623
	/*************************************************************
624
	*                                                            *
625
	* Convert the size from bits to byte.                        *
626
	*                                                            *
627
	*************************************************************/
628
	
629
	if (a_uiDataSize % 8)
630
	{
631
		a_uiDataSize = a_uiDataSize / 8 + 1;
632
	}
633
	else 
634
	{
635
		a_uiDataSize = a_uiDataSize / 8;
636
	}
637
	
638
	/*************************************************************
639
	*                                                            *
640
	* Begin extracting the command.                              *
641
	*                                                            *
642
	*************************************************************/
643
	
644
	while ((ucDataByte = GetByte(g_iMovingAlgoIndex++, 1, 1)) != CONTINUE)
645
	{ 
646
		switch (ucDataByte)
647
		{
648
		case TDI:
649
		/*************************************************************
650
		*                                                            *
651
		* Set data type register to indicate TDI data and set TDI    *
652
		* index to the current algorithm location.                   *
653
		*                                                            *
654
		*************************************************************/
655
			g_usDataType |= TDI_DATA;
656
			g_iTDIIndex = g_iMovingAlgoIndex;
657
			g_iMovingAlgoIndex += a_uiDataSize;
658
			break;
659
		case DTDI:
660
		/*************************************************************
661
		*                                                            *
662
		* Set data type register to indicate DTDI data and check the *
663
		* next byte to make sure it's the DATA byte.  DTDI indicates *
664
		* that the data should be read from the data array, not the  *
665
		* algo array.                                                *
666
		*                                                            *
667
		*************************************************************/
668
			g_usDataType |= DTDI_DATA;
669
			if (GetByte(g_iMovingAlgoIndex++, 1, 1) != DATA)
670
			{
671
				return ERR_ALGO_FILE_ERROR;
672
			}
673
			
674
			/*************************************************************
675
			*                                                            *
676
			* If the COMPRESS flag is set, read the next byte from the   *
677
			* data file array.  If the byte is true, then that indicates *
678
			* the frame was compressable.  Note that even though the     *
679
			* overall data file was compressed, certain frames may not   *
680
			* be compressable that is why this byte must be checked.     *
681
			*                                                            *
682
			*************************************************************/
683
			if (g_usDataType & COMPRESS)
684
			{
685
				if (GetByte(g_iMovingDataIndex++, 0, 1))
686
				{
687
					g_usDataType |= COMPRESS_FRAME;
688
				}
689
			}
690
			break;
691
		case TDO:
692
		/*************************************************************
693
		*                                                            *
694
		* Set data type register to indicate TDO data and set TDO    *
695
		* index to the current algorithm location.                   *
696
		*                                                            *
697
		*************************************************************/
698
			g_usDataType |= TDO_DATA;
699
			g_iTDOIndex = g_iMovingAlgoIndex;
700
			g_iMovingAlgoIndex += a_uiDataSize;
701
			break;
702
		case DTDO:
703
		/*************************************************************
704
		*                                                            *
705
		* Set data type register to indicate DTDO data and check the *
706
		* next byte to make sure it's the DATA byte.  DTDO indicates *
707
		* that the data should be read from the data array, not the  *
708
		* algo array.                                                *
709
		*                                                            *
710
		*************************************************************/
711
			g_usDataType |= DTDO_DATA;
712
			if (GetByte(g_iMovingAlgoIndex++, 1, 1) != DATA)
713
			{
714
				return ERR_ALGO_FILE_ERROR;
715
			}
716
			
717
			/*************************************************************
718
			*                                                            *
719
			* If the COMPRESS flag is set, read the next byte from the   *
720
			* data file array.  If the byte is true, then that indicates *
721
			* the frame was compressable.  Note that even though the     *
722
			* overall data file was compressed, certain frames may not   *
723
			* be compressable that is why this byte must be checked.     *
724
			*                                                            *
725
			*************************************************************/
726
			if (g_usDataType & COMPRESS)
727
			{
728
				if (GetByte(g_iMovingDataIndex++, 0, 1))
729
				{
730
					g_usDataType |= COMPRESS_FRAME;
731
				}
732
			}
733
			break;
734
		case MASK:
735
		/*************************************************************
736
		*                                                            *
737
		* Set data type register to indicate MASK data.  Set MASK    *
738
		* location index to current algorithm array position.        *
739
		*                                                            *
740
		*************************************************************/
741
			g_usDataType |= MASK_DATA;
742
			g_iMASKIndex = g_iMovingAlgoIndex;
743
			g_iMovingAlgoIndex += a_uiDataSize;
744
			break;
745
		default:
746
		/*************************************************************
747
		*                                                            *
748
		* Unrecognized or misplaced opcode.  Return error.           *
749
		*                                                            *
750
		*************************************************************/
751
			return ERR_ALGO_FILE_ERROR;
752
		}
753
	}  
754
	
755
	/*************************************************************
756
	*                                                            *
757
	* Reached the end of the instruction.  Return passing.       *
758
	*                                                            *
759
	*************************************************************/
760
	
761
	return 0;
762
}
763

    
764
/*************************************************************
765
*                                                            *
766
* ISPVMSHIFT                                                 *
767
*                                                            *
768
* INPUT:                                                     *
769
*     a_cCommand: this argument specifies either the SIR or  *
770
*     SDR command.                                           *
771
*                                                            *
772
* RETURN:                                                    *
773
*     The return value indicates whether the SIR/SDR was     *
774
*     processed successfully or not.  A return value equal   *
775
*     to or greater than 0 is passing, and less than 0 is    *
776
*     failing.                                               *
777
*                                                            *
778
* DESCRIPTION:                                               *
779
*     This function is the entry point to execute an SIR or  *
780
*     SDR command to the device.                             *
781
*                                                            *
782
*************************************************************/
783

    
784
short int ispVMShift(char a_cCommand)
785
{
786
	short int siRetCode = 0;
787
	unsigned int uiDataSize = ispVMDataSize(1);
788
	
789
	/*************************************************************
790
	*                                                            *
791
	* Clear any existing SIR/SDR instructions from the data type *
792
	* register.                                                  *
793
	*                                                            *
794
	*************************************************************/
795
	
796
	g_usDataType &= ~(SIR_DATA + SDR_DATA);
797
	
798
	/*************************************************************
799
	*                                                            *
800
	* Move state machine to appropriate state depending on the   *
801
	* command.  Issue bypass if needed.                          *
802
	*                                                            *
803
	*************************************************************/
804
	
805
	switch (a_cCommand)
806
	{
807
	case SIR:
808
	/*************************************************************
809
	*                                                            *
810
	* Set the data type register to indicate that it's executing *
811
	* an SIR instruction.  Move state machine to IRPAUSE,        *
812
	* SHIFTIR.  If header instruction register exists, then      *
813
	* issue bypass.                                              *
814
	*                                                           *
815
	*************************************************************/
816
		g_usDataType |= SIR_DATA;
817
		ispVMStateMachine(IRPAUSE);
818
		ispVMStateMachine(SHIFTIR);
819
		if (g_siHeadIR > 0)
820
		{ 
821
			ispVMBypass(g_siHeadIR);
822
			sclock();
823
		}
824
		break;
825
	case SDR:
826
	/*************************************************************
827
	*                                                            *
828
	* Set the data type register to indicate that it's executing *
829
	* an SDR instruction.  Move state machine to DRPAUSE,        *
830
	* SHIFTDR.  If header data register exists, then issue       *
831
	* bypass.                                                    *
832
	*                                                            *
833
	*************************************************************/
834
		g_usDataType |= SDR_DATA;
835
		ispVMStateMachine(DRPAUSE);
836
		ispVMStateMachine(SHIFTDR);
837
		if (g_siHeadDR > 0)
838
		{
839
			ispVMBypass(g_siHeadDR);
840
			sclock();
841
		}
842
		break;
843
	}
844
	
845
	/*************************************************************
846
	*                                                            *
847
	* Set the appropriate index locations.  If error then return *
848
	* error code immediately.                                    *
849
	*                                                            *
850
	*************************************************************/
851
	
852
	siRetCode = ispVMShiftExec(uiDataSize);
853
	
854
	if (siRetCode < 0)
855
	{
856
		return siRetCode;
857
	}
858
	
859
	/*************************************************************
860
	*                                                            *
861
	* Execute the command to the device.  If TDO exists, then    *
862
	* read from the device and verify.  Else only TDI exists     *
863
	* which must send data to the device only.                   *
864
	*                                                            *
865
	*************************************************************/
866
	
867
	if ((g_usDataType & TDO_DATA) ||(g_usDataType & DTDO_DATA))
868
	{
869
		siRetCode = ispVMRead(uiDataSize);
870
		/*************************************************************
871
		*                                                            *
872
		* A frame of data has just been read and verified.  If the   *
873
		* DTDO_DATA flag is set, then check to make sure the next    *
874
		* byte in the data array, which is the last byte of the      *
875
		* frame, is the END_FRAME byte.                              *
876
		*                                                            *
877
		*************************************************************/
878
		if (g_usDataType & DTDO_DATA)
879
		{
880
			if (GetByte(g_iMovingDataIndex++, 0, 1) != END_FRAME)
881
			{
882
				siRetCode = ERR_DATA_FILE_ERROR;
883
			}
884
		}
885
	}
886
	else 
887
	{
888
		ispVMSend(uiDataSize);
889
		/*************************************************************
890
		*                                                            *
891
		* A frame of data has just been sent.  If the DTDI_DATA flag *
892
		* is set, then check to make sure the next byte in the data  *
893
		* array, which is the last byte of the frame, is the         *
894
		* END_FRAME byte.                                            *
895
		*                                                            *
896
		*************************************************************/
897
		if (g_usDataType & DTDI_DATA)
898
		{
899
			if (GetByte(g_iMovingDataIndex++, 0, 1) != END_FRAME)
900
			{
901
				siRetCode = ERR_DATA_FILE_ERROR;
902
			}
903
		}
904
	}
905
	
906
	/*************************************************************
907
	*                                                            *
908
	* Bypass trailer if it exists.  Move state machine to        *
909
	* ENDIR/ENDDR state.                                         *
910
	*                                                            *
911
	*************************************************************/
912
	
913
	switch (a_cCommand)
914
	{
915
	case SIR:
916
		if (g_siTailIR > 0)
917
		{
918
			sclock();
919
			ispVMBypass(g_siTailIR);
920
		}
921
		ispVMStateMachine(g_cEndIR);
922
		break;
923
    case SDR:  
924
		if (g_siTailDR > 0)
925
		{
926
			sclock();
927
			ispVMBypass(g_siTailDR);
928
		}
929
		ispVMStateMachine(g_cEndDR);
930
		break;
931
	}
932
	
933
	return siRetCode;
934
}
935

    
936
/*************************************************************
937
*                                                            *
938
* GETBYTE                                                    *
939
*                                                            *
940
* INPUT:                                                     *
941
*     a_iCurrentIndex: the current index to access.          *
942
*                                                            *
943
*     a_cAlgo: 1 if the return byte is to be retrieved from  *
944
*     the algorithm array, 0 if the byte is to be retrieved  *
945
*     from the data array.                                   *
946
*                                                            *
947
* RETURN:                                                    *
948
*     This function returns a byte of data from either the   *
949
*     algorithm or data array.  It returns -1 if out of      *
950
*     bounds.                                                *
951
*                                                            *
952
*************************************************************/
953

    
954
void printData(unsigned char d)
955
{
956
	outofs++;
957
	printf("%c", d);
958
#ifdef DEBUG
959
	fprintf(stderr, "%02x ", d);
960
#endif
961
}
962

    
963
unsigned char GetByte(int a_iCurrentIndex, char a_cAlgo, int output)
964
{
965
	unsigned char res;
966

    
967
	if (a_cAlgo)
968
	{ 
969
	/*************************************************************
970
	*                                                            *
971
	* If the current index is still within range, then return    *
972
	* the next byte.  If it is out of range, then return -1.     *
973
	*                                                            *
974
	*************************************************************/
975
		if(a_iCurrentIndex >= g_ispAlgoSize)
976
			res = 0xff;
977
		else res = g_ispAlgo[a_iCurrentIndex];
978
	}
979
	else 
980
	{
981
	/*************************************************************
982
	*                                                            *
983
	* If the current index is still within range, then return    *
984
	* the next byte.  If it is out of range, then return -1.     *
985
	*                                                            *
986
	*************************************************************/
987
		if((a_iCurrentIndex & 1023) == 0)
988
			fprintf(stderr, "%d bytes done (%d%%)\n", a_iCurrentIndex, (a_iCurrentIndex * 100) / g_ispDataSize);
989
		if(a_iCurrentIndex >= g_ispDataSize)
990
			res = 0xff;
991
		else res = g_ispData[a_iCurrentIndex];
992
	}
993
	if(output)
994
		printData(res);
995
	return res;
996
}
997

    
998
/*************************************************************
999
*                                                            *
1000
* SCLOCK                                                     *
1001
*                                                            *
1002
* INPUT:                                                     *
1003
*     None.                                                  *
1004
*                                                            *
1005
* RETURN:                                                    *
1006
*     None.                                                  *
1007
*                                                            *
1008
* DESCRIPTION:                                               *
1009
*     This function applies a HLL pulse to TCK.              *
1010
*                                                            *
1011
*************************************************************/
1012

    
1013
void sclock()
1014
{
1015
/*************************************************************
1016
*                                                            *
1017
* Set TCK to HIGH, LOW, LOW.                                 *
1018
*                                                            *
1019
*************************************************************/
1020

    
1021
	writePort(pinTCK, 0x01);
1022
	writePort(pinTCK, 0x00);
1023
	writePort(pinTCK, 0x00);
1024
}
1025

    
1026
/*************************************************************
1027
*                                                            *
1028
* ISPVMREAD                                                  *
1029
*                                                            *
1030
* INPUT:                                                     *
1031
*     a_uiDataSize: this argument is the size of the         *
1032
*     command.                                               *
1033
*                                                            *
1034
* RETURN:                                                    *
1035
*     The return value is 0 if passing, and -1 if failing.   *
1036
*                                                            *
1037
* DESCRIPTION:                                               *
1038
*     This function reads a data stream from the device and  *
1039
*     compares it to the expected TDO.                       *
1040
*                                                            *
1041
*************************************************************/
1042

    
1043
short int ispVMRead(unsigned int a_uiDataSize)
1044
{
1045
	unsigned int uiIndex = 0;
1046
	unsigned short usErrorCount = 0;
1047
	unsigned char ucTDIByte = 0;
1048
	unsigned char ucTDOByte = 0;
1049
	unsigned char ucMaskByte = 0;
1050
	unsigned char ucCurBit = 0;
1051
	
1052
	for (uiIndex = 0;uiIndex < a_uiDataSize; uiIndex++)
1053
	{ 
1054
		if (uiIndex % 8 == 0)
1055
		{
1056
			if ( g_usDataType & TDI_DATA ) {
1057
				/*************************************************************
1058
				*                                                            *
1059
				* If the TDI_DATA flag is set, then grab the next byte from  *
1060
				* the algo array and increment the TDI index.                *
1061
				*                                                            *
1062
				*************************************************************/
1063
				ucTDIByte = GetByte( g_iTDIIndex++, 1, 1);
1064
			}
1065
			else
1066
			{
1067
				ucTDIByte = 0xFF;
1068
			}
1069
			if (g_usDataType & TDO_DATA)
1070
			{
1071
			/*************************************************************
1072
			*                                                            *
1073
			* If the TDO_DATA flag is set, then grab the next byte from  *
1074
			* the algo array and increment the TDO index.                *
1075
			*                                                            *
1076
			*************************************************************/
1077
				ucTDOByte = GetByte(g_iTDOIndex++, 1, 1);
1078
			}
1079
			else 
1080
			{
1081
			/*************************************************************
1082
			*                                                            *
1083
			* If TDO_DATA is not set, then DTDO_DATA must be set.  If    *
1084
			* the compression counter exists, then the next TDO byte     *
1085
			* must be 0xFF.  If it doesn't exist, then get next byte     *
1086
			* from data file array.                                      *
1087
			*                                                            *
1088
			*************************************************************/
1089
				if (g_ucCompressCounter)
1090
				{
1091
					g_ucCompressCounter--;
1092
					ucTDOByte =(unsigned char) 0xFF;
1093
				}
1094
				else 
1095
				{
1096
					ucTDOByte = GetByte(g_iMovingDataIndex++, 0, 1);
1097
					
1098
					/*************************************************************
1099
					*                                                            *
1100
					* If the frame is compressed and the byte is 0xFF, then the  *
1101
					* next couple bytes must be read to determine how many       *
1102
					* repetitions of 0xFF are there.  That value will be stored  *
1103
					* in the variable g_ucCompressCounter.                       *
1104
					*                                                            *
1105
					*************************************************************/
1106
					if ((g_usDataType & COMPRESS_FRAME) &&(ucTDOByte ==(unsigned char) 0xFF))
1107
					{
1108
						g_ucCompressCounter = GetByte(g_iMovingDataIndex++, 0, 1);
1109
						g_ucCompressCounter--;
1110
					}
1111
				}
1112
			}
1113
			
1114
			if (g_usDataType & MASK_DATA)
1115
			{
1116
				ucMaskByte = GetByte(g_iMASKIndex++, 1, 1);
1117
			}
1118
			else 
1119
			{ 
1120
				ucMaskByte =(unsigned char) 0xFF;
1121
			}
1122
		}
1123
		(void)ucMaskByte;
1124

    
1125

    
1126
		//ucCurBit = readPort();
1127
		ucCurBit = 0;
1128
		
1129
		if ((((ucMaskByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
1130
		{	
1131
			if (ucCurBit !=(unsigned char)(((ucTDOByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
1132
			{
1133
				//usErrorCount++;
1134
			}
1135
		}
1136

    
1137
		/*************************************************************
1138
		*                                                            *
1139
		* Always shift 0x01 into TDI pin when reading.               *
1140
		*                                                            *
1141
		*************************************************************/
1142
		
1143
		writePort(pinTDI, (unsigned char) (((ucTDIByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00));
1144
		
1145
		if (uiIndex < a_uiDataSize - 1)
1146
		{
1147
			sclock();
1148
		}
1149
	}
1150
	
1151
	if (usErrorCount > 0)
1152
	{
1153
		return -1;
1154
	}
1155
	
1156
	return 0;
1157
}
1158

    
1159
/*************************************************************
1160
*                                                            *
1161
* ISPVMSEND                                                  *
1162
*                                                            *
1163
* INPUT:                                                     *
1164
*     a_uiDataSize: this argument is the size of the         *
1165
*     command.                                               *
1166
*                                                            *
1167
* RETURN:                                                    *
1168
*     None.                                                  *
1169
*                                                            *
1170
* DESCRIPTION:                                               *
1171
*     This function sends a data stream to the device.       *
1172
*                                                            *
1173
*************************************************************/
1174

    
1175
void ispVMSend(unsigned int a_uiDataSize)
1176
{
1177
	unsigned int iIndex;
1178
	unsigned char ucCurByte = 0;
1179
	unsigned char ucBitState = 0;
1180
	
1181
	/*************************************************************
1182
	*                                                            *
1183
	* Begin processing the data to the device.                   *
1184
	*                                                            *
1185
	*************************************************************/
1186
	
1187
	for (iIndex = 0;iIndex < a_uiDataSize; iIndex++)
1188
	{ 
1189
		if (iIndex % 8 == 0)
1190
		{ 
1191
			if (g_usDataType & TDI_DATA)
1192
			{
1193
			/*************************************************************
1194
			*                                                            *
1195
			* If the TDI_DATA flag is set, then grab the next byte from  *
1196
			* the algo array and increment the TDI index.                *
1197
			*                                                            *
1198
			*************************************************************/
1199
				ucCurByte = GetByte(g_iTDIIndex++, 1, 1);
1200
			}
1201
			else 
1202
			{
1203
			/*************************************************************
1204
			*                                                            *
1205
			* If TDI_DATA flag is not set, then DTDI_DATA flag must have *
1206
			* already been set.  If the compression counter exists, then *
1207
			* the next TDI byte must be 0xFF.  If it doesn't exist, then *
1208
			* get next byte from data file array.                        *
1209
			*                                                            *
1210
			*************************************************************/
1211
				if (g_ucCompressCounter)
1212
				{
1213
					g_ucCompressCounter--;
1214
					ucCurByte =(unsigned char) 0xFF;
1215
				}
1216
				else 
1217
				{
1218
					ucCurByte = GetByte(g_iMovingDataIndex++, 0, 1);
1219
					
1220
					/*************************************************************
1221
					*                                                            *
1222
					* If the frame is compressed and the byte is 0xFF, then the  *
1223
					* next couple bytes must be read to determine how many       *
1224
					* repetitions of 0xFF are there.  That value will be stored  *
1225
					* in the variable g_ucCompressCounter.                       *
1226
					*                                                            *
1227
					*************************************************************/
1228
					
1229
					if ((g_usDataType & COMPRESS_FRAME) &&(ucCurByte ==(unsigned char) 0xFF))
1230
					{
1231
						g_ucCompressCounter = GetByte(g_iMovingDataIndex++, 0, 1);
1232
						g_ucCompressCounter--;
1233
					}
1234
				}
1235
			}
1236
		}
1237
		
1238
		ucBitState =(unsigned char)(((ucCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00);
1239
		writePort(pinTDI, ucBitState);
1240
		
1241
		if (iIndex < a_uiDataSize - 1)
1242
		{
1243
			sclock();
1244
		}
1245
	}
1246
}
1247

    
1248
/*************************************************************
1249
*                                                            *
1250
* ISPVMSTATEMACHINE                                          *
1251
*                                                            *
1252
* INPUT:                                                     *
1253
*     a_cNextState: this is the opcode of the next JTAG      *
1254
*     state.                                                 *
1255
*                                                            *
1256
* RETURN:                                                    *
1257
*     This functions returns 0 when passing, and -1 when     *
1258
*     failure occurs.                                        *
1259
*                                                            *
1260
* DESCRIPTION:                                               *
1261
*     This function is called to move the device into        *
1262
*     different JTAG states.                                 *
1263
*                                                            *
1264
*************************************************************/
1265

    
1266
void ispVMStateMachine(char a_cNextState)
1267
{
1268
	int cPathIndex, cStateIndex;
1269
	if ((g_cCurrentJTAGState == DRPAUSE) &&(a_cNextState== DRPAUSE) && m_loopState)
1270
	{
1271
	} 
1272
	else if ((g_cCurrentJTAGState == a_cNextState) &&(g_cCurrentJTAGState != RESET))
1273
	{
1274
		return;
1275
	}
1276
	
1277
	for (cStateIndex = 0;cStateIndex < 25; cStateIndex++)
1278
	{
1279
		if ((g_cCurrentJTAGState == iStates[cStateIndex].CurState) &&(a_cNextState == iStates[cStateIndex].NextState))
1280
		{
1281
			break;
1282
		}
1283
	}	
1284
	g_cCurrentJTAGState = a_cNextState;
1285
	for (cPathIndex = 0;cPathIndex < iStates[cStateIndex].Pulses; cPathIndex++)
1286
	{
1287
		if ((iStates[cStateIndex].Pattern << cPathIndex) & 0x80)
1288
		{
1289
			writePort(pinTMS, (unsigned char) 0x01);
1290
		}
1291
		else 
1292
		{
1293
			writePort(pinTMS, (unsigned char) 0x00);
1294
		}
1295
		sclock();
1296
	}
1297
	
1298
	writePort(pinTDI, 0x00);
1299
	writePort(pinTMS, 0x00);
1300
}
1301

    
1302
/*************************************************************
1303
*                                                            *
1304
* ISPVMCLOCKS                                                *
1305
*                                                            *
1306
* INPUT:                                                     *
1307
*     a_usClocks: number of clocks to apply.                 *
1308
*                                                            *
1309
* RETURN:                                                    *
1310
*     None.                                                  *
1311
*                                                            *
1312
* DESCRIPTION:                                               *
1313
*    This procedure applies the specified number of pulses   *
1314
*    to TCK.                                                 *
1315
*                                                            *
1316
*************************************************************/
1317

    
1318
void ispVMClocks(unsigned int a_uiClocks)
1319
{	
1320
	for (; a_uiClocks > 0; a_uiClocks--)
1321
	{
1322
		sclock();
1323
	}
1324
}
1325

    
1326
/*************************************************************
1327
*                                                            *
1328
* ISPVMBYPASS                                                *
1329
*                                                            *
1330
* INPUT:                                                     *
1331
*     a_siLength: this argument is the length of the         *
1332
*     command.                                               *
1333
*                                                            *
1334
* RETURN:                                                    *
1335
*     None.                                                  *
1336
*                                                            *
1337
* DESCRIPTION:                                               *
1338
*     This function takes care of the HIR, HDR, TIR, and TDR *
1339
*     for the purpose of putting the other devices into      *
1340
*     bypass mode.                                           *
1341
*                                                            *
1342
*************************************************************/
1343

    
1344
void ispVMBypass(unsigned int a_uiLength)
1345
{
1346
/*************************************************************
1347
*                                                            *
1348
* Issue a_siLength number of 0x01 to the TDI pin to bypass.  *
1349
*                                                            *
1350
*************************************************************/
1351
	
1352
	for (; a_uiLength > 1; a_uiLength--)
1353
	{
1354
		writePort(pinTDI, (char) 0x01);
1355
		sclock();
1356
	}
1357
	
1358
	writePort(pinTDI, (char) 0x01);
1359
}
1360
/*************************************************************
1361
*                                                            *
1362
* ispVMLCOUNT                                                *
1363
*                                                            *
1364
* INPUT:                                                     *
1365
*     a_usCountSize: The maximum number of loop required to  *
1366
*     poling the status                                      *
1367
*                                                            *
1368
*                                                            *
1369
* DESCRIPTION:                                               *
1370
*     This function is set the maximum loop count            *
1371
*                                                            *
1372
*************************************************************/
1373

    
1374
void ispVMLCOUNT(unsigned short a_usCountSize)
1375
{
1376
	g_usLCOUNTSize = a_usCountSize;
1377
}
1378
/*************************************************************
1379
*                                                            *
1380
* ispVMLDELAY                                                *
1381
*                                                            *
1382
*                                                            *
1383
* DESCRIPTION:                                               *
1384
*     This function is set the delay state, number of TCK and* 
1385
*  the delay time for poling the status                      *
1386
*                                                            *
1387
*************************************************************/
1388
void ispVMLDELAY()
1389
{
1390
	g_ucLDELAYState = IDLE;
1391
	g_ucLDELAYDelay = 0;
1392
	g_ucLDELAYTCK   = 0;
1393
	while (1)
1394
	{
1395
		unsigned char bytedata = GetByte(g_iMovingAlgoIndex++, 1, 1);
1396
		switch (bytedata)
1397
		{
1398
		case STATE: /*step BSCAN state machine to specified state*/
1399
			g_ucLDELAYState = GetByte(g_iMovingAlgoIndex++, 1, 1);
1400
			break;
1401
		case WAIT:  /*opcode to wait for specified time in us or ms*/ 
1402
			g_ucLDELAYDelay = (short int) ispVMDataSize(1);
1403
			break;
1404
		case TCK:   /*pulse TCK signal the specified time*/
1405
			g_ucLDELAYTCK = (short int) ispVMDataSize(1);
1406
			break;
1407
		case ENDSTATE:
1408
			return;
1409
			break;
1410
		}
1411
	}
1412
}
(5-5/8)
Add picture from clipboard (Maximum size: 48.8 MB)