Project

General

Profile

Download (49.7 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 <utility/trace.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
uint8_t fpgaGetByte();
35
unsigned int ispVMDataSize();
36
short int ispVMShiftExec(unsigned int a_uiDataSize);
37
short int ispVMShift(char a_cCommand);
38
void ispVMStateMachine(char a_cNextState);
39
void ispVMClocks(unsigned int a_usClocks);
40
void ispVMBypass(unsigned int a_siLength);
41
void sclock();
42
short int ispVMRead(unsigned int a_uiDataSize);
43
void ispVMSend(unsigned int a_uiDataSize);
44
void ispVMLCOUNT(unsigned short a_usCountSize);
45
void ispVMLDELAY();
46
/*************************************************************
47
*                                                            *
48
* EXTERNAL FUNCTION                                          *
49
*                                                            *
50
*************************************************************/
51

    
52
extern void ispVMDelay(unsigned int a_usDelay);
53
extern int readPort();
54
extern void writePort(unsigned int a_ucPins, unsigned int a_ucValue);
55

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

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

    
79
static short int g_siIspPins = 0x00;   /*** holds the current byte to be sent to the hardware ***/
80
static char g_cCurrentJTAGState = 0;	/*** holds the current state of JTAG state machine ***/
81

    
82
static int  g_iLoopIndex = 0;
83
static int  g_iLoopMovingIndex = 0;	/*** Used to point to the location of LOOP data ***/
84
static int  g_iLoopDataMovingIndex = 0;
85

    
86
static unsigned short g_usLCOUNTSize	= 0;
87
static unsigned char  g_ucLDELAYState = IDLE;
88
static unsigned short int  g_ucLDELAYTCK = 0;
89
static unsigned short int  g_ucLDELAYDelay = 0;
90
static unsigned short int m_loopState = 0;
91

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

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

    
163

    
164
static short int g_lastRetCode;
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
	
182
	if ((ucOpcode = fpgaGetByte()) != 0xFF)
183
	{
184
		//TRACE_INFO_WP("[%02x]", ucOpcode);
185
		/*************************************************************
186
		*                                                            *
187
		* This switch statement is the main switch that represents   *
188
		* the core of the embedded processor.                        *
189
		*                                                            *
190
		*************************************************************/
191
		
192
		switch (ucOpcode)
193
		{
194
		case STATE:
195
			/*************************************************************
196
			*                                                            *
197
			* Move the state.                                            *
198
			*                                                            *
199
			*************************************************************/	
200
			ispVMStateMachine(fpgaGetByte());
201
			break;
202
		case SIR:
203
		case SDR:
204
			/*************************************************************
205
			*                                                            *
206
			* Execute SIR/SDR command.                                   *
207
			*                                                            *
208
			*************************************************************/
209
			siRetCode = ispVMShift(ucOpcode);
210
			break;
211
		case TCK:
212
			/*************************************************************
213
			*                                                            *
214
			* Pulse TCK signal the specified time.                       *
215
			*                                                            *
216
			*************************************************************/
217
			ispVMClocks(ispVMDataSize());
218
			break;
219
		case WAIT:
220
			/*************************************************************
221
			*                                                            *
222
			* Issue delay in specified time.                             *
223
			*                                                            *
224
			*************************************************************/
225
			ispVMDelay(ispVMDataSize());
226
			break;
227
		case ENDDR:
228
			/*************************************************************
229
			*                                                            *
230
			* Get the ENDDR state and store in global variable.          *
231
			*                                                            *
232
			*************************************************************/
233
			g_cEndDR = fpgaGetByte();
234
			break;
235
		case ENDIR:
236
			/*************************************************************
237
			*                                                            *
238
			* Get the ENDIR state and store in global variable.          *
239
			*                                                            *
240
			*************************************************************/
241
			g_cEndIR = fpgaGetByte();
242
			break;
243
		case HIR:
244
			g_siHeadIR = (short int) ispVMDataSize();
245
			break;
246
		case TIR:
247
			g_siTailIR = (short int) ispVMDataSize();		
248
			break;
249
		case HDR:
250
			g_siHeadDR = (short int) ispVMDataSize();
251
			break;
252
		case TDR:
253
			g_siTailDR = (short int) ispVMDataSize();
254
			break;
255
			
256
		case BEGIN_REPEAT:
257
			siRetCode = ERR_ALGO_FILE_ERROR;
258
			break;
259
		case END_REPEAT:
260
				/*************************************************************
261
				*                                                            *
262
				* Exit the current repeat frame.                             *
263
				*                                                            *
264
				*************************************************************/
265
			siRetCode = ERR_ALGO_FILE_ERROR;
266
			break;
267

    
268
		case LOOP:
269
			/*************************************************************
270
			*                                                            *
271
			* Execute repeat loop.                                       *
272
			*                                                            *
273
			*************************************************************/
274
			g_usLCOUNTSize = (short int)ispVMDataSize();
275
#ifdef VME_DEBUG
276
			fprintf(stderr,  "MaxLoopCount %d\n", g_usLCOUNTSize );
277
#endif
278
			/*************************************************************
279
			*                                                            *
280
			* Set the repeat index to the first byte in the repeat loop. *
281
			*                                                            *
282
			*************************************************************/
283

    
284
			fpgaPushAddr();
285
			g_iLoopIndex = 0;
286
			m_loopState = 1;
287

    
288
#if 0
289
			for ( g_iLoopIndex = 0 ; g_iLoopIndex < g_usLCOUNTSize; g_iLoopIndex++ ) {
290
				m_loopState = 1;
291
				/*************************************************************
292
				*                                                            *
293
				* Initialize the current algorithm index to the beginning of *
294
				* the repeat index before each repeat loop.                  *
295
				*                                                            *
296
				*************************************************************/
297

    
298
				g_iMovingAlgoIndex = g_iLoopMovingIndex;
299
				g_iMovingDataIndex = g_iLoopDataMovingIndex;
300

    
301

    
302
				/*************************************************************
303
				*                                                            *
304
				* Make recursive call.                                       *
305
				*                                                            *
306
				*************************************************************/
307

    
308
				fprintf(stderr, "I:%d ", g_iLoopIndex);
309
				siRetCode = ispProcessVME();
310
				if (!siRetCode) {
311
					fprintf(stderr, "OK ", siRetCode);
312
					/*************************************************************
313
					*                                                            *
314
					* Stop if the complete status matched.                       *
315
					*                                                            *
316
					*************************************************************/
317

    
318
					break;
319
				}
320
			}
321
			m_loopState = 0;
322

    
323
			if (siRetCode != 0) {
324
				/*************************************************************
325
				*                                                            *
326
				* Return if the complete status error.                       *
327
				*                                                            *
328
				*************************************************************/
329
				fprintf(stderr, "ERR2 ");
330
				return (siRetCode);
331
			}
332
#endif
333
			break;
334

    
335
		case ENDLOOP:
336
			/*************************************************************
337
			*                                                            *
338
			* End the current loop.                                      *
339
			*                                                            *
340
			*************************************************************/
341
			if(m_loopState) {
342
				if(g_lastRetCode == 0) {
343
					m_loopState = 0;
344
					break;
345
				} else {
346
					if(g_iLoopIndex < g_usLCOUNTSize) {
347
						g_iLoopIndex++;
348
						fpgaPopAddr();
349
					} else {
350
						return -1;
351
					}
352
				}
353
			}
354
			break;
355

    
356
		case ENDVME:
357
			/*************************************************************
358
			*                                                            *
359
			* If the ENDVME token is found and g_iMovingAlgoIndex is     *
360
			* greater than or equal to g_iAlgoSize, then that indicates  *
361
			* the end of the chain.  If g_iMovingAlgoIndex is less than  *
362
			* g_iAlgoSize, then that indicates that there are still more *
363
			* devices to be processed.                                   *
364
			*                                                            *
365
			*************************************************************/
366
			TRACE_INFO("DFU: ENDVME\n\r");
367
			return siRetCode;
368
			break;
369
		case LCOUNT:
370
			/*************************************************************
371
			*                                                            *
372
			* Get the Maximum LoopCount and store in global variable.    *
373
			*                                                            *
374
			*************************************************************/
375
			ispVMLCOUNT((unsigned short) ispVMDataSize());
376
			break;
377
		case LDELAY:
378
			/*************************************************************
379
			*                                                            *
380
			* Get the State,TCK number and Delay time for the poling loop*
381
			* and store in global variable.                              *
382
			*                                                            *
383
			*************************************************************/
384
			ispVMLDELAY();
385
			break;
386
		case LSDR:
387
			/*************************************************************
388
			*                                                            *
389
			* Execute repeat poling status loop.                         *
390
			*                                                            *
391
			*************************************************************/
392
			iMovingAlgoIndex = g_iMovingAlgoIndex;
393
			for (iLoopCount = 0; iLoopCount < g_usLCOUNTSize; iLoopCount++)
394
			{
395
				siRetCode = ispVMShift(SDR);
396
				if (!siRetCode)
397
				{
398
					break;
399
				}
400
				/*************************************************************
401
				*                                                            *
402
				* If the status is not done, then move to the setting State  *
403
				* execute the delay and come back and do the checking again  *
404
				*                                                            *
405
				*************************************************************/
406
				g_iMovingAlgoIndex = iMovingAlgoIndex;
407
				ispVMStateMachine(DRPAUSE);
408
				m_loopState = 1;
409
				ispVMStateMachine(g_ucLDELAYState);
410
				m_loopState = 0;
411
				ispVMClocks(g_ucLDELAYTCK);
412
				ispVMDelay(g_ucLDELAYDelay);
413
			}
414
			if (siRetCode != 0)
415
			{
416
				return (siRetCode);
417
			}
418
			break;
419
		case signalENABLE:
420
			/******************************************************************
421
			* Toggle ispENABLE signal                                         *
422
			*                                                                 *
423
			******************************************************************/
424
			ucState = fpgaGetByte();
425
			if (ucState == 0x01)
426
				writePort(pinENABLE, 0x01);
427
			else
428
				writePort(pinENABLE, 0x00);
429
			ispVMDelay(1);
430
			break;
431
		case signalTRST:
432
			/******************************************************************
433
			* Toggle TRST signal                                              *
434
			*                                                                 *
435
			******************************************************************/
436
			ucState = fpgaGetByte();
437
			if (ucState == 0x01)
438
				writePort(pinTRST, 0x01);
439
			else
440
				writePort(pinTRST, 0x00);
441
			ispVMDelay(1);
442
			break;
443
		default:
444
			/*************************************************************
445
			*                                                            *
446
			* Unrecognized opcode.  Return with file error.              *
447
			*                                                            *
448
			*************************************************************/
449
			return ERR_ALGO_FILE_ERROR;
450
		}
451
		
452
		g_lastRetCode = siRetCode;
453

    
454
		if (siRetCode < 0)
455
		{
456
			if(m_loopState)
457
				return 0;
458
			else return siRetCode;
459
		}
460
	}
461
	
462
	return 0;
463
}
464

    
465
/*************************************************************
466
*                                                            *
467
* ISPVMDATASIZE                                              *
468
*                                                            *
469
* INPUT:                                                     *
470
*     None.                                                  *
471
*                                                            *
472
* RETURN:                                                    *
473
*     This function returns a number indicating the size of  *
474
*     the instruction.                                       *
475
*                                                            *
476
* DESCRIPTION:                                               *
477
*     This function returns a number.  The number is the     *
478
*     value found in SVF commands such as SDR, SIR, HIR, and *
479
*     etc.  For example:                                     *
480
*               SDR 200 TDI(FFF..F);                         *
481
*     The return value would be 200.                         *
482
*                                                            *
483
*************************************************************/
484

    
485
unsigned int ispVMDataSize()
486
{
487
	unsigned int uiSize = 0;
488
	unsigned char ucCurrentByte = 0;
489
	unsigned char ucIndex = 0;
490
	
491
	while ((ucCurrentByte = fpgaGetByte()) & 0x80)
492
	{
493
		uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
494
		ucIndex += 7;
495
	}
496
	uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
497
	return uiSize;
498
}
499

    
500
/*************************************************************
501
*                                                            *
502
* ISPVMSHIFTEXEC                                             *
503
*                                                            *
504
* INPUT:                                                     *
505
*     a_uiDataSize: this holds the size of the command.      *
506
*                                                            *
507
* RETURN:                                                    *
508
*     Returns 0 if passing, -1 if failing.                   *
509
*                                                            *
510
* DESCRIPTION:                                               *
511
*     This function handles the data in the SIR/SDR commands *
512
*     by either decompressing the data or setting the        *
513
*     respective indexes to point to the appropriate         *
514
*     location in the algo or data array.  Note that data    *
515
*     only comes after TDI, DTDI, TDO, DTDO, and MASK.       *
516
*                                                            *
517
*************************************************************/
518

    
519
short int ispVMShiftExec(unsigned int a_uiDataSize)
520
{
521
	unsigned char ucDataByte = 0;
522
	
523
	/*************************************************************
524
	*                                                            *
525
	* Reset the data type register.                              *
526
	*                                                            *
527
	*************************************************************/
528
	
529
	g_usDataType &= ~(TDI_DATA + TDO_DATA + MASK_DATA + DTDI_DATA + DTDO_DATA + COMPRESS_FRAME);
530
	
531
	/*************************************************************
532
	*                                                            *
533
	* Convert the size from bits to byte.                        *
534
	*                                                            *
535
	*************************************************************/
536
	
537
	if (a_uiDataSize % 8)
538
	{
539
		a_uiDataSize = a_uiDataSize / 8 + 1;
540
	}
541
	else 
542
	{
543
		a_uiDataSize = a_uiDataSize / 8;
544
	}
545
	
546
	/*************************************************************
547
	*                                                            *
548
	* Begin extracting the command.                              *
549
	*                                                            *
550
	*************************************************************/
551
	
552
	while ((ucDataByte = fpgaGetByte()) != CONTINUE)
553
	{ 
554
		switch (ucDataByte)
555
		{
556
		case TDI:
557
		/*************************************************************
558
		*                                                            *
559
		* Set data type register to indicate TDI data and set TDI    *
560
		* index to the current algorithm location.                   *
561
		*                                                            *
562
		*************************************************************/
563
			g_usDataType |= TDI_DATA;
564
			g_iTDIIndex = g_iMovingAlgoIndex;
565
			g_iMovingAlgoIndex += a_uiDataSize;
566
			break;
567
		case DTDI:
568
		/*************************************************************
569
		*                                                            *
570
		* Set data type register to indicate DTDI data and check the *
571
		* next byte to make sure it's the DATA byte.  DTDI indicates *
572
		* that the data should be read from the data array, not the  *
573
		* algo array.                                                *
574
		*                                                            *
575
		*************************************************************/
576
			g_usDataType |= DTDI_DATA;
577
			if (fpgaGetByte() != DATA)
578
			{
579
				return ERR_ALGO_FILE_ERROR;
580
			}
581
			
582
			/*************************************************************
583
			*                                                            *
584
			* If the COMPRESS flag is set, read the next byte from the   *
585
			* data file array.  If the byte is true, then that indicates *
586
			* the frame was compressable.  Note that even though the     *
587
			* overall data file was compressed, certain frames may not   *
588
			* be compressable that is why this byte must be checked.     *
589
			*                                                            *
590
			*************************************************************/
591
			if (g_usDataType & COMPRESS)
592
			{
593
				if (fpgaGetByte())
594
				{
595
					g_usDataType |= COMPRESS_FRAME;
596
				}
597
			}
598
			break;
599
		case TDO:
600
		/*************************************************************
601
		*                                                            *
602
		* Set data type register to indicate TDO data and set TDO    *
603
		* index to the current algorithm location.                   *
604
		*                                                            *
605
		*************************************************************/
606
			g_usDataType |= TDO_DATA;
607
			g_iTDOIndex = g_iMovingAlgoIndex;
608
			g_iMovingAlgoIndex += a_uiDataSize;
609
			break;
610
		case DTDO:
611
		/*************************************************************
612
		*                                                            *
613
		* Set data type register to indicate DTDO data and check the *
614
		* next byte to make sure it's the DATA byte.  DTDO indicates *
615
		* that the data should be read from the data array, not the  *
616
		* algo array.                                                *
617
		*                                                            *
618
		*************************************************************/
619
			g_usDataType |= DTDO_DATA;
620
			if (fpgaGetByte() != DATA)
621
			{
622
				return ERR_ALGO_FILE_ERROR;
623
			}
624
			
625
			/*************************************************************
626
			*                                                            *
627
			* If the COMPRESS flag is set, read the next byte from the   *
628
			* data file array.  If the byte is true, then that indicates *
629
			* the frame was compressable.  Note that even though the     *
630
			* overall data file was compressed, certain frames may not   *
631
			* be compressable that is why this byte must be checked.     *
632
			*                                                            *
633
			*************************************************************/
634
			if (g_usDataType & COMPRESS)
635
			{
636
				if (fpgaGetByte())
637
				{
638
					g_usDataType |= COMPRESS_FRAME;
639
				}
640
			}
641
			break;
642
		case MASK:
643
		/*************************************************************
644
		*                                                            *
645
		* Set data type register to indicate MASK data.  Set MASK    *
646
		* location index to current algorithm array position.        *
647
		*                                                            *
648
		*************************************************************/
649
			g_usDataType |= MASK_DATA;
650
			g_iMASKIndex = g_iMovingAlgoIndex;
651
			g_iMovingAlgoIndex += a_uiDataSize;
652
			break;
653
		default:
654
		/*************************************************************
655
		*                                                            *
656
		* Unrecognized or misplaced opcode.  Return error.           *
657
		*                                                            *
658
		*************************************************************/
659
			return ERR_ALGO_FILE_ERROR;
660
		}
661
	}  
662
	
663
	/*************************************************************
664
	*                                                            *
665
	* Reached the end of the instruction.  Return passing.       *
666
	*                                                            *
667
	*************************************************************/
668
	
669
	return 0;
670
}
671

    
672
/*************************************************************
673
*                                                            *
674
* ISPVMSHIFT                                                 *
675
*                                                            *
676
* INPUT:                                                     *
677
*     a_cCommand: this argument specifies either the SIR or  *
678
*     SDR command.                                           *
679
*                                                            *
680
* RETURN:                                                    *
681
*     The return value indicates whether the SIR/SDR was     *
682
*     processed successfully or not.  A return value equal   *
683
*     to or greater than 0 is passing, and less than 0 is    *
684
*     failing.                                               *
685
*                                                            *
686
* DESCRIPTION:                                               *
687
*     This function is the entry point to execute an SIR or  *
688
*     SDR command to the device.                             *
689
*                                                            *
690
*************************************************************/
691

    
692
short int ispVMShift(char a_cCommand)
693
{
694
	short int siRetCode = 0;
695
	unsigned int uiDataSize = ispVMDataSize();
696
	
697
	/*************************************************************
698
	*                                                            *
699
	* Clear any existing SIR/SDR instructions from the data type *
700
	* register.                                                  *
701
	*                                                            *
702
	*************************************************************/
703
	
704
	g_usDataType &= ~(SIR_DATA + SDR_DATA);
705
	
706
	/*************************************************************
707
	*                                                            *
708
	* Move state machine to appropriate state depending on the   *
709
	* command.  Issue bypass if needed.                          *
710
	*                                                            *
711
	*************************************************************/
712
	
713
	switch (a_cCommand)
714
	{
715
	case SIR:
716
	/*************************************************************
717
	*                                                            *
718
	* Set the data type register to indicate that it's executing *
719
	* an SIR instruction.  Move state machine to IRPAUSE,        *
720
	* SHIFTIR.  If header instruction register exists, then      *
721
	* issue bypass.                                              *
722
	*                                                           *
723
	*************************************************************/
724
		g_usDataType |= SIR_DATA;
725
		ispVMStateMachine(IRPAUSE);
726
		ispVMStateMachine(SHIFTIR);
727
		if (g_siHeadIR > 0)
728
		{ 
729
			ispVMBypass(g_siHeadIR);
730
			sclock();
731
		}
732
		break;
733
	case SDR:
734
	/*************************************************************
735
	*                                                            *
736
	* Set the data type register to indicate that it's executing *
737
	* an SDR instruction.  Move state machine to DRPAUSE,        *
738
	* SHIFTDR.  If header data register exists, then issue       *
739
	* bypass.                                                    *
740
	*                                                            *
741
	*************************************************************/
742
		g_usDataType |= SDR_DATA;
743
		ispVMStateMachine(DRPAUSE);
744
		ispVMStateMachine(SHIFTDR);
745
		if (g_siHeadDR > 0)
746
		{
747
			ispVMBypass(g_siHeadDR);
748
			sclock();
749
		}
750
		break;
751
	}
752
	
753
	/*************************************************************
754
	*                                                            *
755
	* Set the appropriate index locations.  If error then return *
756
	* error code immediately.                                    *
757
	*                                                            *
758
	*************************************************************/
759
	
760
	siRetCode = ispVMShiftExec(uiDataSize);
761
	
762
	if (siRetCode < 0)
763
	{
764
		return siRetCode;
765
	}
766
	
767
	/*************************************************************
768
	*                                                            *
769
	* Execute the command to the device.  If TDO exists, then    *
770
	* read from the device and verify.  Else only TDI exists     *
771
	* which must send data to the device only.                   *
772
	*                                                            *
773
	*************************************************************/
774
	
775
	if ((g_usDataType & TDO_DATA) ||(g_usDataType & DTDO_DATA))
776
	{
777
		siRetCode = ispVMRead(uiDataSize);
778
		/*************************************************************
779
		*                                                            *
780
		* A frame of data has just been read and verified.  If the   *
781
		* DTDO_DATA flag is set, then check to make sure the next    *
782
		* byte in the data array, which is the last byte of the      *
783
		* frame, is the END_FRAME byte.                              *
784
		*                                                            *
785
		*************************************************************/
786
		if (g_usDataType & DTDO_DATA)
787
		{
788
			if (fpgaGetByte() != END_FRAME)
789
			{
790
				siRetCode = ERR_DATA_FILE_ERROR;
791
			}
792
		}
793
	}
794
	else 
795
	{
796
		ispVMSend(uiDataSize);
797
		/*************************************************************
798
		*                                                            *
799
		* A frame of data has just been sent.  If the DTDI_DATA flag *
800
		* is set, then check to make sure the next byte in the data  *
801
		* array, which is the last byte of the frame, is the         *
802
		* END_FRAME byte.                                            *
803
		*                                                            *
804
		*************************************************************/
805
		if (g_usDataType & DTDI_DATA)
806
		{
807
			if (fpgaGetByte() != END_FRAME)
808
			{
809
				siRetCode = ERR_DATA_FILE_ERROR;
810
			}
811
		}
812
	}
813
	
814
	/*************************************************************
815
	*                                                            *
816
	* Bypass trailer if it exists.  Move state machine to        *
817
	* ENDIR/ENDDR state.                                         *
818
	*                                                            *
819
	*************************************************************/
820
	
821
	switch (a_cCommand)
822
	{
823
	case SIR:
824
		if (g_siTailIR > 0)
825
		{
826
			sclock();
827
			ispVMBypass(g_siTailIR);
828
		}
829
		ispVMStateMachine(g_cEndIR);
830
		break;
831
    case SDR:  
832
		if (g_siTailDR > 0)
833
		{
834
			sclock();
835
			ispVMBypass(g_siTailDR);
836
		}
837
		ispVMStateMachine(g_cEndDR);
838
		break;
839
	}
840
	
841
	return siRetCode;
842
}
843

    
844
/*************************************************************
845
*                                                            *
846
* SCLOCK                                                     *
847
*                                                            *
848
* INPUT:                                                     *
849
*     None.                                                  *
850
*                                                            *
851
* RETURN:                                                    *
852
*     None.                                                  *
853
*                                                            *
854
* DESCRIPTION:                                               *
855
*     This function applies a HLL pulse to TCK.              *
856
*                                                            *
857
*************************************************************/
858

    
859
void sclock()
860
{
861
/*************************************************************
862
*                                                            *
863
* Set TCK to HIGH, LOW, LOW.                                 *
864
*                                                            *
865
*************************************************************/
866
	
867
	writePort(pinTCK, 0x01);
868
	writePort(pinTCK, 0x00);
869
	writePort(pinTCK, 0x00);
870
}
871

    
872
/*************************************************************
873
*                                                            *
874
* ISPVMREAD                                                  *
875
*                                                            *
876
* INPUT:                                                     *
877
*     a_uiDataSize: this argument is the size of the         *
878
*     command.                                               *
879
*                                                            *
880
* RETURN:                                                    *
881
*     The return value is 0 if passing, and -1 if failing.   *
882
*                                                            *
883
* DESCRIPTION:                                               *
884
*     This function reads a data stream from the device and  *
885
*     compares it to the expected TDO.                       *
886
*                                                            *
887
*************************************************************/
888

    
889
short int ispVMRead(unsigned int a_uiDataSize)
890
{
891
	unsigned int uiIndex = 0;
892
	unsigned short usErrorCount = 0;
893
	unsigned char ucTDIByte = 0;
894
	unsigned char ucTDOByte = 0;
895
	unsigned char ucMaskByte = 0;
896
	unsigned char ucCurBit = 0;
897
	
898
	for (uiIndex = 0;uiIndex < a_uiDataSize; uiIndex++)
899
	{ 
900
		if (uiIndex % 8 == 0)
901
		{
902
			if ( g_usDataType & TDI_DATA ) {
903
				/*************************************************************
904
				*                                                            *
905
				* If the TDI_DATA flag is set, then grab the next byte from  *
906
				* the algo array and increment the TDI index.                *
907
				*                                                            *
908
				*************************************************************/
909
				ucTDIByte = fpgaGetByte();
910
			}
911
			else
912
			{
913
				ucTDIByte = 0xFF;
914
			}
915
			if (g_usDataType & TDO_DATA)
916
			{
917
			/*************************************************************
918
			*                                                            *
919
			* If the TDO_DATA flag is set, then grab the next byte from  *
920
			* the algo array and increment the TDO index.                *
921
			*                                                            *
922
			*************************************************************/
923
				ucTDOByte = fpgaGetByte();
924
			}
925
			else 
926
			{
927
			/*************************************************************
928
			*                                                            *
929
			* If TDO_DATA is not set, then DTDO_DATA must be set.  If    *
930
			* the compression counter exists, then the next TDO byte     *
931
			* must be 0xFF.  If it doesn't exist, then get next byte     *
932
			* from data file array.                                      *
933
			*                                                            *
934
			*************************************************************/
935
				if (g_ucCompressCounter)
936
				{
937
					g_ucCompressCounter--;
938
					ucTDOByte =(unsigned char) 0xFF;
939
				}
940
				else 
941
				{
942
					ucTDOByte = fpgaGetByte();
943
					
944
					/*************************************************************
945
					*                                                            *
946
					* If the frame is compressed and the byte is 0xFF, then the  *
947
					* next couple bytes must be read to determine how many       *
948
					* repetitions of 0xFF are there.  That value will be stored  *
949
					* in the variable g_ucCompressCounter.                       *
950
					*                                                            *
951
					*************************************************************/
952
					if ((g_usDataType & COMPRESS_FRAME) &&(ucTDOByte ==(unsigned char) 0xFF))
953
					{
954
						g_ucCompressCounter = fpgaGetByte();
955
						g_ucCompressCounter--;
956
					}
957
				}
958
			}
959
			
960
			if (g_usDataType & MASK_DATA)
961
			{
962
				ucMaskByte = fpgaGetByte();
963
			}
964
			else 
965
			{ 
966
				ucMaskByte =(unsigned char) 0xFF;
967
			}
968
		}
969
		
970
		ucCurBit = readPort();
971
		
972
		if ((((ucMaskByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
973
		{	
974
			if (ucCurBit != (((ucTDOByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
975
			{
976
				usErrorCount++;  
977
			}
978
		}
979
		
980
		/*************************************************************
981
		*                                                            *
982
		* Always shift 0x01 into TDI pin when reading.               *
983
		*                                                            *
984
		*************************************************************/
985
		
986
		writePort(pinTDI, (unsigned char) (((ucTDIByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00));
987
		
988
		if (uiIndex < a_uiDataSize - 1)
989
		{
990
			sclock();
991
		}
992
	}
993
	
994
	if (usErrorCount > 0)
995
	{
996
		return -1;
997
	}
998
	
999
	return 0;
1000
}
1001

    
1002
/*************************************************************
1003
*                                                            *
1004
* ISPVMSEND                                                  *
1005
*                                                            *
1006
* INPUT:                                                     *
1007
*     a_uiDataSize: this argument is the size of the         *
1008
*     command.                                               *
1009
*                                                            *
1010
* RETURN:                                                    *
1011
*     None.                                                  *
1012
*                                                            *
1013
* DESCRIPTION:                                               *
1014
*     This function sends a data stream to the device.       *
1015
*                                                            *
1016
*************************************************************/
1017

    
1018
void ispVMSend(unsigned int a_uiDataSize)
1019
{
1020
	unsigned int iIndex;
1021
	unsigned char ucCurByte = 0;
1022
	unsigned char ucBitState = 0;
1023
	
1024
	/*************************************************************
1025
	*                                                            *
1026
	* Begin processing the data to the device.                   *
1027
	*                                                            *
1028
	*************************************************************/
1029
	
1030
	for (iIndex = 0;iIndex < a_uiDataSize; iIndex++)
1031
	{ 
1032
		if (iIndex % 8 == 0)
1033
		{ 
1034
			if (g_usDataType & TDI_DATA)
1035
			{
1036
			/*************************************************************
1037
			*                                                            *
1038
			* If the TDI_DATA flag is set, then grab the next byte from  *
1039
			* the algo array and increment the TDI index.                *
1040
			*                                                            *
1041
			*************************************************************/
1042
				ucCurByte = fpgaGetByte();
1043
			}
1044
			else 
1045
			{
1046
			/*************************************************************
1047
			*                                                            *
1048
			* If TDI_DATA flag is not set, then DTDI_DATA flag must have *
1049
			* already been set.  If the compression counter exists, then *
1050
			* the next TDI byte must be 0xFF.  If it doesn't exist, then *
1051
			* get next byte from data file array.                        *
1052
			*                                                            *
1053
			*************************************************************/
1054
				if (g_ucCompressCounter)
1055
				{
1056
					g_ucCompressCounter--;
1057
					ucCurByte =(unsigned char) 0xFF;
1058
				}
1059
				else 
1060
				{
1061
					ucCurByte = fpgaGetByte();
1062
					
1063
					/*************************************************************
1064
					*                                                            *
1065
					* If the frame is compressed and the byte is 0xFF, then the  *
1066
					* next couple bytes must be read to determine how many       *
1067
					* repetitions of 0xFF are there.  That value will be stored  *
1068
					* in the variable g_ucCompressCounter.                       *
1069
					*                                                            *
1070
					*************************************************************/
1071
					
1072
					if ((g_usDataType & COMPRESS_FRAME) &&(ucCurByte ==(unsigned char) 0xFF))
1073
					{
1074
						g_ucCompressCounter = fpgaGetByte();
1075
						g_ucCompressCounter--;
1076
					}
1077
				}
1078
			}
1079
		}
1080
		
1081
		ucBitState =(unsigned char)(((ucCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00);
1082
		writePort(pinTDI, ucBitState);
1083
		
1084
		if (iIndex < a_uiDataSize - 1)
1085
		{
1086
			sclock();
1087
		}
1088
	}
1089
}
1090

    
1091
/*************************************************************
1092
*                                                            *
1093
* ISPVMSTATEMACHINE                                          *
1094
*                                                            *
1095
* INPUT:                                                     *
1096
*     a_cNextState: this is the opcode of the next JTAG      *
1097
*     state.                                                 *
1098
*                                                            *
1099
* RETURN:                                                    *
1100
*     This functions returns 0 when passing, and -1 when     *
1101
*     failure occurs.                                        *
1102
*                                                            *
1103
* DESCRIPTION:                                               *
1104
*     This function is called to move the device into        *
1105
*     different JTAG states.                                 *
1106
*                                                            *
1107
*************************************************************/
1108

    
1109
void ispVMStateMachine(char a_cNextState)
1110
{
1111
	int cPathIndex, cStateIndex;
1112
	if ((g_cCurrentJTAGState == DRPAUSE) &&(a_cNextState== DRPAUSE) && m_loopState)
1113
	{
1114
	} 
1115
	else if ((g_cCurrentJTAGState == a_cNextState) &&(g_cCurrentJTAGState != RESET))
1116
	{
1117
		return;
1118
	}
1119
	
1120
	for (cStateIndex = 0;cStateIndex < 25; cStateIndex++)
1121
	{
1122
		if ((g_cCurrentJTAGState == iStates[cStateIndex].CurState) &&(a_cNextState == iStates[cStateIndex].NextState))
1123
		{
1124
			break;
1125
		}
1126
	}	
1127
	g_cCurrentJTAGState = a_cNextState;
1128
	for (cPathIndex = 0;cPathIndex < iStates[cStateIndex].Pulses; cPathIndex++)
1129
	{
1130
		if ((iStates[cStateIndex].Pattern << cPathIndex) & 0x80)
1131
		{
1132
			writePort(pinTMS, (unsigned char) 0x01);
1133
		}
1134
		else 
1135
		{
1136
			writePort(pinTMS, (unsigned char) 0x00);
1137
		}
1138
		sclock();
1139
	}
1140
	
1141
	writePort(pinTDI, 0x00);
1142
	writePort(pinTMS, 0x00);
1143
}
1144

    
1145
/*************************************************************
1146
*                                                            *
1147
* ISPVMCLOCKS                                                *
1148
*                                                            *
1149
* INPUT:                                                     *
1150
*     a_usClocks: number of clocks to apply.                 *
1151
*                                                            *
1152
* RETURN:                                                    *
1153
*     None.                                                  *
1154
*                                                            *
1155
* DESCRIPTION:                                               *
1156
*    This procedure applies the specified number of pulses   *
1157
*    to TCK.                                                 *
1158
*                                                            *
1159
*************************************************************/
1160

    
1161
void ispVMClocks(unsigned int a_uiClocks)
1162
{	
1163
	for (; a_uiClocks > 0; a_uiClocks--)
1164
	{
1165
		sclock();
1166
	}
1167
}
1168

    
1169
/*************************************************************
1170
*                                                            *
1171
* ISPVMBYPASS                                                *
1172
*                                                            *
1173
* INPUT:                                                     *
1174
*     a_siLength: this argument is the length of the         *
1175
*     command.                                               *
1176
*                                                            *
1177
* RETURN:                                                    *
1178
*     None.                                                  *
1179
*                                                            *
1180
* DESCRIPTION:                                               *
1181
*     This function takes care of the HIR, HDR, TIR, and TDR *
1182
*     for the purpose of putting the other devices into      *
1183
*     bypass mode.                                           *
1184
*                                                            *
1185
*************************************************************/
1186

    
1187
void ispVMBypass(unsigned int a_uiLength)
1188
{
1189
/*************************************************************
1190
*                                                            *
1191
* Issue a_siLength number of 0x01 to the TDI pin to bypass.  *
1192
*                                                            *
1193
*************************************************************/
1194
	
1195
	for (; a_uiLength > 1; a_uiLength--)
1196
	{
1197
		writePort(pinTDI, (char) 0x01);
1198
		sclock();
1199
	}
1200
	
1201
	writePort(pinTDI, (char) 0x01);
1202
}
1203
/*************************************************************
1204
*                                                            *
1205
* ispVMLCOUNT                                                *
1206
*                                                            *
1207
* INPUT:                                                     *
1208
*     a_usCountSize: The maximum number of loop required to  *
1209
*     poling the status                                      *
1210
*                                                            *
1211
*                                                            *
1212
* DESCRIPTION:                                               *
1213
*     This function is set the maximum loop count            *
1214
*                                                            *
1215
*************************************************************/
1216

    
1217
void ispVMLCOUNT(unsigned short a_usCountSize)
1218
{
1219
	g_usLCOUNTSize = a_usCountSize;
1220
}
1221
/*************************************************************
1222
*                                                            *
1223
* ispVMLDELAY                                                *
1224
*                                                            *
1225
*                                                            *
1226
* DESCRIPTION:                                               *
1227
*     This function is set the delay state, number of TCK and* 
1228
*  the delay time for poling the status                      *
1229
*                                                            *
1230
*************************************************************/
1231
void ispVMLDELAY()
1232
{
1233
	g_ucLDELAYState = IDLE;
1234
	g_ucLDELAYDelay = 0;
1235
	g_ucLDELAYTCK   = 0;
1236
	while (1)
1237
	{
1238
		unsigned char bytedata = fpgaGetByte();
1239
		switch (bytedata)
1240
		{
1241
		case STATE: /*step BSCAN state machine to specified state*/
1242
			g_ucLDELAYState = fpgaGetByte();
1243
			break;
1244
		case WAIT:  /*opcode to wait for specified time in us or ms*/ 
1245
			g_ucLDELAYDelay = (short int) ispVMDataSize();
1246
			break;
1247
		case TCK:   /*pulse TCK signal the specified time*/
1248
			g_ucLDELAYTCK = (short int) ispVMDataSize();
1249
			break;
1250
		case ENDSTATE:
1251
			return;
1252
			break;
1253
		}
1254
	}
1255
}
(9-9/11)
Add picture from clipboard (Maximum size: 48.8 MB)