Project

General

Profile

Download (55.2 KB) Statistics
| Branch: | Tag: | Revision:
1 4cd82c23 Christian Daniel
/**************************************************************
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
unsigned int ispVMDataSize();
35
short int ispVMShiftExec(unsigned int a_uiDataSize);
36
short int ispVMShift(char a_cCommand);
37
unsigned char GetByte(int a_iCurrentIndex, char a_cAlgo);
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 unsigned char readPort();
54
extern void writePort(unsigned char a_ucPins, unsigned char a_ucValue);
55
56
/*************************************************************
57
*                                                            *
58
* GLOBAL VARIABLES                                           *
59
*                                                            *
60
*************************************************************/
61
int g_iMovingAlgoIndex = 0;	    /*** variable to hold the current index in the algo array ***/
62
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
unsigned char g_cEndDR = 0;		/*** used to hold the ENDDR state. ***/
66
unsigned char g_cEndIR = 0;		/*** used to hold the ENDIR state. ***/
67
short int g_siHeadDR = 0;		/*** used to hold the header data register ***/
68
short int g_siHeadIR = 0;		/*** used to hold the header instruction register ***/
69
short int g_siTailDR = 0;		/*** used to hold the trailer data register ***/
70
short int g_siTailIR = 0;		/*** used to hold the trailer instruction register ***/
71
72
int g_iMainDataIndex = 0;		/*** forward - only index used as a placed holder in the data array ***/
73
int g_iRepeatIndex = 0;		    /*** Used to point to the location of REPEAT data ***/
74
int g_iTDIIndex = 0;			/*** Used to point to the location of TDI data ***/
75
int g_iTDOIndex = 0;			/*** Used to point to the location of TDO data ***/
76
int g_iMASKIndex = 0;			/*** Used to point to the location of MASK data ***/
77
unsigned char g_ucCompressCounter = 0; /*** used to indicate how many times 0xFF is repeated ***/
78
79
short int g_siIspPins = 0x00;   /*** holds the current byte to be sent to the hardware ***/
80
char g_cCurrentJTAGState = 0;	/*** holds the current state of JTAG state machine ***/
81
82
int  g_iLoopIndex = 0;			
83
int  g_iLoopMovingIndex = 0;	/*** Used to point to the location of LOOP data ***/
84
int  g_iLoopDataMovingIndex = 0;
85
86
unsigned short g_usLCOUNTSize	= 0;
87
unsigned char  g_ucLDELAYState = IDLE;
88
unsigned short int  g_ucLDELAYTCK = 0;
89
unsigned short int  g_ucLDELAYDelay = 0;
90
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
short int ispProcessVME() reentrant
164
{
165
	unsigned char ucOpcode        = 0;
166
	unsigned char ucState         = 0;
167
	short int siRetCode           = 0;
168
	static char cProgram          = 0;
169
	unsigned int uiDataSize       = 0;
170
	int iLoopCount                = 0;
171
	unsigned int iMovingAlgoIndex = 0;
172
	
173
	/*************************************************************
174
	*                                                            *
175
	* Begin processing the vme algorithm and data files.         *
176
	*                                                            *
177
	*************************************************************/
178
	
179
	while ((ucOpcode = GetByte(g_iMovingAlgoIndex++, 1)) != 0xFF) 
180
	{
181
		/*************************************************************
182
		*                                                            *
183
		* This switch statement is the main switch that represents   *
184
		* the core of the embedded processor.                        *
185
		*                                                            *
186
		*************************************************************/
187
		
188
		switch (ucOpcode)
189
		{
190
		case STATE:
191
			/*************************************************************
192
			*                                                            *
193
			* Move the state.                                            *
194
			*                                                            *
195
			*************************************************************/	
196
			ispVMStateMachine(GetByte(g_iMovingAlgoIndex++, 1));
197
			break;
198
		case SIR:
199
		case SDR:
200
			/*************************************************************
201
			*                                                            *
202
			* Execute SIR/SDR command.                                   *
203
			*                                                            *
204
			*************************************************************/
205
			siRetCode = ispVMShift(ucOpcode);
206
			break;
207
		case TCK:
208
			/*************************************************************
209
			*                                                            *
210
			* Pulse TCK signal the specified time.                       *
211
			*                                                            *
212
			*************************************************************/
213
			ispVMClocks(ispVMDataSize());
214
			break;
215
		case WAIT:
216
			/*************************************************************
217
			*                                                            *
218
			* Issue delay in specified time.                             *
219
			*                                                            *
220
			*************************************************************/
221
			ispVMDelay(ispVMDataSize());
222
			break;
223
		case ENDDR:
224
			/*************************************************************
225
			*                                                            *
226
			* Get the ENDDR state and store in global variable.          *
227
			*                                                            *
228
			*************************************************************/
229
			g_cEndDR = GetByte(g_iMovingAlgoIndex++, 1);	
230
			break;
231
		case ENDIR:
232
			/*************************************************************
233
			*                                                            *
234
			* Get the ENDIR state and store in global variable.          *
235
			*                                                            *
236
			*************************************************************/
237
			g_cEndIR = GetByte(g_iMovingAlgoIndex++, 1);
238
			break;
239
		case HIR:
240
			g_siHeadIR = (short int) ispVMDataSize();
241
			break;
242
		case TIR:
243
			g_siTailIR = (short int) ispVMDataSize();		
244
			break;
245
		case HDR:
246
			g_siHeadDR = (short int) ispVMDataSize();
247
							
248
			break;
249
		case TDR:
250
			g_siTailDR = (short int) ispVMDataSize();
251
			
252
			break;
253
		case BEGIN_REPEAT:
254
			/*************************************************************
255
			*                                                            *
256
			* Execute repeat loop.                                       *
257
			*                                                            *
258
			*************************************************************/
259
			
260
			uiDataSize = ispVMDataSize();
261
			
262
			switch (GetByte(g_iMovingAlgoIndex++, 1))
263
			{
264
			case PROGRAM:
265
				/*************************************************************
266
				*                                                            *
267
				* Set the main data index to the moving data index.  This    *
268
				* allows the processor to remember the beginning of the      *
269
				* data.  Set the cProgram variable to true to indicate to    *
270
				* the verify flow later that a programming flow has been     *
271
				* completed so the moving data index must return to the      *
272
				* main data index.                                           *
273
				*                                                            *
274
				*************************************************************/
275
				g_iMainDataIndex = g_iMovingDataIndex;
276
				cProgram = 1;
277
				break;
278
			case VERIFY:
279
				/*************************************************************
280
				*                                                            *
281
				* If the static variable cProgram has been set, then return  *
282
				* the moving data index to the main data index because this  *
283
				* is a erase, program, verify operation.  If the programming *
284
				* flag is not set, then this is a verify only operation thus *
285
				* no need to return the moving data index.                   *
286
				*                                                            *
287
				*************************************************************/
288
				if (cProgram)
289
				{
290
					g_iMovingDataIndex = g_iMainDataIndex;
291
					cProgram = 0;
292
				}
293
				break;
294
			}
295
			
296
			/*************************************************************
297
			*                                                            *
298
			* Set the repeat index to the first byte in the repeat loop. *
299
			*                                                            *
300
			*************************************************************/
301
			
302
			g_iRepeatIndex = g_iMovingAlgoIndex;
303
			
304
			for (; uiDataSize > 0; uiDataSize--)
305
			{
306
				/*************************************************************
307
				*                                                            *
308
				* Initialize the current algorithm index to the beginning of *
309
				* the repeat index before each repeat loop.                  *
310
				*                                                            *
311
				*************************************************************/
312
				
313
				g_iMovingAlgoIndex = g_iRepeatIndex;
314
				
315
				/*************************************************************
316
				*                                                            *
317
				* Make recursive call.                                       *
318
				*                                                            *
319
				*************************************************************/
320
				
321
				siRetCode = ispProcessVME();
322
				if (siRetCode < 0)
323
				{
324
					break;
325
				}
326
			}
327
			break;
328
			case END_REPEAT:
329
				/*************************************************************
330
				*                                                            *
331
				* Exit the current repeat frame.                             *
332
				*                                                            *
333
				*************************************************************/
334
					return siRetCode;
335
				break;
336
			case LOOP:
337
				/*************************************************************
338
				*                                                            *
339
				* Execute repeat loop.                                       *
340
				*                                                            *
341
				*************************************************************/
342
343
				g_usLCOUNTSize = (short int)ispVMDataSize();
344
345
#ifdef VME_DEBUG
346
				printf( "MaxLoopCount %d\n", g_usLCOUNTSize );
347
#endif
348
				/*************************************************************
349
				*                                                            *
350
				* Set the repeat index to the first byte in the repeat loop. *
351
				*                                                            *
352
				*************************************************************/
353
354
				g_iLoopMovingIndex = g_iMovingAlgoIndex;
355
				g_iLoopDataMovingIndex = g_iMovingDataIndex;
356
357
358
				for ( g_iLoopIndex = 0 ; g_iLoopIndex < g_usLCOUNTSize; g_iLoopIndex++ ) {
359
					m_loopState = 1;
360
					/*************************************************************
361
					*                                                            *
362
					* Initialize the current algorithm index to the beginning of *
363
					* the repeat index before each repeat loop.                  *
364
					*                                                            *
365
					*************************************************************/
366
367
					g_iMovingAlgoIndex = g_iLoopMovingIndex;
368
					g_iMovingDataIndex = g_iLoopDataMovingIndex;
369
370
371
					/*************************************************************
372
					*                                                            *
373
					* Make recursive call.                                       *
374
					*                                                            *
375
					*************************************************************/
376
377
					siRetCode = ispProcessVME();
378
					if ( !siRetCode ) {
379
						/*************************************************************
380
						*                                                            *
381
						* Stop if the complete status matched.                       *
382
						*                                                            *
383
						*************************************************************/
384
385
						break;
386
					}
387
				}
388
				m_loopState = 0;
389
390
				if (siRetCode != 0) {
391
					/*************************************************************
392
					*                                                            *
393
					* Return if the complete status error.                       *
394
					*                                                            *
395
					*************************************************************/
396
					return (siRetCode);
397
				}
398
				break;
399
			case ENDLOOP:
400
				/*************************************************************
401
				*                                                            *
402
				* End the current loop.                                      *
403
				*                                                            *
404
				*************************************************************/
405
				if(m_loopState)
406
					return siRetCode;
407
				break;
408
			case ENDVME:
409
				/*************************************************************
410
				*                                                            *
411
				* If the ENDVME token is found and g_iMovingAlgoIndex is     *
412
				* greater than or equal to g_iAlgoSize, then that indicates  *
413
				* the end of the chain.  If g_iMovingAlgoIndex is less than  *
414
				* g_iAlgoSize, then that indicates that there are still more *
415
				* devices to be processed.                                   *
416
				*                                                            *
417
				*************************************************************/
418
				if (g_iMovingAlgoIndex >= g_ispAlgoSize)
419
				{
420
					return siRetCode;
421
				}
422
				break;
423
			case LCOUNT:
424
				/*************************************************************
425
				*                                                            *
426
				* Get the Maximum LoopCount and store in global variable.    *
427
				*                                                            *
428
				*************************************************************/
429
				ispVMLCOUNT((unsigned short) ispVMDataSize());
430
				break;
431
			case LDELAY:
432
				/*************************************************************
433
				*                                                            *
434
				* Get the State,TCK number and Delay time for the poling loop*
435
				* and store in global variable.                              *
436
				*                                                            *
437
				*************************************************************/
438
				ispVMLDELAY();
439
				break;
440
			case LSDR:
441
				/*************************************************************
442
				*                                                            *
443
				* Execute repeat poling status loop.                         *
444
				*                                                            *
445
				*************************************************************/
446
				iMovingAlgoIndex = g_iMovingAlgoIndex;
447
				for (iLoopCount = 0; iLoopCount < g_usLCOUNTSize; iLoopCount++)
448
				{
449
					siRetCode = ispVMShift(SDR);
450
					if (!siRetCode)
451
					{
452
						break;
453
					}
454
					/*************************************************************
455
					*                                                            *
456
					* If the status is not done, then move to the setting State  *
457
					* execute the delay and come back and do the checking again  *
458
					*                                                            *
459
					*************************************************************/
460
					g_iMovingAlgoIndex = iMovingAlgoIndex;
461
					ispVMStateMachine(DRPAUSE);
462
					m_loopState = 1;
463
					ispVMStateMachine(g_ucLDELAYState);
464
					m_loopState = 0;
465
					ispVMClocks(g_ucLDELAYTCK);
466
					ispVMDelay(g_ucLDELAYDelay);	
467
				}
468
				if (siRetCode != 0)
469
				{
470
					return (siRetCode);
471
				}
472
				break;
473
			case signalENABLE:
474
				/******************************************************************
475
				* Toggle ispENABLE signal                                         *
476
				*                                                                 *
477
				******************************************************************/
478
				ucState = GetByte(g_iMovingAlgoIndex++, 1);
479
				if (ucState == 0x01)
480
					writePort(pinENABLE, 0x01);
481
				else
482
					writePort(pinENABLE, 0x00);
483
				ispVMDelay(1);
484
				break;	
485
			case signalTRST:
486
				/******************************************************************
487
				* Toggle TRST signal                                              *
488
				*                                                                 *
489
				******************************************************************/
490
				ucState = GetByte(g_iMovingAlgoIndex++, 1);
491
				if (ucState == 0x01)
492
					writePort(pinTRST, 0x01);
493
				else
494
					writePort(pinTRST, 0x00);
495
				ispVMDelay(1);
496
				break;
497
			default:
498
				/*************************************************************
499
				*                                                            *
500
				* Unrecognized opcode.  Return with file error.              *
501
				*                                                            *
502
				*************************************************************/
503
				return ERR_ALGO_FILE_ERROR;
504
		}
505
		
506
		if (siRetCode < 0)
507
		{
508
			return siRetCode;
509
		}
510
	}
511
	
512
	return ERR_ALGO_FILE_ERROR;
513
}
514
515
/*************************************************************
516
*                                                            *
517
* ISPVMDATASIZE                                              *
518
*                                                            *
519
* INPUT:                                                     *
520
*     None.                                                  *
521
*                                                            *
522
* RETURN:                                                    *
523
*     This function returns a number indicating the size of  *
524
*     the instruction.                                       *
525
*                                                            *
526
* DESCRIPTION:                                               *
527
*     This function returns a number.  The number is the     *
528
*     value found in SVF commands such as SDR, SIR, HIR, and *
529
*     etc.  For example:                                     *
530
*               SDR 200 TDI(FFF..F);                         *
531
*     The return value would be 200.                         *
532
*                                                            *
533
*************************************************************/
534
535
unsigned int ispVMDataSize()
536
{
537
	unsigned int uiSize = 0;
538
	unsigned char ucCurrentByte = 0;
539
	unsigned char ucIndex = 0;
540
	
541
	while ((ucCurrentByte = GetByte(g_iMovingAlgoIndex++, 1)) & 0x80) 
542
	{
543
		uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
544
		ucIndex += 7;
545
	}
546
	uiSize |=((unsigned int)(ucCurrentByte & 0x7F)) << ucIndex;
547
	return uiSize;
548
}
549
550
/*************************************************************
551
*                                                            *
552
* ISPVMSHIFTEXEC                                             *
553
*                                                            *
554
* INPUT:                                                     *
555
*     a_uiDataSize: this holds the size of the command.      *
556
*                                                            *
557
* RETURN:                                                    *
558
*     Returns 0 if passing, -1 if failing.                   *
559
*                                                            *
560
* DESCRIPTION:                                               *
561
*     This function handles the data in the SIR/SDR commands *
562
*     by either decompressing the data or setting the        *
563
*     respective indexes to point to the appropriate         *
564
*     location in the algo or data array.  Note that data    *
565
*     only comes after TDI, DTDI, TDO, DTDO, and MASK.       *
566
*                                                            *
567
*************************************************************/
568
569
short int ispVMShiftExec(unsigned int a_uiDataSize)
570
{
571
	unsigned char ucDataByte = 0;
572
	
573
	/*************************************************************
574
	*                                                            *
575
	* Reset the data type register.                              *
576
	*                                                            *
577
	*************************************************************/
578
	
579
	g_usDataType &= ~(TDI_DATA + TDO_DATA + MASK_DATA + DTDI_DATA + DTDO_DATA + COMPRESS_FRAME);
580
	
581
	/*************************************************************
582
	*                                                            *
583
	* Convert the size from bits to byte.                        *
584
	*                                                            *
585
	*************************************************************/
586
	
587
	if (a_uiDataSize % 8)
588
	{
589
		a_uiDataSize = a_uiDataSize / 8 + 1;
590
	}
591
	else 
592
	{
593
		a_uiDataSize = a_uiDataSize / 8;
594
	}
595
	
596
	/*************************************************************
597
	*                                                            *
598
	* Begin extracting the command.                              *
599
	*                                                            *
600
	*************************************************************/
601
	
602
	while ((ucDataByte = GetByte(g_iMovingAlgoIndex++, 1)) != CONTINUE) 
603
	{ 
604
		switch (ucDataByte)
605
		{
606
		case TDI:
607
		/*************************************************************
608
		*                                                            *
609
		* Set data type register to indicate TDI data and set TDI    *
610
		* index to the current algorithm location.                   *
611
		*                                                            *
612
		*************************************************************/
613
			g_usDataType |= TDI_DATA;
614
			g_iTDIIndex = g_iMovingAlgoIndex;
615
			g_iMovingAlgoIndex += a_uiDataSize;
616
			break;
617
		case DTDI:
618
		/*************************************************************
619
		*                                                            *
620
		* Set data type register to indicate DTDI data and check the *
621
		* next byte to make sure it's the DATA byte.  DTDI indicates *
622
		* that the data should be read from the data array, not the  *
623
		* algo array.                                                *
624
		*                                                            *
625
		*************************************************************/
626
			g_usDataType |= DTDI_DATA;
627
			if (GetByte(g_iMovingAlgoIndex++, 1) != DATA)
628
			{
629
				return ERR_ALGO_FILE_ERROR;
630
			}
631
			
632
			/*************************************************************
633
			*                                                            *
634
			* If the COMPRESS flag is set, read the next byte from the   *
635
			* data file array.  If the byte is true, then that indicates *
636
			* the frame was compressable.  Note that even though the     *
637
			* overall data file was compressed, certain frames may not   *
638
			* be compressable that is why this byte must be checked.     *
639
			*                                                            *
640
			*************************************************************/
641
			if (g_usDataType & COMPRESS)
642
			{
643
				if (GetByte(g_iMovingDataIndex++, 0))
644
				{
645
					g_usDataType |= COMPRESS_FRAME;
646
				}
647
			}
648
			break;
649
		case TDO:
650
		/*************************************************************
651
		*                                                            *
652
		* Set data type register to indicate TDO data and set TDO    *
653
		* index to the current algorithm location.                   *
654
		*                                                            *
655
		*************************************************************/
656
			g_usDataType |= TDO_DATA;
657
			g_iTDOIndex = g_iMovingAlgoIndex;
658
			g_iMovingAlgoIndex += a_uiDataSize;
659
			break;
660
		case DTDO:
661
		/*************************************************************
662
		*                                                            *
663
		* Set data type register to indicate DTDO data and check the *
664
		* next byte to make sure it's the DATA byte.  DTDO indicates *
665
		* that the data should be read from the data array, not the  *
666
		* algo array.                                                *
667
		*                                                            *
668
		*************************************************************/
669
			g_usDataType |= DTDO_DATA;
670
			if (GetByte(g_iMovingAlgoIndex++, 1) != DATA)
671
			{
672
				return ERR_ALGO_FILE_ERROR;
673
			}
674
			
675
			/*************************************************************
676
			*                                                            *
677
			* If the COMPRESS flag is set, read the next byte from the   *
678
			* data file array.  If the byte is true, then that indicates *
679
			* the frame was compressable.  Note that even though the     *
680
			* overall data file was compressed, certain frames may not   *
681
			* be compressable that is why this byte must be checked.     *
682
			*                                                            *
683
			*************************************************************/
684
			if (g_usDataType & COMPRESS)
685
			{
686
				if (GetByte(g_iMovingDataIndex++, 0))
687
				{
688
					g_usDataType |= COMPRESS_FRAME;
689
				}
690
			}
691
			break;
692
		case MASK:
693
		/*************************************************************
694
		*                                                            *
695
		* Set data type register to indicate MASK data.  Set MASK    *
696
		* location index to current algorithm array position.        *
697
		*                                                            *
698
		*************************************************************/
699
			g_usDataType |= MASK_DATA;
700
			g_iMASKIndex = g_iMovingAlgoIndex;
701
			g_iMovingAlgoIndex += a_uiDataSize;
702
			break;
703
		default:
704
		/*************************************************************
705
		*                                                            *
706
		* Unrecognized or misplaced opcode.  Return error.           *
707
		*                                                            *
708
		*************************************************************/
709
			return ERR_ALGO_FILE_ERROR;
710
		}
711
	}  
712
	
713
	/*************************************************************
714
	*                                                            *
715
	* Reached the end of the instruction.  Return passing.       *
716
	*                                                            *
717
	*************************************************************/
718
	
719
	return 0;
720
}
721
722
/*************************************************************
723
*                                                            *
724
* ISPVMSHIFT                                                 *
725
*                                                            *
726
* INPUT:                                                     *
727
*     a_cCommand: this argument specifies either the SIR or  *
728
*     SDR command.                                           *
729
*                                                            *
730
* RETURN:                                                    *
731
*     The return value indicates whether the SIR/SDR was     *
732
*     processed successfully or not.  A return value equal   *
733
*     to or greater than 0 is passing, and less than 0 is    *
734
*     failing.                                               *
735
*                                                            *
736
* DESCRIPTION:                                               *
737
*     This function is the entry point to execute an SIR or  *
738
*     SDR command to the device.                             *
739
*                                                            *
740
*************************************************************/
741
742
short int ispVMShift(char a_cCommand)
743
{
744
	short int siRetCode = 0;
745
	unsigned int uiDataSize = ispVMDataSize();
746
	
747
	/*************************************************************
748
	*                                                            *
749
	* Clear any existing SIR/SDR instructions from the data type *
750
	* register.                                                  *
751
	*                                                            *
752
	*************************************************************/
753
	
754
	g_usDataType &= ~(SIR_DATA + SDR_DATA);
755
	
756
	/*************************************************************
757
	*                                                            *
758
	* Move state machine to appropriate state depending on the   *
759
	* command.  Issue bypass if needed.                          *
760
	*                                                            *
761
	*************************************************************/
762
	
763
	switch (a_cCommand)
764
	{
765
	case SIR:
766
	/*************************************************************
767
	*                                                            *
768
	* Set the data type register to indicate that it's executing *
769
	* an SIR instruction.  Move state machine to IRPAUSE,        *
770
	* SHIFTIR.  If header instruction register exists, then      *
771
	* issue bypass.                                              *
772
	*                                                           *
773
	*************************************************************/
774
		g_usDataType |= SIR_DATA;
775
		ispVMStateMachine(IRPAUSE);
776
		ispVMStateMachine(SHIFTIR);
777
		if (g_siHeadIR > 0)
778
		{ 
779
			ispVMBypass(g_siHeadIR);
780
			sclock();
781
		}
782
		break;
783
	case SDR:
784
	/*************************************************************
785
	*                                                            *
786
	* Set the data type register to indicate that it's executing *
787
	* an SDR instruction.  Move state machine to DRPAUSE,        *
788
	* SHIFTDR.  If header data register exists, then issue       *
789
	* bypass.                                                    *
790
	*                                                            *
791
	*************************************************************/
792
		g_usDataType |= SDR_DATA;
793
		ispVMStateMachine(DRPAUSE);
794
		ispVMStateMachine(SHIFTDR);
795
		if (g_siHeadDR > 0)
796
		{
797
			ispVMBypass(g_siHeadDR);
798
			sclock();
799
		}
800
		break;
801
	}
802
	
803
	/*************************************************************
804
	*                                                            *
805
	* Set the appropriate index locations.  If error then return *
806
	* error code immediately.                                    *
807
	*                                                            *
808
	*************************************************************/
809
	
810
	siRetCode = ispVMShiftExec(uiDataSize);
811
	
812
	if (siRetCode < 0)
813
	{
814
		return siRetCode;
815
	}
816
	
817
	/*************************************************************
818
	*                                                            *
819
	* Execute the command to the device.  If TDO exists, then    *
820
	* read from the device and verify.  Else only TDI exists     *
821
	* which must send data to the device only.                   *
822
	*                                                            *
823
	*************************************************************/
824
	
825
	if ((g_usDataType & TDO_DATA) ||(g_usDataType & DTDO_DATA))
826
	{
827
		siRetCode = ispVMRead(uiDataSize);
828
		/*************************************************************
829
		*                                                            *
830
		* A frame of data has just been read and verified.  If the   *
831
		* DTDO_DATA flag is set, then check to make sure the next    *
832
		* byte in the data array, which is the last byte of the      *
833
		* frame, is the END_FRAME byte.                              *
834
		*                                                            *
835
		*************************************************************/
836
		if (g_usDataType & DTDO_DATA)
837
		{
838
			if (GetByte(g_iMovingDataIndex++, 0) != END_FRAME)
839
			{
840
				siRetCode = ERR_DATA_FILE_ERROR;
841
			}
842
		}
843
	}
844
	else 
845
	{
846
		ispVMSend(uiDataSize);
847
		/*************************************************************
848
		*                                                            *
849
		* A frame of data has just been sent.  If the DTDI_DATA flag *
850
		* is set, then check to make sure the next byte in the data  *
851
		* array, which is the last byte of the frame, is the         *
852
		* END_FRAME byte.                                            *
853
		*                                                            *
854
		*************************************************************/
855
		if (g_usDataType & DTDI_DATA)
856
		{
857
			if (GetByte(g_iMovingDataIndex++, 0) != END_FRAME)
858
			{
859
				siRetCode = ERR_DATA_FILE_ERROR;
860
			}
861
		}
862
	}
863
	
864
	/*************************************************************
865
	*                                                            *
866
	* Bypass trailer if it exists.  Move state machine to        *
867
	* ENDIR/ENDDR state.                                         *
868
	*                                                            *
869
	*************************************************************/
870
	
871
	switch (a_cCommand)
872
	{
873
	case SIR:
874
		if (g_siTailIR > 0)
875
		{
876
			sclock();
877
			ispVMBypass(g_siTailIR);
878
		}
879
		ispVMStateMachine(g_cEndIR);
880
		break;
881
    case SDR:  
882
		if (g_siTailDR > 0)
883
		{
884
			sclock();
885
			ispVMBypass(g_siTailDR);
886
		}
887
		ispVMStateMachine(g_cEndDR);
888
		break;
889
	}
890
	
891
	return siRetCode;
892
}
893
894
/*************************************************************
895
*                                                            *
896
* GETBYTE                                                    *
897
*                                                            *
898
* INPUT:                                                     *
899
*     a_iCurrentIndex: the current index to access.          *
900
*                                                            *
901
*     a_cAlgo: 1 if the return byte is to be retrieved from  *
902
*     the algorithm array, 0 if the byte is to be retrieved  *
903
*     from the data array.                                   *
904
*                                                            *
905
* RETURN:                                                    *
906
*     This function returns a byte of data from either the   *
907
*     algorithm or data array.  It returns -1 if out of      *
908
*     bounds.                                                *
909
*                                                            *
910
*************************************************************/
911
912
unsigned char GetByte(int a_iCurrentIndex, char a_cAlgo)
913
{
914
	if (a_cAlgo)
915
	{ 
916
	/*************************************************************
917
	*                                                            *
918
	* If the current index is still within range, then return    *
919
	* the next byte.  If it is out of range, then return -1.     *
920
	*                                                            *
921
	*************************************************************/
922
		if(a_iCurrentIndex >= g_ispAlgoSize)
923
			return (unsigned char)0xff;
924
		else return g_ispAlgo[a_iCurrentIndex];
925
	}
926
	else 
927
	{
928
	/*************************************************************
929
	*                                                            *
930
	* If the current index is still within range, then return    *
931
	* the next byte.  If it is out of range, then return -1.     *
932
	*                                                            *
933
	*************************************************************/
934
		if((a_iCurrentIndex & 1023) == 0)
935 6a2d2243 Harald Welte
			printf("%d bytes done (%zu%%)\n", a_iCurrentIndex, (a_iCurrentIndex * 100) / g_ispDataSize);
936 4cd82c23 Christian Daniel
		if(a_iCurrentIndex >= g_ispDataSize)
937
			return (unsigned char)0xff;
938
		else return g_ispData[a_iCurrentIndex];
939
	}
940
}
941
942
/*************************************************************
943
*                                                            *
944
* SCLOCK                                                     *
945
*                                                            *
946
* INPUT:                                                     *
947
*     None.                                                  *
948
*                                                            *
949
* RETURN:                                                    *
950
*     None.                                                  *
951
*                                                            *
952
* DESCRIPTION:                                               *
953
*     This function applies a HLL pulse to TCK.              *
954
*                                                            *
955
*************************************************************/
956
957
void sclock()
958
{
959
/*************************************************************
960
*                                                            *
961
* Set TCK to HIGH, LOW, LOW.                                 *
962
*                                                            *
963
*************************************************************/
964
	
965
	writePort(pinTCK, 0x01);
966
	writePort(pinTCK, 0x00);
967
	writePort(pinTCK, 0x00);
968
}
969
970
/*************************************************************
971
*                                                            *
972
* ISPVMREAD                                                  *
973
*                                                            *
974
* INPUT:                                                     *
975
*     a_uiDataSize: this argument is the size of the         *
976
*     command.                                               *
977
*                                                            *
978
* RETURN:                                                    *
979
*     The return value is 0 if passing, and -1 if failing.   *
980
*                                                            *
981
* DESCRIPTION:                                               *
982
*     This function reads a data stream from the device and  *
983
*     compares it to the expected TDO.                       *
984
*                                                            *
985
*************************************************************/
986
987
short int ispVMRead(unsigned int a_uiDataSize)
988
{
989
	unsigned int uiIndex = 0;
990
	unsigned short usErrorCount = 0;
991
	unsigned char ucTDIByte = 0;
992
	unsigned char ucTDOByte = 0;
993
	unsigned char ucMaskByte = 0;
994
	unsigned char ucCurBit = 0;
995
	
996
	for (uiIndex = 0;uiIndex < a_uiDataSize; uiIndex++)
997
	{ 
998
		if (uiIndex % 8 == 0)
999
		{
1000
			if ( g_usDataType & TDI_DATA ) {
1001
				/*************************************************************
1002
				*                                                            *
1003
				* If the TDI_DATA flag is set, then grab the next byte from  *
1004
				* the algo array and increment the TDI index.                *
1005
				*                                                            *
1006
				*************************************************************/
1007
				ucTDIByte = GetByte( g_iTDIIndex++, 1 );
1008
			}
1009
			else
1010
			{
1011
				ucTDIByte = 0xFF;
1012
			}
1013
			if (g_usDataType & TDO_DATA)
1014
			{
1015
			/*************************************************************
1016
			*                                                            *
1017
			* If the TDO_DATA flag is set, then grab the next byte from  *
1018
			* the algo array and increment the TDO index.                *
1019
			*                                                            *
1020
			*************************************************************/
1021
				ucTDOByte = GetByte(g_iTDOIndex++, 1);
1022
			}
1023
			else 
1024
			{
1025
			/*************************************************************
1026
			*                                                            *
1027
			* If TDO_DATA is not set, then DTDO_DATA must be set.  If    *
1028
			* the compression counter exists, then the next TDO byte     *
1029
			* must be 0xFF.  If it doesn't exist, then get next byte     *
1030
			* from data file array.                                      *
1031
			*                                                            *
1032
			*************************************************************/
1033
				if (g_ucCompressCounter)
1034
				{
1035
					g_ucCompressCounter--;
1036
					ucTDOByte =(unsigned char) 0xFF;
1037
				}
1038
				else 
1039
				{
1040
					ucTDOByte = GetByte(g_iMovingDataIndex++, 0);
1041
					
1042
					/*************************************************************
1043
					*                                                            *
1044
					* If the frame is compressed and the byte is 0xFF, then the  *
1045
					* next couple bytes must be read to determine how many       *
1046
					* repetitions of 0xFF are there.  That value will be stored  *
1047
					* in the variable g_ucCompressCounter.                       *
1048
					*                                                            *
1049
					*************************************************************/
1050
					if ((g_usDataType & COMPRESS_FRAME) &&(ucTDOByte ==(unsigned char) 0xFF))
1051
					{
1052
						g_ucCompressCounter = GetByte(g_iMovingDataIndex++, 0);
1053
						g_ucCompressCounter--;
1054
					}
1055
				}
1056
			}
1057
			
1058
			if (g_usDataType & MASK_DATA)
1059
			{
1060
				ucMaskByte = GetByte(g_iMASKIndex++, 1);
1061
			}
1062
			else 
1063
			{ 
1064
				ucMaskByte =(unsigned char) 0xFF;
1065
			}
1066
		}
1067
		
1068
		ucCurBit = readPort();
1069
		
1070
		if ((((ucMaskByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
1071
		{	
1072
			if (ucCurBit !=(unsigned char)(((ucTDOByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00))
1073
			{
1074
				usErrorCount++;  
1075
			}
1076
		}
1077
		
1078
		/*************************************************************
1079
		*                                                            *
1080
		* Always shift 0x01 into TDI pin when reading.               *
1081
		*                                                            *
1082
		*************************************************************/
1083
		
1084
		writePort(pinTDI, (unsigned char) (((ucTDIByte << uiIndex % 8) & 0x80) ? 0x01 : 0x00));
1085
		
1086
		if (uiIndex < a_uiDataSize - 1)
1087
		{
1088
			sclock();
1089
		}
1090
	}
1091
	
1092
	if (usErrorCount > 0)
1093
	{
1094
		return -1;
1095
	}
1096
	
1097
	return 0;
1098
}
1099
1100
/*************************************************************
1101
*                                                            *
1102
* ISPVMSEND                                                  *
1103
*                                                            *
1104
* INPUT:                                                     *
1105
*     a_uiDataSize: this argument is the size of the         *
1106
*     command.                                               *
1107
*                                                            *
1108
* RETURN:                                                    *
1109
*     None.                                                  *
1110
*                                                            *
1111
* DESCRIPTION:                                               *
1112
*     This function sends a data stream to the device.       *
1113
*                                                            *
1114
*************************************************************/
1115
1116
void ispVMSend(unsigned int a_uiDataSize)
1117
{
1118
	unsigned int iIndex;
1119
	unsigned char ucCurByte = 0;
1120
	unsigned char ucBitState = 0;
1121
	
1122
	/*************************************************************
1123
	*                                                            *
1124
	* Begin processing the data to the device.                   *
1125
	*                                                            *
1126
	*************************************************************/
1127
	
1128
	for (iIndex = 0;iIndex < a_uiDataSize; iIndex++)
1129
	{ 
1130
		if (iIndex % 8 == 0)
1131
		{ 
1132
			if (g_usDataType & TDI_DATA)
1133
			{
1134
			/*************************************************************
1135
			*                                                            *
1136
			* If the TDI_DATA flag is set, then grab the next byte from  *
1137
			* the algo array and increment the TDI index.                *
1138
			*                                                            *
1139
			*************************************************************/
1140
				ucCurByte = GetByte(g_iTDIIndex++, 1);
1141
			}
1142
			else 
1143
			{
1144
			/*************************************************************
1145
			*                                                            *
1146
			* If TDI_DATA flag is not set, then DTDI_DATA flag must have *
1147
			* already been set.  If the compression counter exists, then *
1148
			* the next TDI byte must be 0xFF.  If it doesn't exist, then *
1149
			* get next byte from data file array.                        *
1150
			*                                                            *
1151
			*************************************************************/
1152
				if (g_ucCompressCounter)
1153
				{
1154
					g_ucCompressCounter--;
1155
					ucCurByte =(unsigned char) 0xFF;
1156
				}
1157
				else 
1158
				{
1159
					ucCurByte = GetByte(g_iMovingDataIndex++, 0);
1160
					
1161
					/*************************************************************
1162
					*                                                            *
1163
					* If the frame is compressed and the byte is 0xFF, then the  *
1164
					* next couple bytes must be read to determine how many       *
1165
					* repetitions of 0xFF are there.  That value will be stored  *
1166
					* in the variable g_ucCompressCounter.                       *
1167
					*                                                            *
1168
					*************************************************************/
1169
					
1170
					if ((g_usDataType & COMPRESS_FRAME) &&(ucCurByte ==(unsigned char) 0xFF))
1171
					{
1172
						g_ucCompressCounter = GetByte(g_iMovingDataIndex++, 0);
1173
						g_ucCompressCounter--;
1174
					}
1175
				}
1176
			}
1177
		}
1178
		
1179
		ucBitState =(unsigned char)(((ucCurByte << iIndex % 8) & 0x80) ? 0x01 : 0x00);
1180
		writePort(pinTDI, ucBitState);
1181
		
1182
		if (iIndex < a_uiDataSize - 1)
1183
		{
1184
			sclock();
1185
		}
1186
	}
1187
}
1188
1189
/*************************************************************
1190
*                                                            *
1191
* ISPVMSTATEMACHINE                                          *
1192
*                                                            *
1193
* INPUT:                                                     *
1194
*     a_cNextState: this is the opcode of the next JTAG      *
1195
*     state.                                                 *
1196
*                                                            *
1197
* RETURN:                                                    *
1198
*     This functions returns 0 when passing, and -1 when     *
1199
*     failure occurs.                                        *
1200
*                                                            *
1201
* DESCRIPTION:                                               *
1202
*     This function is called to move the device into        *
1203
*     different JTAG states.                                 *
1204
*                                                            *
1205
*************************************************************/
1206
1207
void ispVMStateMachine(char a_cNextState)
1208
{
1209
	int cPathIndex, cStateIndex;
1210
	if ((g_cCurrentJTAGState == DRPAUSE) &&(a_cNextState== DRPAUSE) && m_loopState)
1211
	{
1212
	} 
1213
	else if ((g_cCurrentJTAGState == a_cNextState) &&(g_cCurrentJTAGState != RESET))
1214
	{
1215
		return;
1216
	}
1217
	
1218
	for (cStateIndex = 0;cStateIndex < 25; cStateIndex++)
1219
	{
1220
		if ((g_cCurrentJTAGState == iStates[cStateIndex].CurState) &&(a_cNextState == iStates[cStateIndex].NextState))
1221
		{
1222
			break;
1223
		}
1224
	}	
1225
	g_cCurrentJTAGState = a_cNextState;
1226
	for (cPathIndex = 0;cPathIndex < iStates[cStateIndex].Pulses; cPathIndex++)
1227
	{
1228
		if ((iStates[cStateIndex].Pattern << cPathIndex) & 0x80)
1229
		{
1230
			writePort(pinTMS, (unsigned char) 0x01);
1231
		}
1232
		else 
1233
		{
1234
			writePort(pinTMS, (unsigned char) 0x00);
1235
		}
1236
		sclock();
1237
	}
1238
	
1239
	writePort(pinTDI, 0x00);
1240
	writePort(pinTMS, 0x00);
1241
}
1242
1243
/*************************************************************
1244
*                                                            *
1245
* ISPVMCLOCKS                                                *
1246
*                                                            *
1247
* INPUT:                                                     *
1248
*     a_usClocks: number of clocks to apply.                 *
1249
*                                                            *
1250
* RETURN:                                                    *
1251
*     None.                                                  *
1252
*                                                            *
1253
* DESCRIPTION:                                               *
1254
*    This procedure applies the specified number of pulses   *
1255
*    to TCK.                                                 *
1256
*                                                            *
1257
*************************************************************/
1258
1259
void ispVMClocks(unsigned int a_uiClocks)
1260
{	
1261
	for (; a_uiClocks > 0; a_uiClocks--)
1262
	{
1263
		sclock();
1264
	}
1265
}
1266
1267
/*************************************************************
1268
*                                                            *
1269
* ISPVMBYPASS                                                *
1270
*                                                            *
1271
* INPUT:                                                     *
1272
*     a_siLength: this argument is the length of the         *
1273
*     command.                                               *
1274
*                                                            *
1275
* RETURN:                                                    *
1276
*     None.                                                  *
1277
*                                                            *
1278
* DESCRIPTION:                                               *
1279
*     This function takes care of the HIR, HDR, TIR, and TDR *
1280
*     for the purpose of putting the other devices into      *
1281
*     bypass mode.                                           *
1282
*                                                            *
1283
*************************************************************/
1284
1285
void ispVMBypass(unsigned int a_uiLength)
1286
{
1287
/*************************************************************
1288
*                                                            *
1289
* Issue a_siLength number of 0x01 to the TDI pin to bypass.  *
1290
*                                                            *
1291
*************************************************************/
1292
	
1293
	for (; a_uiLength > 1; a_uiLength--)
1294
	{
1295
		writePort(pinTDI, (char) 0x01);
1296
		sclock();
1297
	}
1298
	
1299
	writePort(pinTDI, (char) 0x01);
1300
}
1301
/*************************************************************
1302
*                                                            *
1303
* ispVMLCOUNT                                                *
1304
*                                                            *
1305
* INPUT:                                                     *
1306
*     a_usCountSize: The maximum number of loop required to  *
1307
*     poling the status                                      *
1308
*                                                            *
1309
*                                                            *
1310
* DESCRIPTION:                                               *
1311
*     This function is set the maximum loop count            *
1312
*                                                            *
1313
*************************************************************/
1314
1315
void ispVMLCOUNT(unsigned short a_usCountSize)
1316
{
1317
	g_usLCOUNTSize = a_usCountSize;
1318
}
1319
/*************************************************************
1320
*                                                            *
1321
* ispVMLDELAY                                                *
1322
*                                                            *
1323
*                                                            *
1324
* DESCRIPTION:                                               *
1325
*     This function is set the delay state, number of TCK and* 
1326
*  the delay time for poling the status                      *
1327
*                                                            *
1328
*************************************************************/
1329
void ispVMLDELAY()
1330
{
1331
	g_ucLDELAYState = IDLE;
1332
	g_ucLDELAYDelay = 0;
1333
	g_ucLDELAYTCK   = 0;
1334
	while (1)
1335
	{
1336
		unsigned char bytedata = GetByte(g_iMovingAlgoIndex++, 1);
1337
		switch (bytedata)
1338
		{
1339
		case STATE: /*step BSCAN state machine to specified state*/
1340
			g_ucLDELAYState = GetByte(g_iMovingAlgoIndex++, 1);
1341
			break;
1342
		case WAIT:  /*opcode to wait for specified time in us or ms*/ 
1343
			g_ucLDELAYDelay = (short int) ispVMDataSize();
1344
			break;
1345
		case TCK:   /*pulse TCK signal the specified time*/
1346
			g_ucLDELAYTCK = (short int) ispVMDataSize();
1347
			break;
1348
		case ENDSTATE:
1349
			return;
1350
			break;
1351
		}
1352
	}
1353
}
Add picture from clipboard (Maximum size: 48.8 MB)