vmod/vmodttl: fixed bug related to luns not ordered and/or not starting from zero.
[ht-drivers.git] / jtag / micro.c
blob8f6190ae40e8584d6800863d72ce8e8243d49ab7
1 /*****************************************************************************
2 * file: micro.c
3 * abstract: This file contains the function, xsvfExecute(),
4 * call for interpreting the XSVF commands.
5 * Usage: Call xsvfExecute() to process XSVF data.
6 * The XSVF data is retrieved by readByte() in ports.c
7 * Remove the main function if you already have one.
8 * Options: XSVF_SUPPORT_COMPRESSION
9 * This define supports the XC9500/XL compression scheme.
10 * This define adds support for XSDRINC and XSETSDRMASKS.
11 * XSVF_SUPPORT_ERRORCODES
12 * This define causes the xsvfExecute function to return
13 * an error code for specific errors. See error codes below.
14 * If this is not defined, the return value defaults to the
15 * legacy values for backward compatibility:
16 * 1 = success; 0 = failure.
17 * Debugging: DEBUG_MODE (Legacy name)
18 * Define DEBUG_MODE to compile with debugging features.
19 * Both micro.c and ports.c must be compiled with the DEBUG_MODE
20 * defined to enable the standalone main implementation in
21 * micro.c that reads XSVF from a file.
22 * History: v2.00 - Original XSVF implementation.
23 * v4.04 - Added delay at end of XSIR for XC18v00 support.
24 * Added new commands for CoolRunner support:
25 * XSTATE, XENDIR, XENDDR
26 * v4.05 - Cleanup micro.c but leave ports.c intact.
27 * v4.06 - Fix xsvfGotoTapState for retry transition.
28 * v4.07 - Update example waitTime implementations for
29 * compatibility with Virtex-II.
30 * v4.10 - Add new XSIR2 command that supports a 2-byte
31 * IR-length parameter for IR shifts > 255 bits.
32 * v4.11 - No change. Update version to match SVF2XSVF xlator.
33 * v4.14 - Added XCOMMENT.
34 * v5.00 - Improve XSTATE support.
35 * Added XWAIT.
36 *****************************************************************************/
38 /*============================================================================
39 * #pragmas
40 ============================================================================*/
41 #ifdef _MSC_VER
42 #pragma warning( disable : 4100 )
43 #endif /* _MSC_VER */
45 /*============================================================================
46 * #include files
47 ============================================================================*/
48 #ifdef DEBUG_MODE
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <time.h>
53 #endif /* DEBUG_MODE */
55 #include <micro.h>
56 #include <lenval.h>
57 #include <ports.h>
59 /*============================================================================
60 * XSVF #define
61 ============================================================================*/
63 #define XSVF_VERSION "5.00"
65 /*****************************************************************************
66 * Define: XSVF_SUPPORT_COMPRESSION
67 * Description: Define this to support the XC9500/XL XSVF data compression
68 * scheme.
69 * Code size can be reduced by NOT supporting this feature.
70 * However, you must use the -nc (no compress) option when
71 * translating SVF to XSVF using the SVF2XSVF translator.
72 * Corresponding, uncompressed XSVF may be larger.
73 *****************************************************************************/
74 #ifndef XSVF_SUPPORT_COMPRESSION
75 #define XSVF_SUPPORT_COMPRESSION 1
76 #endif
78 /*****************************************************************************
79 * Define: XSVF_SUPPORT_ERRORCODES
80 * Description: Define this to support the new XSVF error codes.
81 * (The original XSVF player just returned 1 for success and
82 * 0 for an unspecified failure.)
83 *****************************************************************************/
84 #ifndef XSVF_SUPPORT_ERRORCODES
85 #define XSVF_SUPPORT_ERRORCODES 1
86 #endif
88 #ifdef XSVF_SUPPORT_ERRORCODES
89 #define XSVF_ERRORCODE(errorCode) errorCode
90 #else /* Use legacy error code */
91 #define XSVF_ERRORCODE(errorCode) ((errorCode==XSVF_ERROR_NONE)?1:0)
92 #endif /* XSVF_SUPPORT_ERRORCODES */
95 /*****************************************************************************
96 * Define: XSVF_MAIN
97 * Description: Define this to compile with a main function for standalone
98 * debugging.
99 *****************************************************************************/
100 #if 0
101 #ifndef XSVF_MAIN
102 #ifdef DEBUG_MODE
103 #define XSVF_MAIN 1
104 #endif /* DEBUG_MODE */
105 #endif /* XSVF_MAIN */
106 #endif
108 /*============================================================================
109 * DEBUG_MODE #define
110 ============================================================================*/
112 #ifdef DEBUG_MODE
113 #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \
114 { if ( xsvf_iDebugLevel >= iDebugLevel ) \
115 printf( pzFormat ); }
116 #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \
117 { if ( xsvf_iDebugLevel >= iDebugLevel ) \
118 printf( pzFormat, arg1 ); }
119 #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \
120 { if ( xsvf_iDebugLevel >= iDebugLevel ) \
121 printf( pzFormat, arg1, arg2 ); }
122 #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \
123 { if ( xsvf_iDebugLevel >= iDebugLevel ) \
124 printf( pzFormat, arg1, arg2, arg3 ); }
125 #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \
126 { if ( xsvf_iDebugLevel >= iDebugLevel ) \
127 xsvfPrintLenVal(plenVal); }
128 #else /* !DEBUG_MODE */
129 #define XSVFDBG_PRINTF(iDebugLevel,pzFormat)
130 #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1)
131 #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2)
132 #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3)
133 #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal)
134 #endif /* DEBUG_MODE */
137 /*============================================================================
138 * XSVF Type Declarations
139 ============================================================================*/
141 /*****************************************************************************
142 * Struct: SXsvfInfo
143 * Description: This structure contains all of the data used during the
144 * execution of the XSVF. Some data is persistent, predefined
145 * information (e.g. lRunTestTime). The bulk of this struct's
146 * size is due to the lenVal structs (defined in lenval.h)
147 * which contain buffers for the active shift data. The MAX_LEN
148 * #define in lenval.h defines the size of these buffers.
149 * These buffers must be large enough to store the longest
150 * shift data in your XSVF file. For example:
151 * MAX_LEN >= ( longest_shift_data_in_bits / 8 )
152 * Because the lenVal struct dominates the space usage of this
153 * struct, the rough size of this struct is:
154 * sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals)
155 * xsvfInitialize() contains initialization code for the data
156 * in this struct.
157 * xsvfCleanup() contains cleanup code for the data in this
158 * struct.
159 *****************************************************************************/
160 typedef struct tagSXsvfInfo
162 /* XSVF status information */
163 unsigned char ucComplete; /* 0 = running; 1 = complete */
164 unsigned char ucCommand; /* Current XSVF command byte */
165 long lCommandCount; /* Number of commands processed */
166 int iErrorCode; /* An error code. 0 = no error. */
168 /* TAP state/sequencing information */
169 unsigned char ucTapState; /* Current TAP state */
170 unsigned char ucEndIR; /* ENDIR TAP state (See SVF) */
171 unsigned char ucEndDR; /* ENDDR TAP state (See SVF) */
173 /* RUNTEST information */
174 unsigned char ucMaxRepeat; /* Max repeat loops (for xc9500/xl) */
175 long lRunTestTime; /* Pre-specified RUNTEST time (usec) */
177 /* Shift Data Info and Buffers */
178 long lShiftLengthBits; /* Len. current shift data in bits */
179 short sShiftLengthBytes; /* Len. current shift data in bytes */
181 lenVal lvTdi; /* Current TDI shift data */
182 lenVal lvTdoExpected; /* Expected TDO shift data */
183 lenVal lvTdoCaptured; /* Captured TDO shift data */
184 lenVal lvTdoMask; /* TDO mask: 0=dontcare; 1=compare */
186 #ifdef XSVF_SUPPORT_COMPRESSION
187 /* XSDRINC Data Buffers */
188 lenVal lvAddressMask; /* Address mask for XSDRINC */
189 lenVal lvDataMask; /* Data mask for XSDRINC */
190 lenVal lvNextData; /* Next data for XSDRINC */
191 #endif /* XSVF_SUPPORT_COMPRESSION */
192 } SXsvfInfo;
194 /* Declare pointer to functions that perform XSVF commands */
195 typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
198 /*============================================================================
199 * XSVF Command Bytes
200 ============================================================================*/
202 /* encodings of xsvf instructions */
203 #define XCOMPLETE 0
204 #define XTDOMASK 1
205 #define XSIR 2
206 #define XSDR 3
207 #define XRUNTEST 4
208 /* Reserved 5 */
209 /* Reserved 6 */
210 #define XREPEAT 7
211 #define XSDRSIZE 8
212 #define XSDRTDO 9
213 #define XSETSDRMASKS 10
214 #define XSDRINC 11
215 #define XSDRB 12
216 #define XSDRC 13
217 #define XSDRE 14
218 #define XSDRTDOB 15
219 #define XSDRTDOC 16
220 #define XSDRTDOE 17
221 #define XSTATE 18 /* 4.00 */
222 #define XENDIR 19 /* 4.04 */
223 #define XENDDR 20 /* 4.04 */
224 #define XSIR2 21 /* 4.10 */
225 #define XCOMMENT 22 /* 4.14 */
226 #define XWAIT 23 /* 5.00 */
227 /* Insert new commands here */
228 /* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */
229 #define XLASTCMD 24 /* Last command marker */
232 /*============================================================================
233 * XSVF Command Parameter Values
234 ============================================================================*/
236 #define XSTATE_RESET 0 /* 4.00 parameter for XSTATE */
237 #define XSTATE_RUNTEST 1 /* 4.00 parameter for XSTATE */
239 #define XENDXR_RUNTEST 0 /* 4.04 parameter for XENDIR/DR */
240 #define XENDXR_PAUSE 1 /* 4.04 parameter for XENDIR/DR */
242 /* TAP states */
243 #define XTAPSTATE_RESET 0x00
244 #define XTAPSTATE_RUNTEST 0x01 /* a.k.a. IDLE */
245 #define XTAPSTATE_SELECTDR 0x02
246 #define XTAPSTATE_CAPTUREDR 0x03
247 #define XTAPSTATE_SHIFTDR 0x04
248 #define XTAPSTATE_EXIT1DR 0x05
249 #define XTAPSTATE_PAUSEDR 0x06
250 #define XTAPSTATE_EXIT2DR 0x07
251 #define XTAPSTATE_UPDATEDR 0x08
252 #define XTAPSTATE_IRSTATES 0x09 /* All IR states begin here */
253 #define XTAPSTATE_SELECTIR 0x09
254 #define XTAPSTATE_CAPTUREIR 0x0A
255 #define XTAPSTATE_SHIFTIR 0x0B
256 #define XTAPSTATE_EXIT1IR 0x0C
257 #define XTAPSTATE_PAUSEIR 0x0D
258 #define XTAPSTATE_EXIT2IR 0x0E
259 #define XTAPSTATE_UPDATEIR 0x0F
261 /*============================================================================
262 * XSVF Function Prototypes
263 ============================================================================*/
265 int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ); /* Illegal command function */
266 int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo );
267 int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo );
268 int xsvfDoXSIR( SXsvfInfo* pXsvfInfo );
269 int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo );
270 int xsvfDoXSDR( SXsvfInfo* pXsvfInfo );
271 int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo );
272 int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo );
273 int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo );
274 int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo );
275 int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo );
276 int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo );
277 int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo );
278 int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo );
279 int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo );
280 int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo );
281 int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo );
282 int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo );
283 /* Insert new command functions here */
285 /*============================================================================
286 * XSVF Global Variables
287 ============================================================================*/
289 /* Array of XSVF command functions. Must follow command byte value order! */
290 /* If your compiler cannot take this form, then convert to a switch statement*/
291 TXsvfDoCmdFuncPtr xsvf_pfDoCmd[] =
293 xsvfDoXCOMPLETE, /* 0 */
294 xsvfDoXTDOMASK, /* 1 */
295 xsvfDoXSIR, /* 2 */
296 xsvfDoXSDR, /* 3 */
297 xsvfDoXRUNTEST, /* 4 */
298 xsvfDoIllegalCmd, /* 5 */
299 xsvfDoIllegalCmd, /* 6 */
300 xsvfDoXREPEAT, /* 7 */
301 xsvfDoXSDRSIZE, /* 8 */
302 xsvfDoXSDRTDO, /* 9 */
303 #ifdef XSVF_SUPPORT_COMPRESSION
304 xsvfDoXSETSDRMASKS, /* 10 */
305 xsvfDoXSDRINC, /* 11 */
306 #else
307 xsvfDoIllegalCmd, /* 10 */
308 xsvfDoIllegalCmd, /* 11 */
309 #endif /* XSVF_SUPPORT_COMPRESSION */
310 xsvfDoXSDRBCE, /* 12 */
311 xsvfDoXSDRBCE, /* 13 */
312 xsvfDoXSDRBCE, /* 14 */
313 xsvfDoXSDRTDOBCE, /* 15 */
314 xsvfDoXSDRTDOBCE, /* 16 */
315 xsvfDoXSDRTDOBCE, /* 17 */
316 xsvfDoXSTATE, /* 18 */
317 xsvfDoXENDXR, /* 19 */
318 xsvfDoXENDXR, /* 20 */
319 xsvfDoXSIR2, /* 21 */
320 xsvfDoXCOMMENT, /* 22 */
321 xsvfDoXWAIT /* 23 */
322 /* Insert new command functions here */
325 #ifdef DEBUG_MODE
326 char* xsvf_pzCommandName[] =
328 "XCOMPLETE",
329 "XTDOMASK",
330 "XSIR",
331 "XSDR",
332 "XRUNTEST",
333 "Reserved5",
334 "Reserved6",
335 "XREPEAT",
336 "XSDRSIZE",
337 "XSDRTDO",
338 "XSETSDRMASKS",
339 "XSDRINC",
340 "XSDRB",
341 "XSDRC",
342 "XSDRE",
343 "XSDRTDOB",
344 "XSDRTDOC",
345 "XSDRTDOE",
346 "XSTATE",
347 "XENDIR",
348 "XENDDR",
349 "XSIR2",
350 "XCOMMENT",
351 "XWAIT"
354 char* xsvf_pzErrorName[] =
356 "No error",
357 "ERROR: Unknown",
358 "ERROR: TDO mismatch",
359 "ERROR: TDO mismatch and exceeded max retries",
360 "ERROR: Unsupported XSVF command",
361 "ERROR: Illegal state specification",
362 "ERROR: Data overflows allocated MAX_LEN buffer size"
365 char* xsvf_pzTapState[] =
367 "RESET", /* 0x00 */
368 "RUNTEST/IDLE", /* 0x01 */
369 "DRSELECT", /* 0x02 */
370 "DRCAPTURE", /* 0x03 */
371 "DRSHIFT", /* 0x04 */
372 "DREXIT1", /* 0x05 */
373 "DRPAUSE", /* 0x06 */
374 "DREXIT2", /* 0x07 */
375 "DRUPDATE", /* 0x08 */
376 "IRSELECT", /* 0x09 */
377 "IRCAPTURE", /* 0x0A */
378 "IRSHIFT", /* 0x0B */
379 "IREXIT1", /* 0x0C */
380 "IRPAUSE", /* 0x0D */
381 "IREXIT2", /* 0x0E */
382 "IRUPDATE" /* 0x0F */
384 #endif /* DEBUG_MODE */
386 #ifdef DEBUG_MODE
387 FILE* in; /* Legacy DEBUG_MODE file pointer */
388 #endif /* DEBUG_MODE */
390 /*============================================================================
391 * Utility Functions
392 ============================================================================*/
394 /*****************************************************************************
395 * Function: xsvfPrintLenVal
396 * Description: Print the lenval value in hex.
397 * Parameters: plv - ptr to lenval.
398 * Returns: void.
399 *****************************************************************************/
400 #ifdef DEBUG_MODE
401 void xsvfPrintLenVal( lenVal *plv )
403 int i;
405 if ( plv )
407 printf( "0x" );
408 for ( i = 0; i < plv->len; ++i )
410 printf( "%02x", ((unsigned int)(plv->val[ i ])) );
414 #endif /* DEBUG_MODE */
417 /*****************************************************************************
418 * Function: xsvfInfoInit
419 * Description: Initialize the xsvfInfo data.
420 * Parameters: pXsvfInfo - ptr to the XSVF info structure.
421 * Returns: int - 0 = success; otherwise error.
422 *****************************************************************************/
423 int xsvfInfoInit( SXsvfInfo* pXsvfInfo )
425 XSVFDBG_PRINTF1( 4, " sizeof( SXsvfInfo ) = %d bytes\n",
426 sizeof( SXsvfInfo ) );
428 pXsvfInfo->ucComplete = 0;
429 pXsvfInfo->ucCommand = XCOMPLETE;
430 pXsvfInfo->lCommandCount = 0;
431 pXsvfInfo->iErrorCode = XSVF_ERROR_NONE;
432 pXsvfInfo->ucMaxRepeat = 0;
433 pXsvfInfo->ucTapState = XTAPSTATE_RESET;
434 pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST;
435 pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST;
436 pXsvfInfo->lShiftLengthBits = 0L;
437 pXsvfInfo->sShiftLengthBytes= 0;
438 pXsvfInfo->lRunTestTime = 0L;
440 return( 0 );
443 /*****************************************************************************
444 * Function: xsvfInfoCleanup
445 * Description: Cleanup the xsvfInfo data.
446 * Parameters: pXsvfInfo - ptr to the XSVF info structure.
447 * Returns: void.
448 *****************************************************************************/
449 void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo )
453 /*****************************************************************************
454 * Function: xsvfGetAsNumBytes
455 * Description: Calculate the number of bytes the given number of bits
456 * consumes.
457 * Parameters: lNumBits - the number of bits.
458 * Returns: short - the number of bytes to store the number of bits.
459 *****************************************************************************/
460 short xsvfGetAsNumBytes( long lNumBits )
462 return( (short)( ( lNumBits + 7L ) / 8L ) );
465 /*****************************************************************************
466 * Function: xsvfTmsTransition
467 * Description: Apply TMS and transition TAP controller by applying one TCK
468 * cycle.
469 * Parameters: sTms - new TMS value.
470 * Returns: void.
471 *****************************************************************************/
472 void xsvfTmsTransition( short sTms )
474 setPort( TMS, sTms );
475 setPort( TCK, 0 );
476 setPort( TCK, 1 );
479 /*****************************************************************************
480 * Function: xsvfGotoTapState
481 * Description: From the current TAP state, go to the named TAP state.
482 * A target state of RESET ALWAYS causes TMS reset sequence.
483 * All SVF standard stable state paths are supported.
484 * All state transitions are supported except for the following
485 * which cause an XSVF_ERROR_ILLEGALSTATE:
486 * - Target==DREXIT2; Start!=DRPAUSE
487 * - Target==IREXIT2; Start!=IRPAUSE
488 * Parameters: pucTapState - Current TAP state; returns final TAP state.
489 * ucTargetState - New target TAP state.
490 * Returns: int - 0 = success; otherwise error.
491 *****************************************************************************/
492 int xsvfGotoTapState( unsigned char* pucTapState,
493 unsigned char ucTargetState )
495 int i;
496 int iErrorCode;
498 iErrorCode = XSVF_ERROR_NONE;
499 if ( ucTargetState == XTAPSTATE_RESET )
501 /* If RESET, always perform TMS reset sequence to reset/sync TAPs */
502 xsvfTmsTransition( 1 );
503 for ( i = 0; i < 5; ++i )
505 setPort( TCK, 0 );
506 setPort( TCK, 1 );
508 *pucTapState = XTAPSTATE_RESET;
509 XSVFDBG_PRINTF( 3, " TMS Reset Sequence -> Test-Logic-Reset\n" );
510 XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
511 xsvf_pzTapState[ *pucTapState ] );
513 else if ( ( ucTargetState != *pucTapState ) &&
514 ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) ||
515 ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) )
517 /* Trap illegal TAP state path specification */
518 iErrorCode = XSVF_ERROR_ILLEGALSTATE;
520 else
522 if ( ucTargetState == *pucTapState )
524 /* Already in target state. Do nothing except when in DRPAUSE
525 or in IRPAUSE to comply with SVF standard */
526 if ( ucTargetState == XTAPSTATE_PAUSEDR )
528 xsvfTmsTransition( 1 );
529 *pucTapState = XTAPSTATE_EXIT2DR;
530 XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
531 xsvf_pzTapState[ *pucTapState ] );
533 else if ( ucTargetState == XTAPSTATE_PAUSEIR )
535 xsvfTmsTransition( 1 );
536 *pucTapState = XTAPSTATE_EXIT2IR;
537 XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
538 xsvf_pzTapState[ *pucTapState ] );
542 /* Perform TAP state transitions to get to the target state */
543 while ( ucTargetState != *pucTapState )
545 switch ( *pucTapState )
547 case XTAPSTATE_RESET:
548 xsvfTmsTransition( 0 );
549 *pucTapState = XTAPSTATE_RUNTEST;
550 break;
551 case XTAPSTATE_RUNTEST:
552 xsvfTmsTransition( 1 );
553 *pucTapState = XTAPSTATE_SELECTDR;
554 break;
555 case XTAPSTATE_SELECTDR:
556 if ( ucTargetState >= XTAPSTATE_IRSTATES )
558 xsvfTmsTransition( 1 );
559 *pucTapState = XTAPSTATE_SELECTIR;
561 else
563 xsvfTmsTransition( 0 );
564 *pucTapState = XTAPSTATE_CAPTUREDR;
566 break;
567 case XTAPSTATE_CAPTUREDR:
568 if ( ucTargetState == XTAPSTATE_SHIFTDR )
570 xsvfTmsTransition( 0 );
571 *pucTapState = XTAPSTATE_SHIFTDR;
573 else
575 xsvfTmsTransition( 1 );
576 *pucTapState = XTAPSTATE_EXIT1DR;
578 break;
579 case XTAPSTATE_SHIFTDR:
580 xsvfTmsTransition( 1 );
581 *pucTapState = XTAPSTATE_EXIT1DR;
582 break;
583 case XTAPSTATE_EXIT1DR:
584 if ( ucTargetState == XTAPSTATE_PAUSEDR )
586 xsvfTmsTransition( 0 );
587 *pucTapState = XTAPSTATE_PAUSEDR;
589 else
591 xsvfTmsTransition( 1 );
592 *pucTapState = XTAPSTATE_UPDATEDR;
594 break;
595 case XTAPSTATE_PAUSEDR:
596 xsvfTmsTransition( 1 );
597 *pucTapState = XTAPSTATE_EXIT2DR;
598 break;
599 case XTAPSTATE_EXIT2DR:
600 if ( ucTargetState == XTAPSTATE_SHIFTDR )
602 xsvfTmsTransition( 0 );
603 *pucTapState = XTAPSTATE_SHIFTDR;
605 else
607 xsvfTmsTransition( 1 );
608 *pucTapState = XTAPSTATE_UPDATEDR;
610 break;
611 case XTAPSTATE_UPDATEDR:
612 if ( ucTargetState == XTAPSTATE_RUNTEST )
614 xsvfTmsTransition( 0 );
615 *pucTapState = XTAPSTATE_RUNTEST;
617 else
619 xsvfTmsTransition( 1 );
620 *pucTapState = XTAPSTATE_SELECTDR;
622 break;
623 case XTAPSTATE_SELECTIR:
624 xsvfTmsTransition( 0 );
625 *pucTapState = XTAPSTATE_CAPTUREIR;
626 break;
627 case XTAPSTATE_CAPTUREIR:
628 if ( ucTargetState == XTAPSTATE_SHIFTIR )
630 xsvfTmsTransition( 0 );
631 *pucTapState = XTAPSTATE_SHIFTIR;
633 else
635 xsvfTmsTransition( 1 );
636 *pucTapState = XTAPSTATE_EXIT1IR;
638 break;
639 case XTAPSTATE_SHIFTIR:
640 xsvfTmsTransition( 1 );
641 *pucTapState = XTAPSTATE_EXIT1IR;
642 break;
643 case XTAPSTATE_EXIT1IR:
644 if ( ucTargetState == XTAPSTATE_PAUSEIR )
646 xsvfTmsTransition( 0 );
647 *pucTapState = XTAPSTATE_PAUSEIR;
649 else
651 xsvfTmsTransition( 1 );
652 *pucTapState = XTAPSTATE_UPDATEIR;
654 break;
655 case XTAPSTATE_PAUSEIR:
656 xsvfTmsTransition( 1 );
657 *pucTapState = XTAPSTATE_EXIT2IR;
658 break;
659 case XTAPSTATE_EXIT2IR:
660 if ( ucTargetState == XTAPSTATE_SHIFTIR )
662 xsvfTmsTransition( 0 );
663 *pucTapState = XTAPSTATE_SHIFTIR;
665 else
667 xsvfTmsTransition( 1 );
668 *pucTapState = XTAPSTATE_UPDATEIR;
670 break;
671 case XTAPSTATE_UPDATEIR:
672 if ( ucTargetState == XTAPSTATE_RUNTEST )
674 xsvfTmsTransition( 0 );
675 *pucTapState = XTAPSTATE_RUNTEST;
677 else
679 xsvfTmsTransition( 1 );
680 *pucTapState = XTAPSTATE_SELECTDR;
682 break;
683 default:
684 iErrorCode = XSVF_ERROR_ILLEGALSTATE;
685 *pucTapState = ucTargetState; /* Exit while loop */
686 break;
688 XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
689 xsvf_pzTapState[ *pucTapState ] );
693 return( iErrorCode );
696 /*****************************************************************************
697 * Function: xsvfShiftOnly
698 * Description: Assumes that starting TAP state is SHIFT-DR or SHIFT-IR.
699 * Shift the given TDI data into the JTAG scan chain.
700 * Optionally, save the TDO data shifted out of the scan chain.
701 * Last shift cycle is special: capture last TDO, set last TDI,
702 * but does not pulse TCK. Caller must pulse TCK and optionally
703 * set TMS=1 to exit shift state.
704 * Parameters: lNumBits - number of bits to shift.
705 * plvTdi - ptr to lenval for TDI data.
706 * plvTdoCaptured - ptr to lenval for storing captured TDO data.
707 * iExitShift - 1=exit at end of shift; 0=stay in Shift-DR.
708 * Returns: void.
709 *****************************************************************************/
710 void xsvfShiftOnly( long lNumBits,
711 lenVal* plvTdi,
712 lenVal* plvTdoCaptured,
713 int iExitShift )
715 unsigned char* pucTdi;
716 unsigned char* pucTdo;
717 unsigned char ucTdiByte;
718 unsigned char ucTdoByte;
719 unsigned char ucTdoBit;
720 int i;
722 /* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */
724 /* Initialize TDO storage len == TDI len */
725 pucTdo = 0;
726 if ( plvTdoCaptured )
728 plvTdoCaptured->len = plvTdi->len;
729 pucTdo = plvTdoCaptured->val + plvTdi->len;
732 /* Shift LSB first. val[N-1] == LSB. val[0] == MSB. */
733 pucTdi = plvTdi->val + plvTdi->len;
734 while ( lNumBits )
736 /* Process on a byte-basis */
737 ucTdiByte = (*(--pucTdi));
738 ucTdoByte = 0;
739 for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i )
741 --lNumBits;
742 if ( iExitShift && !lNumBits )
744 /* Exit Shift-DR state */
745 setPort( TMS, 1 );
748 /* Set the new TDI value */
749 setPort( TDI, (short)(ucTdiByte & 1) );
750 ucTdiByte >>= 1;
752 /* Set TCK low */
753 setPort( TCK, 0 );
755 if ( pucTdo )
757 /* Save the TDO value */
758 ucTdoBit = readTDOBit();
759 ucTdoByte |= ( ucTdoBit << i );
762 /* Set TCK high */
763 setPort( TCK, 1 );
766 /* Save the TDO byte value */
767 if ( pucTdo )
769 (*(--pucTdo)) = ucTdoByte;
774 /*****************************************************************************
775 * Function: xsvfShift
776 * Description: Goes to the given starting TAP state.
777 * Calls xsvfShiftOnly to shift in the given TDI data and
778 * optionally capture the TDO data.
779 * Compares the TDO captured data against the TDO expected
780 * data.
781 * If a data mismatch occurs, then executes the exception
782 * handling loop upto ucMaxRepeat times.
783 * Parameters: pucTapState - Ptr to current TAP state.
784 * ucStartState - Starting shift state: Shift-DR or Shift-IR.
785 * lNumBits - number of bits to shift.
786 * plvTdi - ptr to lenval for TDI data.
787 * plvTdoCaptured - ptr to lenval for storing TDO data.
788 * plvTdoExpected - ptr to expected TDO data.
789 * plvTdoMask - ptr to TDO mask.
790 * ucEndState - state in which to end the shift.
791 * lRunTestTime - amount of time to wait after the shift.
792 * ucMaxRepeat - Maximum number of retries on TDO mismatch.
793 * Returns: int - 0 = success; otherwise TDO mismatch.
794 * Notes: XC9500XL-only Optimization:
795 * Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1]
796 * is NOT all zeros and sMatch==1.
797 *****************************************************************************/
798 int xsvfShift( unsigned char* pucTapState,
799 unsigned char ucStartState,
800 long lNumBits,
801 lenVal* plvTdi,
802 lenVal* plvTdoCaptured,
803 lenVal* plvTdoExpected,
804 lenVal* plvTdoMask,
805 unsigned char ucEndState,
806 long lRunTestTime,
807 unsigned char ucMaxRepeat )
809 int iErrorCode;
810 int iMismatch;
811 unsigned char ucRepeat;
812 int iExitShift;
814 iErrorCode = XSVF_ERROR_NONE;
815 iMismatch = 0;
816 ucRepeat = 0;
817 iExitShift = ( ucStartState != ucEndState );
819 XSVFDBG_PRINTF1( 3, " Shift Length = %ld\n", lNumBits );
820 XSVFDBG_PRINTF( 4, " TDI = ");
821 XSVFDBG_PRINTLENVAL( 4, plvTdi );
822 XSVFDBG_PRINTF( 4, "\n");
823 XSVFDBG_PRINTF( 4, " TDO Expected = ");
824 XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
825 XSVFDBG_PRINTF( 4, "\n");
827 if ( !lNumBits )
829 /* Compatibility with XSVF2.00: XSDR 0 = no shift, but wait in RTI */
830 if ( lRunTestTime )
832 /* Wait for prespecified XRUNTEST time */
833 xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
834 XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
835 waitTime( lRunTestTime );
838 else
842 /* Goto Shift-DR or Shift-IR */
843 xsvfGotoTapState( pucTapState, ucStartState );
845 /* Shift TDI and capture TDO */
846 xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift );
848 if ( plvTdoExpected )
850 /* Compare TDO data to expected TDO data */
851 iMismatch = !EqualLenVal( plvTdoExpected,
852 plvTdoCaptured,
853 plvTdoMask );
856 if ( iExitShift )
858 /* Update TAP state: Shift->Exit */
859 ++(*pucTapState);
860 XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
861 xsvf_pzTapState[ *pucTapState ] );
863 if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) )
865 XSVFDBG_PRINTF( 4, " TDO Expected = ");
866 XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
867 XSVFDBG_PRINTF( 4, "\n");
868 XSVFDBG_PRINTF( 4, " TDO Captured = ");
869 XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured );
870 XSVFDBG_PRINTF( 4, "\n");
871 XSVFDBG_PRINTF( 4, " TDO Mask = ");
872 XSVFDBG_PRINTLENVAL( 4, plvTdoMask );
873 XSVFDBG_PRINTF( 4, "\n");
874 XSVFDBG_PRINTF1( 3, " Retry #%d\n", ( ucRepeat + 1 ) );
875 /* Do exception handling retry - ShiftDR only */
876 xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR );
877 /* Shift 1 extra bit */
878 xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR );
879 /* Increment RUNTEST time by an additional 25% */
880 lRunTestTime += ( lRunTestTime >> 2 );
882 else
884 /* Do normal exit from Shift-XR */
885 xsvfGotoTapState( pucTapState, ucEndState );
888 if ( lRunTestTime )
890 /* Wait for prespecified XRUNTEST time */
891 xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
892 XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
893 waitTime( lRunTestTime );
896 } while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) );
899 if ( iMismatch )
901 XSVFDBG_PRINTF( 1, " TDO Expected = ");
902 XSVFDBG_PRINTLENVAL( 1, plvTdoExpected );
903 XSVFDBG_PRINTF( 1, "\n");
904 XSVFDBG_PRINTF( 1, " TDO Captured = ");
905 XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured );
906 XSVFDBG_PRINTF( 1, "\n");
907 XSVFDBG_PRINTF( 1, " TDO Mask = ");
908 XSVFDBG_PRINTLENVAL( 1, plvTdoMask );
909 XSVFDBG_PRINTF( 1, "\n");
910 if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) )
912 iErrorCode = XSVF_ERROR_MAXRETRIES;
914 else
916 iErrorCode = XSVF_ERROR_TDOMISMATCH;
920 return( iErrorCode );
923 /*****************************************************************************
924 * Function: xsvfBasicXSDRTDO
925 * Description: Get the XSDRTDO parameters and execute the XSDRTDO command.
926 * This is the common function for all XSDRTDO commands.
927 * Parameters: pucTapState - Current TAP state.
928 * lShiftLengthBits - number of bits to shift.
929 * sShiftLengthBytes - number of bytes to read.
930 * plvTdi - ptr to lenval for TDI data.
931 * lvTdoCaptured - ptr to lenval for storing TDO data.
932 * iEndState - state in which to end the shift.
933 * lRunTestTime - amount of time to wait after the shift.
934 * ucMaxRepeat - maximum xc9500/xl retries.
935 * Returns: int - 0 = success; otherwise TDO mismatch.
936 *****************************************************************************/
937 int xsvfBasicXSDRTDO( unsigned char* pucTapState,
938 long lShiftLengthBits,
939 short sShiftLengthBytes,
940 lenVal* plvTdi,
941 lenVal* plvTdoCaptured,
942 lenVal* plvTdoExpected,
943 lenVal* plvTdoMask,
944 unsigned char ucEndState,
945 long lRunTestTime,
946 unsigned char ucMaxRepeat )
948 readVal( plvTdi, sShiftLengthBytes );
949 if ( plvTdoExpected )
951 readVal( plvTdoExpected, sShiftLengthBytes );
953 return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
954 plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask,
955 ucEndState, lRunTestTime, ucMaxRepeat ) );
958 /*****************************************************************************
959 * Function: xsvfDoSDRMasking
960 * Description: Update the data value with the next XSDRINC data and address.
961 * Example: dataVal=0x01ff, nextData=0xab, addressMask=0x0100,
962 * dataMask=0x00ff, should set dataVal to 0x02ab
963 * Parameters: plvTdi - The current TDI value.
964 * plvNextData - the next data value.
965 * plvAddressMask - the address mask.
966 * plvDataMask - the data mask.
967 * Returns: void.
968 *****************************************************************************/
969 #ifdef XSVF_SUPPORT_COMPRESSION
970 void xsvfDoSDRMasking( lenVal* plvTdi,
971 lenVal* plvNextData,
972 lenVal* plvAddressMask,
973 lenVal* plvDataMask )
975 int i;
976 unsigned char ucTdi;
977 unsigned char ucTdiMask;
978 unsigned char ucDataMask;
979 unsigned char ucNextData;
980 unsigned char ucNextMask;
981 short sNextData;
983 /* add the address Mask to dataVal and return as a new dataVal */
984 addVal( plvTdi, plvTdi, plvAddressMask );
986 ucNextData = 0;
987 ucNextMask = 0;
988 sNextData = plvNextData->len;
989 for ( i = plvDataMask->len - 1; i >= 0; --i )
991 /* Go through data mask in reverse order looking for mask (1) bits */
992 ucDataMask = plvDataMask->val[ i ];
993 if ( ucDataMask )
995 /* Retrieve the corresponding TDI byte value */
996 ucTdi = plvTdi->val[ i ];
998 /* For each bit in the data mask byte, look for 1's */
999 ucTdiMask = 1;
1000 while ( ucDataMask )
1002 if ( ucDataMask & 1 )
1004 if ( !ucNextMask )
1006 /* Get the next data byte */
1007 ucNextData = plvNextData->val[ --sNextData ];
1008 ucNextMask = 1;
1011 /* Set or clear the data bit according to the next data */
1012 if ( ucNextData & ucNextMask )
1014 ucTdi |= ucTdiMask; /* Set bit */
1016 else
1018 ucTdi &= ( ~ucTdiMask ); /* Clear bit */
1021 /* Update the next data */
1022 ucNextMask <<= 1;
1024 ucTdiMask <<= 1;
1025 ucDataMask >>= 1;
1028 /* Update the TDI value */
1029 plvTdi->val[ i ] = ucTdi;
1033 #endif /* XSVF_SUPPORT_COMPRESSION */
1035 /*============================================================================
1036 * XSVF Command Functions (type = TXsvfDoCmdFuncPtr)
1037 * These functions update pXsvfInfo->iErrorCode only on an error.
1038 * Otherwise, the error code is left alone.
1039 * The function returns the error code from the function.
1040 ============================================================================*/
1042 /*****************************************************************************
1043 * Function: xsvfDoIllegalCmd
1044 * Description: Function place holder for illegal/unsupported commands.
1045 * Parameters: pXsvfInfo - XSVF information pointer.
1046 * Returns: int - 0 = success; non-zero = error.
1047 *****************************************************************************/
1048 int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
1050 XSVFDBG_PRINTF2( 0, "ERROR: Encountered unsupported command #%d (%s)\n",
1051 ((unsigned int)(pXsvfInfo->ucCommand)),
1052 ((pXsvfInfo->ucCommand < XLASTCMD)
1053 ? (xsvf_pzCommandName[pXsvfInfo->ucCommand])
1054 : "Unknown") );
1055 pXsvfInfo->iErrorCode = XSVF_ERROR_ILLEGALCMD;
1056 return( pXsvfInfo->iErrorCode );
1059 /*****************************************************************************
1060 * Function: xsvfDoXCOMPLETE
1061 * Description: XCOMPLETE (no parameters)
1062 * Update complete status for XSVF player.
1063 * Parameters: pXsvfInfo - XSVF information pointer.
1064 * Returns: int - 0 = success; non-zero = error.
1065 *****************************************************************************/
1066 int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
1068 pXsvfInfo->ucComplete = 1;
1069 return( XSVF_ERROR_NONE );
1072 /*****************************************************************************
1073 * Function: xsvfDoXTDOMASK
1074 * Description: XTDOMASK <lenVal.TdoMask[XSDRSIZE]>
1075 * Prespecify the TDO compare mask.
1076 * Parameters: pXsvfInfo - XSVF information pointer.
1077 * Returns: int - 0 = success; non-zero = error.
1078 *****************************************************************************/
1079 int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
1081 readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes );
1082 XSVFDBG_PRINTF( 4, " TDO Mask = ");
1083 XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) );
1084 XSVFDBG_PRINTF( 4, "\n");
1085 return( XSVF_ERROR_NONE );
1088 /*****************************************************************************
1089 * Function: xsvfDoXSIR
1090 * Description: XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]>
1091 * Get the instruction and shift the instruction into the TAP.
1092 * If prespecified XRUNTEST!=0, goto RUNTEST and wait after
1093 * the shift for XRUNTEST usec.
1094 * Parameters: pXsvfInfo - XSVF information pointer.
1095 * Returns: int - 0 = success; non-zero = error.
1096 *****************************************************************************/
1097 int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
1099 unsigned char ucShiftIrBits;
1100 short sShiftIrBytes;
1101 int iErrorCode;
1103 /* Get the shift length and store */
1104 readByte( &ucShiftIrBits );
1105 sShiftIrBytes = xsvfGetAsNumBytes( ucShiftIrBits );
1106 XSVFDBG_PRINTF1( 3, " XSIR length = %d\n",
1107 ((unsigned int)ucShiftIrBits) );
1109 if ( sShiftIrBytes > MAX_LEN )
1111 iErrorCode = XSVF_ERROR_DATAOVERFLOW;
1113 else
1115 /* Get and store instruction to shift in */
1116 readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) );
1118 /* Shift the data */
1119 iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
1120 ucShiftIrBits, &(pXsvfInfo->lvTdi),
1121 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1122 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
1123 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
1126 if ( iErrorCode != XSVF_ERROR_NONE )
1128 pXsvfInfo->iErrorCode = iErrorCode;
1130 return( iErrorCode );
1133 /*****************************************************************************
1134 * Function: xsvfDoXSIR2
1135 * Description: XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]>
1136 * Get the instruction and shift the instruction into the TAP.
1137 * If prespecified XRUNTEST!=0, goto RUNTEST and wait after
1138 * the shift for XRUNTEST usec.
1139 * Parameters: pXsvfInfo - XSVF information pointer.
1140 * Returns: int - 0 = success; non-zero = error.
1141 *****************************************************************************/
1142 int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
1144 long lShiftIrBits;
1145 short sShiftIrBytes;
1146 int iErrorCode;
1148 /* Get the shift length and store */
1149 readVal( &(pXsvfInfo->lvTdi), 2 );
1150 lShiftIrBits = value( &(pXsvfInfo->lvTdi) );
1151 sShiftIrBytes = xsvfGetAsNumBytes( lShiftIrBits );
1152 XSVFDBG_PRINTF1( 3, " XSIR2 length = %d\n", (int) lShiftIrBits);
1154 if ( sShiftIrBytes > MAX_LEN )
1156 iErrorCode = XSVF_ERROR_DATAOVERFLOW;
1158 else
1160 /* Get and store instruction to shift in */
1161 readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) );
1163 /* Shift the data */
1164 iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
1165 lShiftIrBits, &(pXsvfInfo->lvTdi),
1166 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1167 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
1168 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
1171 if ( iErrorCode != XSVF_ERROR_NONE )
1173 pXsvfInfo->iErrorCode = iErrorCode;
1175 return( iErrorCode );
1178 /*****************************************************************************
1179 * Function: xsvfDoXSDR
1180 * Description: XSDR <lenVal.TDI[XSDRSIZE]>
1181 * Shift the given TDI data into the JTAG scan chain.
1182 * Compare the captured TDO with the expected TDO from the
1183 * previous XSDRTDO command using the previously specified
1184 * XTDOMASK.
1185 * Parameters: pXsvfInfo - XSVF information pointer.
1186 * Returns: int - 0 = success; non-zero = error.
1187 *****************************************************************************/
1188 int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
1190 int iErrorCode;
1191 readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
1192 /* use TDOExpected from last XSDRTDO instruction */
1193 iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
1194 pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi),
1195 &(pXsvfInfo->lvTdoCaptured),
1196 &(pXsvfInfo->lvTdoExpected),
1197 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
1198 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
1199 if ( iErrorCode != XSVF_ERROR_NONE )
1201 pXsvfInfo->iErrorCode = iErrorCode;
1203 return( iErrorCode );
1206 /*****************************************************************************
1207 * Function: xsvfDoXRUNTEST
1208 * Description: XRUNTEST <uint32>
1209 * Prespecify the XRUNTEST wait time for shift operations.
1210 * Parameters: pXsvfInfo - XSVF information pointer.
1211 * Returns: int - 0 = success; non-zero = error.
1212 *****************************************************************************/
1213 int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
1215 readVal( &(pXsvfInfo->lvTdi), 4 );
1216 pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) );
1217 XSVFDBG_PRINTF1( 3, " XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime );
1218 return( XSVF_ERROR_NONE );
1221 /*****************************************************************************
1222 * Function: xsvfDoXREPEAT
1223 * Description: XREPEAT <byte>
1224 * Prespecify the maximum number of XC9500/XL retries.
1225 * Parameters: pXsvfInfo - XSVF information pointer.
1226 * Returns: int - 0 = success; non-zero = error.
1227 *****************************************************************************/
1228 int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
1230 readByte( &(pXsvfInfo->ucMaxRepeat) );
1231 XSVFDBG_PRINTF1( 3, " XREPEAT = %d\n",
1232 ((unsigned int)(pXsvfInfo->ucMaxRepeat)) );
1233 return( XSVF_ERROR_NONE );
1236 /*****************************************************************************
1237 * Function: xsvfDoXSDRSIZE
1238 * Description: XSDRSIZE <uint32>
1239 * Prespecify the XRUNTEST wait time for shift operations.
1240 * Parameters: pXsvfInfo - XSVF information pointer.
1241 * Returns: int - 0 = success; non-zero = error.
1242 *****************************************************************************/
1243 int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
1245 int iErrorCode;
1246 iErrorCode = XSVF_ERROR_NONE;
1247 readVal( &(pXsvfInfo->lvTdi), 4 );
1248 pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) );
1249 pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits );
1250 XSVFDBG_PRINTF1( 3, " XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits );
1251 if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN )
1253 iErrorCode = XSVF_ERROR_DATAOVERFLOW;
1254 pXsvfInfo->iErrorCode = iErrorCode;
1256 return( iErrorCode );
1259 /*****************************************************************************
1260 * Function: xsvfDoXSDRTDO
1261 * Description: XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
1262 * Get the TDI and expected TDO values. Then, shift.
1263 * Compare the expected TDO with the captured TDO using the
1264 * prespecified XTDOMASK.
1265 * Parameters: pXsvfInfo - XSVF information pointer.
1266 * Returns: int - 0 = success; non-zero = error.
1267 *****************************************************************************/
1268 int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
1270 int iErrorCode;
1271 iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1272 pXsvfInfo->lShiftLengthBits,
1273 pXsvfInfo->sShiftLengthBytes,
1274 &(pXsvfInfo->lvTdi),
1275 &(pXsvfInfo->lvTdoCaptured),
1276 &(pXsvfInfo->lvTdoExpected),
1277 &(pXsvfInfo->lvTdoMask),
1278 pXsvfInfo->ucEndDR,
1279 pXsvfInfo->lRunTestTime,
1280 pXsvfInfo->ucMaxRepeat );
1281 if ( iErrorCode != XSVF_ERROR_NONE )
1283 pXsvfInfo->iErrorCode = iErrorCode;
1285 return( iErrorCode );
1288 /*****************************************************************************
1289 * Function: xsvfDoXSETSDRMASKS
1290 * Description: XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]>
1291 * <lenVal.DataMask[XSDRSIZE]>
1292 * Get the prespecified address and data mask for the XSDRINC
1293 * command.
1294 * Used for xc9500/xl compressed XSVF data.
1295 * Parameters: pXsvfInfo - XSVF information pointer.
1296 * Returns: int - 0 = success; non-zero = error.
1297 *****************************************************************************/
1298 #ifdef XSVF_SUPPORT_COMPRESSION
1299 int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
1301 /* read the addressMask */
1302 readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes );
1303 /* read the dataMask */
1304 readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes );
1306 XSVFDBG_PRINTF( 4, " Address Mask = " );
1307 XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) );
1308 XSVFDBG_PRINTF( 4, "\n" );
1309 XSVFDBG_PRINTF( 4, " Data Mask = " );
1310 XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) );
1311 XSVFDBG_PRINTF( 4, "\n" );
1313 return( XSVF_ERROR_NONE );
1315 #endif /* XSVF_SUPPORT_COMPRESSION */
1317 /*****************************************************************************
1318 * Function: xsvfDoXSDRINC
1319 * Description: XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)>
1320 * <lenVal.data[XSETSDRMASKS.dataMask.len]> ...
1321 * Get the XSDRINC parameters and execute the XSDRINC command.
1322 * XSDRINC starts by loading the first TDI shift value.
1323 * Then, for numTimes, XSDRINC gets the next piece of data,
1324 * replaces the bits from the starting TDI as defined by the
1325 * XSETSDRMASKS.dataMask, adds the address mask from
1326 * XSETSDRMASKS.addressMask, shifts the new TDI value,
1327 * and compares the TDO to the expected TDO from the previous
1328 * XSDRTDO command using the XTDOMASK.
1329 * Used for xc9500/xl compressed XSVF data.
1330 * Parameters: pXsvfInfo - XSVF information pointer.
1331 * Returns: int - 0 = success; non-zero = error.
1332 *****************************************************************************/
1333 #ifdef XSVF_SUPPORT_COMPRESSION
1334 int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
1336 int iErrorCode;
1337 int iDataMaskLen;
1338 unsigned char ucDataMask;
1339 unsigned char ucNumTimes;
1340 unsigned char i;
1342 readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
1343 iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
1344 pXsvfInfo->lShiftLengthBits,
1345 &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured),
1346 &(pXsvfInfo->lvTdoExpected),
1347 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
1348 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
1349 if ( !iErrorCode )
1351 /* Calculate number of data mask bits */
1352 iDataMaskLen = 0;
1353 for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i )
1355 ucDataMask = pXsvfInfo->lvDataMask.val[ i ];
1356 while ( ucDataMask )
1358 iDataMaskLen += ( ucDataMask & 1 );
1359 ucDataMask >>= 1;
1363 /* Get the number of data pieces, i.e. number of times to shift */
1364 readByte( &ucNumTimes );
1366 /* For numTimes, get data, fix TDI, and shift */
1367 for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i )
1369 readVal( &(pXsvfInfo->lvNextData),
1370 xsvfGetAsNumBytes( iDataMaskLen ) );
1371 xsvfDoSDRMasking( &(pXsvfInfo->lvTdi),
1372 &(pXsvfInfo->lvNextData),
1373 &(pXsvfInfo->lvAddressMask),
1374 &(pXsvfInfo->lvDataMask) );
1375 iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState),
1376 XTAPSTATE_SHIFTDR,
1377 pXsvfInfo->lShiftLengthBits,
1378 &(pXsvfInfo->lvTdi),
1379 &(pXsvfInfo->lvTdoCaptured),
1380 &(pXsvfInfo->lvTdoExpected),
1381 &(pXsvfInfo->lvTdoMask),
1382 pXsvfInfo->ucEndDR,
1383 pXsvfInfo->lRunTestTime,
1384 pXsvfInfo->ucMaxRepeat );
1387 if ( iErrorCode != XSVF_ERROR_NONE )
1389 pXsvfInfo->iErrorCode = iErrorCode;
1391 return( iErrorCode );
1393 #endif /* XSVF_SUPPORT_COMPRESSION */
1395 /*****************************************************************************
1396 * Function: xsvfDoXSDRBCE
1397 * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]>
1398 * If not already in SHIFTDR, goto SHIFTDR.
1399 * Shift the given TDI data into the JTAG scan chain.
1400 * Ignore TDO.
1401 * If cmd==XSDRE, then goto ENDDR. Otherwise, stay in ShiftDR.
1402 * XSDRB, XSDRC, and XSDRE are the same implementation.
1403 * Parameters: pXsvfInfo - XSVF information pointer.
1404 * Returns: int - 0 = success; non-zero = error.
1405 *****************************************************************************/
1406 int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
1408 unsigned char ucEndDR;
1409 int iErrorCode;
1410 ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ?
1411 pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
1412 iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1413 pXsvfInfo->lShiftLengthBits,
1414 pXsvfInfo->sShiftLengthBytes,
1415 &(pXsvfInfo->lvTdi),
1416 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1417 /*plvTdoMask*/0, ucEndDR,
1418 /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
1419 if ( iErrorCode != XSVF_ERROR_NONE )
1421 pXsvfInfo->iErrorCode = iErrorCode;
1423 return( iErrorCode );
1426 /*****************************************************************************
1427 * Function: xsvfDoXSDRTDOBCE
1428 * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
1429 * If not already in SHIFTDR, goto SHIFTDR.
1430 * Shift the given TDI data into the JTAG scan chain.
1431 * Compare TDO, but do NOT use XTDOMASK.
1432 * If cmd==XSDRTDOE, then goto ENDDR. Otherwise, stay in ShiftDR.
1433 * XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation.
1434 * Parameters: pXsvfInfo - XSVF information pointer.
1435 * Returns: int - 0 = success; non-zero = error.
1436 *****************************************************************************/
1437 int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
1439 unsigned char ucEndDR;
1440 int iErrorCode;
1441 ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ?
1442 pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
1443 iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1444 pXsvfInfo->lShiftLengthBits,
1445 pXsvfInfo->sShiftLengthBytes,
1446 &(pXsvfInfo->lvTdi),
1447 &(pXsvfInfo->lvTdoCaptured),
1448 &(pXsvfInfo->lvTdoExpected),
1449 /*plvTdoMask*/0, ucEndDR,
1450 /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
1451 if ( iErrorCode != XSVF_ERROR_NONE )
1453 pXsvfInfo->iErrorCode = iErrorCode;
1455 return( iErrorCode );
1458 /*****************************************************************************
1459 * Function: xsvfDoXSTATE
1460 * Description: XSTATE <byte>
1461 * <byte> == XTAPSTATE;
1462 * Get the state parameter and transition the TAP to that state.
1463 * Parameters: pXsvfInfo - XSVF information pointer.
1464 * Returns: int - 0 = success; non-zero = error.
1465 *****************************************************************************/
1466 int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
1468 unsigned char ucNextState;
1469 int iErrorCode;
1470 readByte( &ucNextState );
1471 iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState );
1472 if ( iErrorCode != XSVF_ERROR_NONE )
1474 pXsvfInfo->iErrorCode = iErrorCode;
1476 return( iErrorCode );
1479 /*****************************************************************************
1480 * Function: xsvfDoXENDXR
1481 * Description: XENDIR/XENDDR <byte>
1482 * <byte>: 0 = RUNTEST; 1 = PAUSE.
1483 * Get the prespecified XENDIR or XENDDR.
1484 * Both XENDIR and XENDDR use the same implementation.
1485 * Parameters: pXsvfInfo - XSVF information pointer.
1486 * Returns: int - 0 = success; non-zero = error.
1487 *****************************************************************************/
1488 int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
1490 int iErrorCode;
1491 unsigned char ucEndState;
1493 iErrorCode = XSVF_ERROR_NONE;
1494 readByte( &ucEndState );
1495 if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) )
1497 iErrorCode = XSVF_ERROR_ILLEGALSTATE;
1499 else
1502 if ( pXsvfInfo->ucCommand == XENDIR )
1504 if ( ucEndState == XENDXR_RUNTEST )
1506 pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST;
1508 else
1510 pXsvfInfo->ucEndIR = XTAPSTATE_PAUSEIR;
1512 XSVFDBG_PRINTF1( 3, " ENDIR State = %s\n",
1513 xsvf_pzTapState[ pXsvfInfo->ucEndIR ] );
1515 else /* XENDDR */
1517 if ( ucEndState == XENDXR_RUNTEST )
1519 pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST;
1521 else
1523 pXsvfInfo->ucEndDR = XTAPSTATE_PAUSEDR;
1525 XSVFDBG_PRINTF1( 3, " ENDDR State = %s\n",
1526 xsvf_pzTapState[ pXsvfInfo->ucEndDR ] );
1530 if ( iErrorCode != XSVF_ERROR_NONE )
1532 pXsvfInfo->iErrorCode = iErrorCode;
1534 return( iErrorCode );
1537 /*****************************************************************************
1538 * Function: xsvfDoXCOMMENT
1539 * Description: XCOMMENT <text string ending in \0>
1540 * <text string ending in \0> == text comment;
1541 * Arbitrary comment embedded in the XSVF.
1542 * Parameters: pXsvfInfo - XSVF information pointer.
1543 * Returns: int - 0 = success; non-zero = error.
1544 *****************************************************************************/
1545 int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
1547 /* Use the comment for debugging */
1548 /* Otherwise, read through the comment to the end '\0' and ignore */
1549 unsigned char ucText;
1551 #ifdef DEBUG_MODE
1552 if ( xsvf_iDebugLevel > 0 )
1554 putchar( ' ' );
1556 #endif
1560 readByte( &ucText );
1561 #ifdef DEBUG_MODE
1562 if ( xsvf_iDebugLevel > 0 )
1564 putchar( ucText ? ucText : '\n' );
1566 #endif
1567 } while ( ucText );
1569 pXsvfInfo->iErrorCode = XSVF_ERROR_NONE;
1571 return( pXsvfInfo->iErrorCode );
1574 /*****************************************************************************
1575 * Function: xsvfDoXWAIT
1576 * Description: XWAIT <wait_state> <end_state> <wait_time>
1577 * If not already in <wait_state>, then go to <wait_state>.
1578 * Wait in <wait_state> for <wait_time> microseconds.
1579 * Finally, if not already in <end_state>, then goto <end_state>.
1580 * Parameters: pXsvfInfo - XSVF information pointer.
1581 * Returns: int - 0 = success; non-zero = error.
1582 *****************************************************************************/
1583 int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
1585 unsigned char ucWaitState;
1586 unsigned char ucEndState;
1587 long lWaitTime;
1589 /* Get Parameters */
1590 /* <wait_state> */
1591 readVal( &(pXsvfInfo->lvTdi), 1 );
1592 ucWaitState = pXsvfInfo->lvTdi.val[0];
1594 /* <end_state> */
1595 readVal( &(pXsvfInfo->lvTdi), 1 );
1596 ucEndState = pXsvfInfo->lvTdi.val[0];
1598 /* <wait_time> */
1599 readVal( &(pXsvfInfo->lvTdi), 4 );
1600 lWaitTime = value( &(pXsvfInfo->lvTdi) );
1601 XSVFDBG_PRINTF2( 3, " XWAIT: state = %s; time = %ld\n",
1602 xsvf_pzTapState[ ucWaitState ], lWaitTime );
1604 /* If not already in <wait_state>, go to <wait_state> */
1605 if ( pXsvfInfo->ucTapState != ucWaitState )
1607 xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState );
1610 /* Wait for <wait_time> microseconds */
1611 waitTime( lWaitTime );
1613 /* If not already in <end_state>, go to <end_state> */
1614 if ( pXsvfInfo->ucTapState != ucEndState )
1616 xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState );
1619 return( XSVF_ERROR_NONE );
1623 /*============================================================================
1624 * Execution Control Functions
1625 ============================================================================*/
1627 /*****************************************************************************
1628 * Function: xsvfInitialize
1629 * Description: Initialize the xsvf player.
1630 * Call this before running the player to initialize the data
1631 * in the SXsvfInfo struct.
1632 * xsvfCleanup is called to clean up the data in SXsvfInfo
1633 * after the XSVF is played.
1634 * Parameters: pXsvfInfo - ptr to the XSVF information.
1635 * Returns: int - 0 = success; otherwise error.
1636 *****************************************************************************/
1637 int xsvfInitialize( SXsvfInfo* pXsvfInfo )
1639 /* Initialize values */
1640 pXsvfInfo->iErrorCode = xsvfInfoInit( pXsvfInfo );
1642 if ( !pXsvfInfo->iErrorCode )
1644 /* Initialize the TAPs */
1645 pXsvfInfo->iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState),
1646 XTAPSTATE_RESET );
1649 return( pXsvfInfo->iErrorCode );
1652 /*****************************************************************************
1653 * Function: xsvfRun
1654 * Description: Run the xsvf player for a single command and return.
1655 * First, call xsvfInitialize.
1656 * Then, repeatedly call this function until an error is detected
1657 * or until the pXsvfInfo->ucComplete variable is non-zero.
1658 * Finally, call xsvfCleanup to cleanup any remnants.
1659 * Parameters: pXsvfInfo - ptr to the XSVF information.
1660 * Returns: int - 0 = success; otherwise error.
1661 *****************************************************************************/
1662 int xsvfRun( SXsvfInfo* pXsvfInfo )
1664 /* Process the XSVF commands */
1665 if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) )
1667 /* read 1 byte for the instruction */
1668 readByte( &(pXsvfInfo->ucCommand) );
1669 ++(pXsvfInfo->lCommandCount);
1671 if ( pXsvfInfo->ucCommand < XLASTCMD )
1673 /* Execute the command. Func sets error code. */
1674 XSVFDBG_PRINTF1( 2, " %s\n",
1675 xsvf_pzCommandName[pXsvfInfo->ucCommand] );
1676 /* If your compiler cannot take this form,
1677 then convert to a switch statement */
1678 xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo );
1680 else
1682 /* Illegal command value. Func sets error code. */
1683 xsvfDoIllegalCmd( pXsvfInfo );
1687 return( pXsvfInfo->iErrorCode );
1690 /*****************************************************************************
1691 * Function: xsvfCleanup
1692 * Description: cleanup remnants of the xsvf player.
1693 * Parameters: pXsvfInfo - ptr to the XSVF information.
1694 * Returns: void.
1695 *****************************************************************************/
1696 void xsvfCleanup( SXsvfInfo* pXsvfInfo )
1698 xsvfInfoCleanup( pXsvfInfo );
1702 /*============================================================================
1703 * xsvfExecute() - The primary entry point to the XSVF player
1704 ============================================================================*/
1706 /*****************************************************************************
1707 * Function: xsvfExecute
1708 * Description: Process, interpret, and apply the XSVF commands.
1709 * See port.c:readByte for source of XSVF data.
1710 * Parameters: none.
1711 * Returns: int - Legacy result values: 1 == success; 0 == failed.
1712 *****************************************************************************/
1713 int xsvfExecute()
1715 SXsvfInfo xsvfInfo;
1717 xsvfInitialize( &xsvfInfo );
1719 while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) )
1721 xsvfRun( &xsvfInfo );
1724 if ( xsvfInfo.iErrorCode )
1726 XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[
1727 ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST )
1728 ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] );
1729 XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld. See line #%ld in the XSVF ASCII file.\n",
1730 xsvfInfo.lCommandCount, xsvfInfo.lCommandCount );
1732 else
1734 XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" );
1737 xsvfCleanup( &xsvfInfo );
1739 return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) );
1743 /*============================================================================
1744 * main
1745 ============================================================================*/
1747 /*****************************************************************************
1748 * Function: main
1749 * Description: main function.
1750 * Specified here for creating stand-alone debug executable.
1751 * Embedded users should call xsvfExecute() directly.
1752 * Parameters: iArgc - number of command-line arguments.
1753 * ppzArgv - array of ptrs to strings (command-line arguments).
1754 * Returns: int - Legacy return value: 1 = success; 0 = error.
1755 *****************************************************************************/
1756 #ifdef XSVF_MAIN
1757 int main( int iArgc, char** ppzArgv )
1759 int iErrorCode;
1760 char* pzXsvfFileName;
1761 int i;
1762 clock_t startClock;
1763 clock_t endClock;
1765 iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE );
1766 pzXsvfFileName = 0;
1768 printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION );
1770 for ( i = 1; i < iArgc ; ++i )
1772 if ( !_stricmp( ppzArgv[ i ], "-v" ) )
1774 ++i;
1775 if ( i >= iArgc )
1777 printf( "ERROR: missing <level> parameter for -v option.\n" );
1779 else
1781 xsvf_iDebugLevel = atoi( ppzArgv[ i ] );
1782 printf( "Verbose level = %d\n", xsvf_iDebugLevel );
1785 else
1787 pzXsvfFileName = ppzArgv[ i ];
1788 printf( "XSVF file = %s\n", pzXsvfFileName );
1792 if ( !pzXsvfFileName )
1794 printf( "USAGE: playxsvf [-v level] filename.xsvf\n" );
1795 printf( "where: -v level = verbose, level = 0-4 (default=0)\n" );
1796 printf( " filename.xsvf = the XSVF file to execute.\n" );
1798 else
1800 /* read from the XSVF file instead of a real prom */
1801 in = fopen( pzXsvfFileName, "rb" );
1802 if ( !in )
1804 printf( "ERROR: Cannot open file %s\n", pzXsvfFileName );
1805 iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN );
1807 else
1809 /* Initialize the I/O. SetPort initializes I/O on first call */
1810 setPort( TMS, 1 );
1812 /* Execute the XSVF in the file */
1813 startClock = clock();
1814 iErrorCode = xsvfExecute();
1815 endClock = clock();
1816 fclose( in );
1817 printf( "Execution Time = %.3f seconds\n",
1818 (((double)(endClock - startClock))/CLOCKS_PER_SEC) );
1822 return( iErrorCode );
1824 #endif /* XSVF_MAIN */