|
@@ -0,0 +1,1864 @@
|
|
|
|
+/*
|
|
|
|
+ * (C) Copyright 2003
|
|
|
|
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
|
|
|
|
+ *
|
|
|
|
+ * See file CREDITS for list of people who contributed to this
|
|
|
|
+ * project.
|
|
|
|
+ *
|
|
|
|
+ * This program is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
|
|
+ * published by the Free Software Foundation; either version 2 of
|
|
|
|
+ * the License, or (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
+ * along with this program; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
+ * MA 02111-1307 USA
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * file: micro.c
|
|
|
|
+ * abstract: This file contains the function, xsvfExecute(),
|
|
|
|
+ * call for interpreting the XSVF commands.
|
|
|
|
+ * Usage: Call xsvfExecute() to process XSVF data.
|
|
|
|
+ * The XSVF data is retrieved by readByte() in ports.c
|
|
|
|
+ * Remove the main function if you already have one.
|
|
|
|
+ * Options: XSVF_SUPPORT_COMPRESSION
|
|
|
|
+ * This define supports the XC9500/XL compression scheme.
|
|
|
|
+ * This define adds support for XSDRINC and XSETSDRMASKS.
|
|
|
|
+ * XSVF_SUPPORT_ERRORCODES
|
|
|
|
+ * This define causes the xsvfExecute function to return
|
|
|
|
+ * an error code for specific errors. See error codes below.
|
|
|
|
+ * If this is not defined, the return value defaults to the
|
|
|
|
+ * legacy values for backward compatibility:
|
|
|
|
+ * 1 = success; 0 = failure.
|
|
|
|
+ * Debugging: DEBUG_MODE (Legacy name)
|
|
|
|
+ * Define DEBUG_MODE to compile with debugging features.
|
|
|
|
+ * Both micro.c and ports.c must be compiled with the DEBUG_MODE
|
|
|
|
+ * defined to enable the standalone main implementation in
|
|
|
|
+ * micro.c that reads XSVF from a file.
|
|
|
|
+ * History: v2.00 - Original XSVF implementation.
|
|
|
|
+ * v4.04 - Added delay at end of XSIR for XC18v00 support.
|
|
|
|
+ * Added new commands for CoolRunner support:
|
|
|
|
+ * XSTATE, XENDIR, XENDDR
|
|
|
|
+ * v4.05 - Cleanup micro.c but leave ports.c intact.
|
|
|
|
+ * v4.06 - Fix xsvfGotoTapState for retry transition.
|
|
|
|
+ * v4.07 - Update example waitTime implementations for
|
|
|
|
+ * compatibility with Virtex-II.
|
|
|
|
+ * v4.10 - Add new XSIR2 command that supports a 2-byte
|
|
|
|
+ * IR-length parameter for IR shifts > 255 bits.
|
|
|
|
+ * v4.11 - No change. Update version to match SVF2XSVF xlator.
|
|
|
|
+ * v4.14 - Added XCOMMENT.
|
|
|
|
+ * v5.00 - Improve XSTATE support.
|
|
|
|
+ * Added XWAIT.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+
|
|
|
|
+#include <common.h>
|
|
|
|
+#include <command.h>
|
|
|
|
+#include <asm/processor.h>
|
|
|
|
+
|
|
|
|
+#include "micro.h"
|
|
|
|
+#include "lenval.h"
|
|
|
|
+#include "ports.h"
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+extern const unsigned char fpgadata[];
|
|
|
|
+extern int filesize;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF #define
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+#define XSVF_VERSION "5.00"
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Define: XSVF_SUPPORT_COMPRESSION
|
|
|
|
+ * Description: Define this to support the XC9500/XL XSVF data compression
|
|
|
|
+ * scheme.
|
|
|
|
+ * Code size can be reduced by NOT supporting this feature.
|
|
|
|
+ * However, you must use the -nc (no compress) option when
|
|
|
|
+ * translating SVF to XSVF using the SVF2XSVF translator.
|
|
|
|
+ * Corresponding, uncompressed XSVF may be larger.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifndef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+#define XSVF_SUPPORT_COMPRESSION 1
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Define: XSVF_SUPPORT_ERRORCODES
|
|
|
|
+ * Description: Define this to support the new XSVF error codes.
|
|
|
|
+ * (The original XSVF player just returned 1 for success and
|
|
|
|
+ * 0 for an unspecified failure.)
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifndef XSVF_SUPPORT_ERRORCODES
|
|
|
|
+#define XSVF_SUPPORT_ERRORCODES 1
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef XSVF_SUPPORT_ERRORCODES
|
|
|
|
+#define XSVF_ERRORCODE(errorCode) errorCode
|
|
|
|
+#else /* Use legacy error code */
|
|
|
|
+#define XSVF_ERRORCODE(errorCode) ((errorCode==XSVF_ERROR_NONE)?1:0)
|
|
|
|
+#endif /* XSVF_SUPPORT_ERRORCODES */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * DEBUG_MODE #define
|
|
|
|
+ ============================================================================*/
|
|
|
|
+#define DEBUG_MODE
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG_MODE
|
|
|
|
+#define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \
|
|
|
|
+ { if ( xsvf_iDebugLevel >= iDebugLevel ) \
|
|
|
|
+ printf( pzFormat ); }
|
|
|
|
+#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \
|
|
|
|
+ { if ( xsvf_iDebugLevel >= iDebugLevel ) \
|
|
|
|
+ printf( pzFormat, arg1 ); }
|
|
|
|
+#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \
|
|
|
|
+ { if ( xsvf_iDebugLevel >= iDebugLevel ) \
|
|
|
|
+ printf( pzFormat, arg1, arg2 ); }
|
|
|
|
+#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \
|
|
|
|
+ { if ( xsvf_iDebugLevel >= iDebugLevel ) \
|
|
|
|
+ printf( pzFormat, arg1, arg2, arg3 ); }
|
|
|
|
+#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \
|
|
|
|
+ { if ( xsvf_iDebugLevel >= iDebugLevel ) \
|
|
|
|
+ xsvfPrintLenVal(plenVal); }
|
|
|
|
+#else /* !DEBUG_MODE */
|
|
|
|
+#define XSVFDBG_PRINTF(iDebugLevel,pzFormat)
|
|
|
|
+#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1)
|
|
|
|
+#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2)
|
|
|
|
+#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3)
|
|
|
|
+#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal)
|
|
|
|
+#endif /* DEBUG_MODE */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Type Declarations
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Struct: SXsvfInfo
|
|
|
|
+ * Description: This structure contains all of the data used during the
|
|
|
|
+ * execution of the XSVF. Some data is persistent, predefined
|
|
|
|
+ * information (e.g. lRunTestTime). The bulk of this struct's
|
|
|
|
+ * size is due to the lenVal structs (defined in lenval.h)
|
|
|
|
+ * which contain buffers for the active shift data. The MAX_LEN
|
|
|
|
+ * #define in lenval.h defines the size of these buffers.
|
|
|
|
+ * These buffers must be large enough to store the longest
|
|
|
|
+ * shift data in your XSVF file. For example:
|
|
|
|
+ * MAX_LEN >= ( longest_shift_data_in_bits / 8 )
|
|
|
|
+ * Because the lenVal struct dominates the space usage of this
|
|
|
|
+ * struct, the rough size of this struct is:
|
|
|
|
+ * sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals)
|
|
|
|
+ * xsvfInitialize() contains initialization code for the data
|
|
|
|
+ * in this struct.
|
|
|
|
+ * xsvfCleanup() contains cleanup code for the data in this
|
|
|
|
+ * struct.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+typedef struct tagSXsvfInfo
|
|
|
|
+{
|
|
|
|
+ /* XSVF status information */
|
|
|
|
+ unsigned char ucComplete; /* 0 = running; 1 = complete */
|
|
|
|
+ unsigned char ucCommand; /* Current XSVF command byte */
|
|
|
|
+ long lCommandCount; /* Number of commands processed */
|
|
|
|
+ int iErrorCode; /* An error code. 0 = no error. */
|
|
|
|
+
|
|
|
|
+ /* TAP state/sequencing information */
|
|
|
|
+ unsigned char ucTapState; /* Current TAP state */
|
|
|
|
+ unsigned char ucEndIR; /* ENDIR TAP state (See SVF) */
|
|
|
|
+ unsigned char ucEndDR; /* ENDDR TAP state (See SVF) */
|
|
|
|
+
|
|
|
|
+ /* RUNTEST information */
|
|
|
|
+ unsigned char ucMaxRepeat; /* Max repeat loops (for xc9500/xl) */
|
|
|
|
+ long lRunTestTime; /* Pre-specified RUNTEST time (usec) */
|
|
|
|
+
|
|
|
|
+ /* Shift Data Info and Buffers */
|
|
|
|
+ long lShiftLengthBits; /* Len. current shift data in bits */
|
|
|
|
+ short sShiftLengthBytes; /* Len. current shift data in bytes */
|
|
|
|
+
|
|
|
|
+ lenVal lvTdi; /* Current TDI shift data */
|
|
|
|
+ lenVal lvTdoExpected; /* Expected TDO shift data */
|
|
|
|
+ lenVal lvTdoCaptured; /* Captured TDO shift data */
|
|
|
|
+ lenVal lvTdoMask; /* TDO mask: 0=dontcare; 1=compare */
|
|
|
|
+
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+ /* XSDRINC Data Buffers */
|
|
|
|
+ lenVal lvAddressMask; /* Address mask for XSDRINC */
|
|
|
|
+ lenVal lvDataMask; /* Data mask for XSDRINC */
|
|
|
|
+ lenVal lvNextData; /* Next data for XSDRINC */
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+} SXsvfInfo;
|
|
|
|
+
|
|
|
|
+/* Declare pointer to functions that perform XSVF commands */
|
|
|
|
+typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Command Bytes
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/* encodings of xsvf instructions */
|
|
|
|
+#define XCOMPLETE 0
|
|
|
|
+#define XTDOMASK 1
|
|
|
|
+#define XSIR 2
|
|
|
|
+#define XSDR 3
|
|
|
|
+#define XRUNTEST 4
|
|
|
|
+/* Reserved 5 */
|
|
|
|
+/* Reserved 6 */
|
|
|
|
+#define XREPEAT 7
|
|
|
|
+#define XSDRSIZE 8
|
|
|
|
+#define XSDRTDO 9
|
|
|
|
+#define XSETSDRMASKS 10
|
|
|
|
+#define XSDRINC 11
|
|
|
|
+#define XSDRB 12
|
|
|
|
+#define XSDRC 13
|
|
|
|
+#define XSDRE 14
|
|
|
|
+#define XSDRTDOB 15
|
|
|
|
+#define XSDRTDOC 16
|
|
|
|
+#define XSDRTDOE 17
|
|
|
|
+#define XSTATE 18 /* 4.00 */
|
|
|
|
+#define XENDIR 19 /* 4.04 */
|
|
|
|
+#define XENDDR 20 /* 4.04 */
|
|
|
|
+#define XSIR2 21 /* 4.10 */
|
|
|
|
+#define XCOMMENT 22 /* 4.14 */
|
|
|
|
+#define XWAIT 23 /* 5.00 */
|
|
|
|
+/* Insert new commands here */
|
|
|
|
+/* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */
|
|
|
|
+#define XLASTCMD 24 /* Last command marker */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Command Parameter Values
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+#define XSTATE_RESET 0 /* 4.00 parameter for XSTATE */
|
|
|
|
+#define XSTATE_RUNTEST 1 /* 4.00 parameter for XSTATE */
|
|
|
|
+
|
|
|
|
+#define XENDXR_RUNTEST 0 /* 4.04 parameter for XENDIR/DR */
|
|
|
|
+#define XENDXR_PAUSE 1 /* 4.04 parameter for XENDIR/DR */
|
|
|
|
+
|
|
|
|
+/* TAP states */
|
|
|
|
+#define XTAPSTATE_RESET 0x00
|
|
|
|
+#define XTAPSTATE_RUNTEST 0x01 /* a.k.a. IDLE */
|
|
|
|
+#define XTAPSTATE_SELECTDR 0x02
|
|
|
|
+#define XTAPSTATE_CAPTUREDR 0x03
|
|
|
|
+#define XTAPSTATE_SHIFTDR 0x04
|
|
|
|
+#define XTAPSTATE_EXIT1DR 0x05
|
|
|
|
+#define XTAPSTATE_PAUSEDR 0x06
|
|
|
|
+#define XTAPSTATE_EXIT2DR 0x07
|
|
|
|
+#define XTAPSTATE_UPDATEDR 0x08
|
|
|
|
+#define XTAPSTATE_IRSTATES 0x09 /* All IR states begin here */
|
|
|
|
+#define XTAPSTATE_SELECTIR 0x09
|
|
|
|
+#define XTAPSTATE_CAPTUREIR 0x0A
|
|
|
|
+#define XTAPSTATE_SHIFTIR 0x0B
|
|
|
|
+#define XTAPSTATE_EXIT1IR 0x0C
|
|
|
|
+#define XTAPSTATE_PAUSEIR 0x0D
|
|
|
|
+#define XTAPSTATE_EXIT2IR 0x0E
|
|
|
|
+#define XTAPSTATE_UPDATEIR 0x0F
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Function Prototypes
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ); /* Illegal command function */
|
|
|
|
+int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSIR( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDR( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo );
|
|
|
|
+int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo );
|
|
|
|
+/* Insert new command functions here */
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Global Variables
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/* Array of XSVF command functions. Must follow command byte value order! */
|
|
|
|
+/* If your compiler cannot take this form, then convert to a switch statement*/
|
|
|
|
+TXsvfDoCmdFuncPtr xsvf_pfDoCmd[] =
|
|
|
|
+{
|
|
|
|
+ xsvfDoXCOMPLETE, /* 0 */
|
|
|
|
+ xsvfDoXTDOMASK, /* 1 */
|
|
|
|
+ xsvfDoXSIR, /* 2 */
|
|
|
|
+ xsvfDoXSDR, /* 3 */
|
|
|
|
+ xsvfDoXRUNTEST, /* 4 */
|
|
|
|
+ xsvfDoIllegalCmd, /* 5 */
|
|
|
|
+ xsvfDoIllegalCmd, /* 6 */
|
|
|
|
+ xsvfDoXREPEAT, /* 7 */
|
|
|
|
+ xsvfDoXSDRSIZE, /* 8 */
|
|
|
|
+ xsvfDoXSDRTDO, /* 9 */
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+ xsvfDoXSETSDRMASKS, /* 10 */
|
|
|
|
+ xsvfDoXSDRINC, /* 11 */
|
|
|
|
+#else
|
|
|
|
+ xsvfDoIllegalCmd, /* 10 */
|
|
|
|
+ xsvfDoIllegalCmd, /* 11 */
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+ xsvfDoXSDRBCE, /* 12 */
|
|
|
|
+ xsvfDoXSDRBCE, /* 13 */
|
|
|
|
+ xsvfDoXSDRBCE, /* 14 */
|
|
|
|
+ xsvfDoXSDRTDOBCE, /* 15 */
|
|
|
|
+ xsvfDoXSDRTDOBCE, /* 16 */
|
|
|
|
+ xsvfDoXSDRTDOBCE, /* 17 */
|
|
|
|
+ xsvfDoXSTATE, /* 18 */
|
|
|
|
+ xsvfDoXENDXR, /* 19 */
|
|
|
|
+ xsvfDoXENDXR, /* 20 */
|
|
|
|
+ xsvfDoXSIR2, /* 21 */
|
|
|
|
+ xsvfDoXCOMMENT, /* 22 */
|
|
|
|
+ xsvfDoXWAIT /* 23 */
|
|
|
|
+/* Insert new command functions here */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG_MODE
|
|
|
|
+char* xsvf_pzCommandName[] =
|
|
|
|
+{
|
|
|
|
+ "XCOMPLETE",
|
|
|
|
+ "XTDOMASK",
|
|
|
|
+ "XSIR",
|
|
|
|
+ "XSDR",
|
|
|
|
+ "XRUNTEST",
|
|
|
|
+ "Reserved5",
|
|
|
|
+ "Reserved6",
|
|
|
|
+ "XREPEAT",
|
|
|
|
+ "XSDRSIZE",
|
|
|
|
+ "XSDRTDO",
|
|
|
|
+ "XSETSDRMASKS",
|
|
|
|
+ "XSDRINC",
|
|
|
|
+ "XSDRB",
|
|
|
|
+ "XSDRC",
|
|
|
|
+ "XSDRE",
|
|
|
|
+ "XSDRTDOB",
|
|
|
|
+ "XSDRTDOC",
|
|
|
|
+ "XSDRTDOE",
|
|
|
|
+ "XSTATE",
|
|
|
|
+ "XENDIR",
|
|
|
|
+ "XENDDR",
|
|
|
|
+ "XSIR2",
|
|
|
|
+ "XCOMMENT",
|
|
|
|
+ "XWAIT"
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+char* xsvf_pzErrorName[] =
|
|
|
|
+{
|
|
|
|
+ "No error",
|
|
|
|
+ "ERROR: Unknown",
|
|
|
|
+ "ERROR: TDO mismatch",
|
|
|
|
+ "ERROR: TDO mismatch and exceeded max retries",
|
|
|
|
+ "ERROR: Unsupported XSVF command",
|
|
|
|
+ "ERROR: Illegal state specification",
|
|
|
|
+ "ERROR: Data overflows allocated MAX_LEN buffer size"
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+char* xsvf_pzTapState[] =
|
|
|
|
+{
|
|
|
|
+ "RESET", /* 0x00 */
|
|
|
|
+ "RUNTEST/IDLE", /* 0x01 */
|
|
|
|
+ "DRSELECT", /* 0x02 */
|
|
|
|
+ "DRCAPTURE", /* 0x03 */
|
|
|
|
+ "DRSHIFT", /* 0x04 */
|
|
|
|
+ "DREXIT1", /* 0x05 */
|
|
|
|
+ "DRPAUSE", /* 0x06 */
|
|
|
|
+ "DREXIT2", /* 0x07 */
|
|
|
|
+ "DRUPDATE", /* 0x08 */
|
|
|
|
+ "IRSELECT", /* 0x09 */
|
|
|
|
+ "IRCAPTURE", /* 0x0A */
|
|
|
|
+ "IRSHIFT", /* 0x0B */
|
|
|
|
+ "IREXIT1", /* 0x0C */
|
|
|
|
+ "IRPAUSE", /* 0x0D */
|
|
|
|
+ "IREXIT2", /* 0x0E */
|
|
|
|
+ "IRUPDATE" /* 0x0F */
|
|
|
|
+};
|
|
|
|
+#endif /* DEBUG_MODE */
|
|
|
|
+
|
|
|
|
+//#ifdef DEBUG_MODE
|
|
|
|
+// FILE* in; /* Legacy DEBUG_MODE file pointer */
|
|
|
|
+int xsvf_iDebugLevel;
|
|
|
|
+//#endif /* DEBUG_MODE */
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * Utility Functions
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfPrintLenVal
|
|
|
|
+ * Description: Print the lenval value in hex.
|
|
|
|
+ * Parameters: plv - ptr to lenval.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifdef DEBUG_MODE
|
|
|
|
+void xsvfPrintLenVal( lenVal *plv )
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if ( plv )
|
|
|
|
+ {
|
|
|
|
+ printf( "0x" );
|
|
|
|
+ for ( i = 0; i < plv->len; ++i )
|
|
|
|
+ {
|
|
|
|
+ printf( "%02x", ((unsigned int)(plv->val[ i ])) );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif /* DEBUG_MODE */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfInfoInit
|
|
|
|
+ * Description: Initialize the xsvfInfo data.
|
|
|
|
+ * Parameters: pXsvfInfo - ptr to the XSVF info structure.
|
|
|
|
+ * Returns: int - 0 = success; otherwise error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfInfoInit( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ XSVFDBG_PRINTF1( 4, " sizeof( SXsvfInfo ) = %d bytes\n",
|
|
|
|
+ sizeof( SXsvfInfo ) );
|
|
|
|
+
|
|
|
|
+ pXsvfInfo->ucComplete = 0;
|
|
|
|
+ pXsvfInfo->ucCommand = XCOMPLETE;
|
|
|
|
+ pXsvfInfo->lCommandCount = 0;
|
|
|
|
+ pXsvfInfo->iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+ pXsvfInfo->ucMaxRepeat = 0;
|
|
|
|
+ pXsvfInfo->ucTapState = XTAPSTATE_RESET;
|
|
|
|
+ pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST;
|
|
|
|
+ pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST;
|
|
|
|
+ pXsvfInfo->lShiftLengthBits = 0L;
|
|
|
|
+ pXsvfInfo->sShiftLengthBytes= 0;
|
|
|
|
+ pXsvfInfo->lRunTestTime = 0L;
|
|
|
|
+
|
|
|
|
+ return( 0 );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfInfoCleanup
|
|
|
|
+ * Description: Cleanup the xsvfInfo data.
|
|
|
|
+ * Parameters: pXsvfInfo - ptr to the XSVF info structure.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfGetAsNumBytes
|
|
|
|
+ * Description: Calculate the number of bytes the given number of bits
|
|
|
|
+ * consumes.
|
|
|
|
+ * Parameters: lNumBits - the number of bits.
|
|
|
|
+ * Returns: short - the number of bytes to store the number of bits.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+short xsvfGetAsNumBytes( long lNumBits )
|
|
|
|
+{
|
|
|
|
+ return( (short)( ( lNumBits + 7L ) / 8L ) );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfTmsTransition
|
|
|
|
+ * Description: Apply TMS and transition TAP controller by applying one TCK
|
|
|
|
+ * cycle.
|
|
|
|
+ * Parameters: sTms - new TMS value.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+void xsvfTmsTransition( short sTms )
|
|
|
|
+{
|
|
|
|
+ setPort( TMS, sTms );
|
|
|
|
+ setPort( TCK, 0 );
|
|
|
|
+ setPort( TCK, 1 );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfGotoTapState
|
|
|
|
+ * Description: From the current TAP state, go to the named TAP state.
|
|
|
|
+ * A target state of RESET ALWAYS causes TMS reset sequence.
|
|
|
|
+ * All SVF standard stable state paths are supported.
|
|
|
|
+ * All state transitions are supported except for the following
|
|
|
|
+ * which cause an XSVF_ERROR_ILLEGALSTATE:
|
|
|
|
+ * - Target==DREXIT2; Start!=DRPAUSE
|
|
|
|
+ * - Target==IREXIT2; Start!=IRPAUSE
|
|
|
|
+ * Parameters: pucTapState - Current TAP state; returns final TAP state.
|
|
|
|
+ * ucTargetState - New target TAP state.
|
|
|
|
+ * Returns: int - 0 = success; otherwise error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfGotoTapState( unsigned char* pucTapState,
|
|
|
|
+ unsigned char ucTargetState )
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+
|
|
|
|
+ iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_RESET )
|
|
|
|
+ {
|
|
|
|
+ /* If RESET, always perform TMS reset sequence to reset/sync TAPs */
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ for ( i = 0; i < 5; ++i )
|
|
|
|
+ {
|
|
|
|
+ setPort( TCK, 0 );
|
|
|
|
+ setPort( TCK, 1 );
|
|
|
|
+ }
|
|
|
|
+ *pucTapState = XTAPSTATE_RESET;
|
|
|
|
+ XSVFDBG_PRINTF( 3, " TMS Reset Sequence -> Test-Logic-Reset\n" );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ *pucTapState ] );
|
|
|
|
+ } else if ( ( ucTargetState != *pucTapState ) &&
|
|
|
|
+ ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) ||
|
|
|
|
+ ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) )
|
|
|
|
+ {
|
|
|
|
+ /* Trap illegal TAP state path specification */
|
|
|
|
+ iErrorCode = XSVF_ERROR_ILLEGALSTATE;
|
|
|
|
+ } else {
|
|
|
|
+ if ( ucTargetState == *pucTapState )
|
|
|
|
+ {
|
|
|
|
+ /* Already in target state. Do nothing except when in DRPAUSE
|
|
|
|
+ or in IRPAUSE to comply with SVF standard */
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_PAUSEDR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT2DR;
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ *pucTapState ] );
|
|
|
|
+ }
|
|
|
|
+ else if ( ucTargetState == XTAPSTATE_PAUSEIR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT2IR;
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ *pucTapState ] );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Perform TAP state transitions to get to the target state */
|
|
|
|
+ while ( ucTargetState != *pucTapState )
|
|
|
|
+ {
|
|
|
|
+ switch ( *pucTapState )
|
|
|
|
+ {
|
|
|
|
+ case XTAPSTATE_RESET:
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_RUNTEST;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_RUNTEST:
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SELECTDR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_SELECTDR:
|
|
|
|
+ if ( ucTargetState >= XTAPSTATE_IRSTATES )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SELECTIR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_CAPTUREDR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_CAPTUREDR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_SHIFTDR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SHIFTDR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT1DR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_SHIFTDR:
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT1DR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_EXIT1DR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_PAUSEDR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_PAUSEDR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_UPDATEDR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_PAUSEDR:
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT2DR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_EXIT2DR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_SHIFTDR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SHIFTDR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_UPDATEDR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_UPDATEDR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_RUNTEST )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_RUNTEST;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SELECTDR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_SELECTIR:
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_CAPTUREIR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_CAPTUREIR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_SHIFTIR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SHIFTIR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT1IR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_SHIFTIR:
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT1IR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_EXIT1IR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_PAUSEIR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_PAUSEIR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_UPDATEIR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_PAUSEIR:
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_EXIT2IR;
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_EXIT2IR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_SHIFTIR )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SHIFTIR;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_UPDATEIR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case XTAPSTATE_UPDATEIR:
|
|
|
|
+ if ( ucTargetState == XTAPSTATE_RUNTEST )
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 0 );
|
|
|
|
+ *pucTapState = XTAPSTATE_RUNTEST;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ xsvfTmsTransition( 1 );
|
|
|
|
+ *pucTapState = XTAPSTATE_SELECTDR;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ iErrorCode = XSVF_ERROR_ILLEGALSTATE;
|
|
|
|
+ *pucTapState = ucTargetState; /* Exit while loop */
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ *pucTapState ] );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfShiftOnly
|
|
|
|
+ * Description: Assumes that starting TAP state is SHIFT-DR or SHIFT-IR.
|
|
|
|
+ * Shift the given TDI data into the JTAG scan chain.
|
|
|
|
+ * Optionally, save the TDO data shifted out of the scan chain.
|
|
|
|
+ * Last shift cycle is special: capture last TDO, set last TDI,
|
|
|
|
+ * but does not pulse TCK. Caller must pulse TCK and optionally
|
|
|
|
+ * set TMS=1 to exit shift state.
|
|
|
|
+ * Parameters: lNumBits - number of bits to shift.
|
|
|
|
+ * plvTdi - ptr to lenval for TDI data.
|
|
|
|
+ * plvTdoCaptured - ptr to lenval for storing captured TDO data.
|
|
|
|
+ * iExitShift - 1=exit at end of shift; 0=stay in Shift-DR.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+void xsvfShiftOnly( long lNumBits,
|
|
|
|
+ lenVal* plvTdi,
|
|
|
|
+ lenVal* plvTdoCaptured,
|
|
|
|
+ int iExitShift )
|
|
|
|
+{
|
|
|
|
+ unsigned char* pucTdi;
|
|
|
|
+ unsigned char* pucTdo;
|
|
|
|
+ unsigned char ucTdiByte;
|
|
|
|
+ unsigned char ucTdoByte;
|
|
|
|
+ unsigned char ucTdoBit;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */
|
|
|
|
+
|
|
|
|
+ /* Initialize TDO storage len == TDI len */
|
|
|
|
+ pucTdo = 0;
|
|
|
|
+ if ( plvTdoCaptured )
|
|
|
|
+ {
|
|
|
|
+ plvTdoCaptured->len = plvTdi->len;
|
|
|
|
+ pucTdo = plvTdoCaptured->val + plvTdi->len;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Shift LSB first. val[N-1] == LSB. val[0] == MSB. */
|
|
|
|
+ pucTdi = plvTdi->val + plvTdi->len;
|
|
|
|
+ while ( lNumBits )
|
|
|
|
+ {
|
|
|
|
+ /* Process on a byte-basis */
|
|
|
|
+ ucTdiByte = (*(--pucTdi));
|
|
|
|
+ ucTdoByte = 0;
|
|
|
|
+ for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i )
|
|
|
|
+ {
|
|
|
|
+ --lNumBits;
|
|
|
|
+ if ( iExitShift && !lNumBits )
|
|
|
|
+ {
|
|
|
|
+ /* Exit Shift-DR state */
|
|
|
|
+ setPort( TMS, 1 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Set the new TDI value */
|
|
|
|
+ setPort( TDI, (short)(ucTdiByte & 1) );
|
|
|
|
+ ucTdiByte >>= 1;
|
|
|
|
+
|
|
|
|
+ /* Set TCK low */
|
|
|
|
+ setPort( TCK, 0 );
|
|
|
|
+
|
|
|
|
+ if ( pucTdo )
|
|
|
|
+ {
|
|
|
|
+ /* Save the TDO value */
|
|
|
|
+ ucTdoBit = readTDOBit();
|
|
|
|
+ ucTdoByte |= ( ucTdoBit << i );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Set TCK high */
|
|
|
|
+ setPort( TCK, 1 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Save the TDO byte value */
|
|
|
|
+ if ( pucTdo )
|
|
|
|
+ {
|
|
|
|
+ (*(--pucTdo)) = ucTdoByte;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfShift
|
|
|
|
+ * Description: Goes to the given starting TAP state.
|
|
|
|
+ * Calls xsvfShiftOnly to shift in the given TDI data and
|
|
|
|
+ * optionally capture the TDO data.
|
|
|
|
+ * Compares the TDO captured data against the TDO expected
|
|
|
|
+ * data.
|
|
|
|
+ * If a data mismatch occurs, then executes the exception
|
|
|
|
+ * handling loop upto ucMaxRepeat times.
|
|
|
|
+ * Parameters: pucTapState - Ptr to current TAP state.
|
|
|
|
+ * ucStartState - Starting shift state: Shift-DR or Shift-IR.
|
|
|
|
+ * lNumBits - number of bits to shift.
|
|
|
|
+ * plvTdi - ptr to lenval for TDI data.
|
|
|
|
+ * plvTdoCaptured - ptr to lenval for storing TDO data.
|
|
|
|
+ * plvTdoExpected - ptr to expected TDO data.
|
|
|
|
+ * plvTdoMask - ptr to TDO mask.
|
|
|
|
+ * ucEndState - state in which to end the shift.
|
|
|
|
+ * lRunTestTime - amount of time to wait after the shift.
|
|
|
|
+ * ucMaxRepeat - Maximum number of retries on TDO mismatch.
|
|
|
|
+ * Returns: int - 0 = success; otherwise TDO mismatch.
|
|
|
|
+ * Notes: XC9500XL-only Optimization:
|
|
|
|
+ * Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1]
|
|
|
|
+ * is NOT all zeros and sMatch==1.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfShift( unsigned char* pucTapState,
|
|
|
|
+ unsigned char ucStartState,
|
|
|
|
+ long lNumBits,
|
|
|
|
+ lenVal* plvTdi,
|
|
|
|
+ lenVal* plvTdoCaptured,
|
|
|
|
+ lenVal* plvTdoExpected,
|
|
|
|
+ lenVal* plvTdoMask,
|
|
|
|
+ unsigned char ucEndState,
|
|
|
|
+ long lRunTestTime,
|
|
|
|
+ unsigned char ucMaxRepeat )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ int iMismatch;
|
|
|
|
+ unsigned char ucRepeat;
|
|
|
|
+ int iExitShift;
|
|
|
|
+
|
|
|
|
+ iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+ iMismatch = 0;
|
|
|
|
+ ucRepeat = 0;
|
|
|
|
+ iExitShift = ( ucStartState != ucEndState );
|
|
|
|
+
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " Shift Length = %ld\n", lNumBits );
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDI = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, plvTdi );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDO Expected = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+
|
|
|
|
+ if ( !lNumBits )
|
|
|
|
+ {
|
|
|
|
+ /* Compatibility with XSVF2.00: XSDR 0 = no shift, but wait in RTI */
|
|
|
|
+ if ( lRunTestTime )
|
|
|
|
+ {
|
|
|
|
+ /* Wait for prespecified XRUNTEST time */
|
|
|
|
+ xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
|
|
|
|
+ waitTime( lRunTestTime );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ /* Goto Shift-DR or Shift-IR */
|
|
|
|
+ xsvfGotoTapState( pucTapState, ucStartState );
|
|
|
|
+
|
|
|
|
+ /* Shift TDI and capture TDO */
|
|
|
|
+ xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift );
|
|
|
|
+
|
|
|
|
+ if ( plvTdoExpected )
|
|
|
|
+ {
|
|
|
|
+ /* Compare TDO data to expected TDO data */
|
|
|
|
+ iMismatch = !EqualLenVal( plvTdoExpected,
|
|
|
|
+ plvTdoCaptured,
|
|
|
|
+ plvTdoMask );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( iExitShift )
|
|
|
|
+ {
|
|
|
|
+ /* Update TAP state: Shift->Exit */
|
|
|
|
+ ++(*pucTapState);
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " TAP State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ *pucTapState ] );
|
|
|
|
+
|
|
|
|
+ if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) )
|
|
|
|
+ {
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDO Expected = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDO Captured = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDO Mask = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, plvTdoMask );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " Retry #%d\n", ( ucRepeat + 1 ) );
|
|
|
|
+ /* Do exception handling retry - ShiftDR only */
|
|
|
|
+ xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR );
|
|
|
|
+ /* Shift 1 extra bit */
|
|
|
|
+ xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR );
|
|
|
|
+ /* Increment RUNTEST time by an additional 25% */
|
|
|
|
+ lRunTestTime += ( lRunTestTime >> 2 );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* Do normal exit from Shift-XR */
|
|
|
|
+ xsvfGotoTapState( pucTapState, ucEndState );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( lRunTestTime )
|
|
|
|
+ {
|
|
|
|
+ /* Wait for prespecified XRUNTEST time */
|
|
|
|
+ xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " Wait = %ld usec\n", lRunTestTime );
|
|
|
|
+ waitTime( lRunTestTime );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( iMismatch )
|
|
|
|
+ {
|
|
|
|
+ XSVFDBG_PRINTF( 1, " TDO Expected = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 1, plvTdoExpected );
|
|
|
|
+ XSVFDBG_PRINTF( 1, "\n");
|
|
|
|
+ XSVFDBG_PRINTF( 1, " TDO Captured = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured );
|
|
|
|
+ XSVFDBG_PRINTF( 1, "\n");
|
|
|
|
+ XSVFDBG_PRINTF( 1, " TDO Mask = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 1, plvTdoMask );
|
|
|
|
+ XSVFDBG_PRINTF( 1, "\n");
|
|
|
|
+ if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) )
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_MAXRETRIES;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_TDOMISMATCH;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfBasicXSDRTDO
|
|
|
|
+ * Description: Get the XSDRTDO parameters and execute the XSDRTDO command.
|
|
|
|
+ * This is the common function for all XSDRTDO commands.
|
|
|
|
+ * Parameters: pucTapState - Current TAP state.
|
|
|
|
+ * lShiftLengthBits - number of bits to shift.
|
|
|
|
+ * sShiftLengthBytes - number of bytes to read.
|
|
|
|
+ * plvTdi - ptr to lenval for TDI data.
|
|
|
|
+ * lvTdoCaptured - ptr to lenval for storing TDO data.
|
|
|
|
+ * iEndState - state in which to end the shift.
|
|
|
|
+ * lRunTestTime - amount of time to wait after the shift.
|
|
|
|
+ * ucMaxRepeat - maximum xc9500/xl retries.
|
|
|
|
+ * Returns: int - 0 = success; otherwise TDO mismatch.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfBasicXSDRTDO( unsigned char* pucTapState,
|
|
|
|
+ long lShiftLengthBits,
|
|
|
|
+ short sShiftLengthBytes,
|
|
|
|
+ lenVal* plvTdi,
|
|
|
|
+ lenVal* plvTdoCaptured,
|
|
|
|
+ lenVal* plvTdoExpected,
|
|
|
|
+ lenVal* plvTdoMask,
|
|
|
|
+ unsigned char ucEndState,
|
|
|
|
+ long lRunTestTime,
|
|
|
|
+ unsigned char ucMaxRepeat )
|
|
|
|
+{
|
|
|
|
+ readVal( plvTdi, sShiftLengthBytes );
|
|
|
|
+ if ( plvTdoExpected )
|
|
|
|
+ {
|
|
|
|
+ readVal( plvTdoExpected, sShiftLengthBytes );
|
|
|
|
+ }
|
|
|
|
+ return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
|
|
|
|
+ plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask,
|
|
|
|
+ ucEndState, lRunTestTime, ucMaxRepeat ) );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoSDRMasking
|
|
|
|
+ * Description: Update the data value with the next XSDRINC data and address.
|
|
|
|
+ * Example: dataVal=0x01ff, nextData=0xab, addressMask=0x0100,
|
|
|
|
+ * dataMask=0x00ff, should set dataVal to 0x02ab
|
|
|
|
+ * Parameters: plvTdi - The current TDI value.
|
|
|
|
+ * plvNextData - the next data value.
|
|
|
|
+ * plvAddressMask - the address mask.
|
|
|
|
+ * plvDataMask - the data mask.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+void xsvfDoSDRMasking( lenVal* plvTdi,
|
|
|
|
+ lenVal* plvNextData,
|
|
|
|
+ lenVal* plvAddressMask,
|
|
|
|
+ lenVal* plvDataMask )
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ unsigned char ucTdi;
|
|
|
|
+ unsigned char ucTdiMask;
|
|
|
|
+ unsigned char ucDataMask;
|
|
|
|
+ unsigned char ucNextData;
|
|
|
|
+ unsigned char ucNextMask;
|
|
|
|
+ short sNextData;
|
|
|
|
+
|
|
|
|
+ /* add the address Mask to dataVal and return as a new dataVal */
|
|
|
|
+ addVal( plvTdi, plvTdi, plvAddressMask );
|
|
|
|
+
|
|
|
|
+ ucNextData = 0;
|
|
|
|
+ ucNextMask = 0;
|
|
|
|
+ sNextData = plvNextData->len;
|
|
|
|
+ for ( i = plvDataMask->len - 1; i >= 0; --i )
|
|
|
|
+ {
|
|
|
|
+ /* Go through data mask in reverse order looking for mask (1) bits */
|
|
|
|
+ ucDataMask = plvDataMask->val[ i ];
|
|
|
|
+ if ( ucDataMask )
|
|
|
|
+ {
|
|
|
|
+ /* Retrieve the corresponding TDI byte value */
|
|
|
|
+ ucTdi = plvTdi->val[ i ];
|
|
|
|
+
|
|
|
|
+ /* For each bit in the data mask byte, look for 1's */
|
|
|
|
+ ucTdiMask = 1;
|
|
|
|
+ while ( ucDataMask )
|
|
|
|
+ {
|
|
|
|
+ if ( ucDataMask & 1 )
|
|
|
|
+ {
|
|
|
|
+ if ( !ucNextMask )
|
|
|
|
+ {
|
|
|
|
+ /* Get the next data byte */
|
|
|
|
+ ucNextData = plvNextData->val[ --sNextData ];
|
|
|
|
+ ucNextMask = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Set or clear the data bit according to the next data */
|
|
|
|
+ if ( ucNextData & ucNextMask )
|
|
|
|
+ {
|
|
|
|
+ ucTdi |= ucTdiMask; /* Set bit */
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ucTdi &= ( ~ucTdiMask ); /* Clear bit */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Update the next data */
|
|
|
|
+ ucNextMask <<= 1;
|
|
|
|
+ }
|
|
|
|
+ ucTdiMask <<= 1;
|
|
|
|
+ ucDataMask >>= 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Update the TDI value */
|
|
|
|
+ plvTdi->val[ i ] = ucTdi;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * XSVF Command Functions (type = TXsvfDoCmdFuncPtr)
|
|
|
|
+ * These functions update pXsvfInfo->iErrorCode only on an error.
|
|
|
|
+ * Otherwise, the error code is left alone.
|
|
|
|
+ * The function returns the error code from the function.
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoIllegalCmd
|
|
|
|
+ * Description: Function place holder for illegal/unsupported commands.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ XSVFDBG_PRINTF2( 0, "ERROR: Encountered unsupported command #%d (%s)\n",
|
|
|
|
+ ((unsigned int)(pXsvfInfo->ucCommand)),
|
|
|
|
+ ((pXsvfInfo->ucCommand < XLASTCMD)
|
|
|
|
+ ? (xsvf_pzCommandName[pXsvfInfo->ucCommand])
|
|
|
|
+ : "Unknown") );
|
|
|
|
+ pXsvfInfo->iErrorCode = XSVF_ERROR_ILLEGALCMD;
|
|
|
|
+ return( pXsvfInfo->iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXCOMPLETE
|
|
|
|
+ * Description: XCOMPLETE (no parameters)
|
|
|
|
+ * Update complete status for XSVF player.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ pXsvfInfo->ucComplete = 1;
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXTDOMASK
|
|
|
|
+ * Description: XTDOMASK <lenVal.TdoMask[XSDRSIZE]>
|
|
|
|
+ * Prespecify the TDO compare mask.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes );
|
|
|
|
+ XSVFDBG_PRINTF( 4, " TDO Mask = ");
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n");
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSIR
|
|
|
|
+ * Description: XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]>
|
|
|
|
+ * Get the instruction and shift the instruction into the TAP.
|
|
|
|
+ * If prespecified XRUNTEST!=0, goto RUNTEST and wait after
|
|
|
|
+ * the shift for XRUNTEST usec.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ unsigned char ucShiftIrBits;
|
|
|
|
+ short sShiftIrBytes;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+
|
|
|
|
+ /* Get the shift length and store */
|
|
|
|
+ readByte( &ucShiftIrBits );
|
|
|
|
+ sShiftIrBytes = xsvfGetAsNumBytes( ucShiftIrBits );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " XSIR length = %d\n",
|
|
|
|
+ ((unsigned int)ucShiftIrBits) );
|
|
|
|
+
|
|
|
|
+ if ( sShiftIrBytes > MAX_LEN )
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_DATAOVERFLOW;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* Get and store instruction to shift in */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) );
|
|
|
|
+
|
|
|
|
+ /* Shift the data */
|
|
|
|
+ iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
|
|
|
|
+ ucShiftIrBits, &(pXsvfInfo->lvTdi),
|
|
|
|
+ /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
|
|
|
|
+ /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
|
|
|
|
+ pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSIR2
|
|
|
|
+ * Description: XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]>
|
|
|
|
+ * Get the instruction and shift the instruction into the TAP.
|
|
|
|
+ * If prespecified XRUNTEST!=0, goto RUNTEST and wait after
|
|
|
|
+ * the shift for XRUNTEST usec.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ long lShiftIrBits;
|
|
|
|
+ short sShiftIrBytes;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+
|
|
|
|
+ /* Get the shift length and store */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 2 );
|
|
|
|
+ lShiftIrBits = value( &(pXsvfInfo->lvTdi) );
|
|
|
|
+ sShiftIrBytes = xsvfGetAsNumBytes( lShiftIrBits );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " XSIR2 length = %d\n", (int)lShiftIrBits);
|
|
|
|
+
|
|
|
|
+ if ( sShiftIrBytes > MAX_LEN )
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_DATAOVERFLOW;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* Get and store instruction to shift in */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) );
|
|
|
|
+
|
|
|
|
+ /* Shift the data */
|
|
|
|
+ iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
|
|
|
|
+ lShiftIrBits, &(pXsvfInfo->lvTdi),
|
|
|
|
+ /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
|
|
|
|
+ /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
|
|
|
|
+ pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDR
|
|
|
|
+ * Description: XSDR <lenVal.TDI[XSDRSIZE]>
|
|
|
|
+ * Shift the given TDI data into the JTAG scan chain.
|
|
|
|
+ * Compare the captured TDO with the expected TDO from the
|
|
|
|
+ * previous XSDRTDO command using the previously specified
|
|
|
|
+ * XTDOMASK.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
|
|
|
|
+ /* use TDOExpected from last XSDRTDO instruction */
|
|
|
|
+ iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
|
|
|
|
+ pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi),
|
|
|
|
+ &(pXsvfInfo->lvTdoCaptured),
|
|
|
|
+ &(pXsvfInfo->lvTdoExpected),
|
|
|
|
+ &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
|
|
|
|
+ pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXRUNTEST
|
|
|
|
+ * Description: XRUNTEST <uint32>
|
|
|
|
+ * Prespecify the XRUNTEST wait time for shift operations.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 4 );
|
|
|
|
+ pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime );
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXREPEAT
|
|
|
|
+ * Description: XREPEAT <byte>
|
|
|
|
+ * Prespecify the maximum number of XC9500/XL retries.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ readByte( &(pXsvfInfo->ucMaxRepeat) );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " XREPEAT = %d\n",
|
|
|
|
+ ((unsigned int)(pXsvfInfo->ucMaxRepeat)) );
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDRSIZE
|
|
|
|
+ * Description: XSDRSIZE <uint32>
|
|
|
|
+ * Prespecify the XRUNTEST wait time for shift operations.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 4 );
|
|
|
|
+ pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) );
|
|
|
|
+ pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits );
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits );
|
|
|
|
+ if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN )
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_DATAOVERFLOW;
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDRTDO
|
|
|
|
+ * Description: XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
|
|
|
|
+ * Get the TDI and expected TDO values. Then, shift.
|
|
|
|
+ * Compare the expected TDO with the captured TDO using the
|
|
|
|
+ * prespecified XTDOMASK.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
|
|
|
|
+ pXsvfInfo->lShiftLengthBits,
|
|
|
|
+ pXsvfInfo->sShiftLengthBytes,
|
|
|
|
+ &(pXsvfInfo->lvTdi),
|
|
|
|
+ &(pXsvfInfo->lvTdoCaptured),
|
|
|
|
+ &(pXsvfInfo->lvTdoExpected),
|
|
|
|
+ &(pXsvfInfo->lvTdoMask),
|
|
|
|
+ pXsvfInfo->ucEndDR,
|
|
|
|
+ pXsvfInfo->lRunTestTime,
|
|
|
|
+ pXsvfInfo->ucMaxRepeat );
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSETSDRMASKS
|
|
|
|
+ * Description: XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]>
|
|
|
|
+ * <lenVal.DataMask[XSDRSIZE]>
|
|
|
|
+ * Get the prespecified address and data mask for the XSDRINC
|
|
|
|
+ * command.
|
|
|
|
+ * Used for xc9500/xl compressed XSVF data.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ /* read the addressMask */
|
|
|
|
+ readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes );
|
|
|
|
+ /* read the dataMask */
|
|
|
|
+ readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes );
|
|
|
|
+
|
|
|
|
+ XSVFDBG_PRINTF( 4, " Address Mask = " );
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n" );
|
|
|
|
+ XSVFDBG_PRINTF( 4, " Data Mask = " );
|
|
|
|
+ XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) );
|
|
|
|
+ XSVFDBG_PRINTF( 4, "\n" );
|
|
|
|
+
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDRINC
|
|
|
|
+ * Description: XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)>
|
|
|
|
+ * <lenVal.data[XSETSDRMASKS.dataMask.len]> ...
|
|
|
|
+ * Get the XSDRINC parameters and execute the XSDRINC command.
|
|
|
|
+ * XSDRINC starts by loading the first TDI shift value.
|
|
|
|
+ * Then, for numTimes, XSDRINC gets the next piece of data,
|
|
|
|
+ * replaces the bits from the starting TDI as defined by the
|
|
|
|
+ * XSETSDRMASKS.dataMask, adds the address mask from
|
|
|
|
+ * XSETSDRMASKS.addressMask, shifts the new TDI value,
|
|
|
|
+ * and compares the TDO to the expected TDO from the previous
|
|
|
|
+ * XSDRTDO command using the XTDOMASK.
|
|
|
|
+ * Used for xc9500/xl compressed XSVF data.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ int iDataMaskLen;
|
|
|
|
+ unsigned char ucDataMask;
|
|
|
|
+ unsigned char ucNumTimes;
|
|
|
|
+ unsigned char i;
|
|
|
|
+
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
|
|
|
|
+ iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
|
|
|
|
+ pXsvfInfo->lShiftLengthBits,
|
|
|
|
+ &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured),
|
|
|
|
+ &(pXsvfInfo->lvTdoExpected),
|
|
|
|
+ &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
|
|
|
|
+ pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
|
|
|
|
+ if ( !iErrorCode )
|
|
|
|
+ {
|
|
|
|
+ /* Calculate number of data mask bits */
|
|
|
|
+ iDataMaskLen = 0;
|
|
|
|
+ for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i )
|
|
|
|
+ {
|
|
|
|
+ ucDataMask = pXsvfInfo->lvDataMask.val[ i ];
|
|
|
|
+ while ( ucDataMask )
|
|
|
|
+ {
|
|
|
|
+ iDataMaskLen += ( ucDataMask & 1 );
|
|
|
|
+ ucDataMask >>= 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Get the number of data pieces, i.e. number of times to shift */
|
|
|
|
+ readByte( &ucNumTimes );
|
|
|
|
+
|
|
|
|
+ /* For numTimes, get data, fix TDI, and shift */
|
|
|
|
+ for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i )
|
|
|
|
+ {
|
|
|
|
+ readVal( &(pXsvfInfo->lvNextData),
|
|
|
|
+ xsvfGetAsNumBytes( iDataMaskLen ) );
|
|
|
|
+ xsvfDoSDRMasking( &(pXsvfInfo->lvTdi),
|
|
|
|
+ &(pXsvfInfo->lvNextData),
|
|
|
|
+ &(pXsvfInfo->lvAddressMask),
|
|
|
|
+ &(pXsvfInfo->lvDataMask) );
|
|
|
|
+ iErrorCode = xsvfShift( &(pXsvfInfo->ucTapState),
|
|
|
|
+ XTAPSTATE_SHIFTDR,
|
|
|
|
+ pXsvfInfo->lShiftLengthBits,
|
|
|
|
+ &(pXsvfInfo->lvTdi),
|
|
|
|
+ &(pXsvfInfo->lvTdoCaptured),
|
|
|
|
+ &(pXsvfInfo->lvTdoExpected),
|
|
|
|
+ &(pXsvfInfo->lvTdoMask),
|
|
|
|
+ pXsvfInfo->ucEndDR,
|
|
|
|
+ pXsvfInfo->lRunTestTime,
|
|
|
|
+ pXsvfInfo->ucMaxRepeat );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDRBCE
|
|
|
|
+ * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]>
|
|
|
|
+ * If not already in SHIFTDR, goto SHIFTDR.
|
|
|
|
+ * Shift the given TDI data into the JTAG scan chain.
|
|
|
|
+ * Ignore TDO.
|
|
|
|
+ * If cmd==XSDRE, then goto ENDDR. Otherwise, stay in ShiftDR.
|
|
|
|
+ * XSDRB, XSDRC, and XSDRE are the same implementation.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ unsigned char ucEndDR;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ?
|
|
|
|
+ pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
|
|
|
|
+ iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
|
|
|
|
+ pXsvfInfo->lShiftLengthBits,
|
|
|
|
+ pXsvfInfo->sShiftLengthBytes,
|
|
|
|
+ &(pXsvfInfo->lvTdi),
|
|
|
|
+ /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
|
|
|
|
+ /*plvTdoMask*/0, ucEndDR,
|
|
|
|
+ /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSDRTDOBCE
|
|
|
|
+ * Description: XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
|
|
|
|
+ * If not already in SHIFTDR, goto SHIFTDR.
|
|
|
|
+ * Shift the given TDI data into the JTAG scan chain.
|
|
|
|
+ * Compare TDO, but do NOT use XTDOMASK.
|
|
|
|
+ * If cmd==XSDRTDOE, then goto ENDDR. Otherwise, stay in ShiftDR.
|
|
|
|
+ * XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ unsigned char ucEndDR;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ?
|
|
|
|
+ pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
|
|
|
|
+ iErrorCode = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
|
|
|
|
+ pXsvfInfo->lShiftLengthBits,
|
|
|
|
+ pXsvfInfo->sShiftLengthBytes,
|
|
|
|
+ &(pXsvfInfo->lvTdi),
|
|
|
|
+ &(pXsvfInfo->lvTdoCaptured),
|
|
|
|
+ &(pXsvfInfo->lvTdoExpected),
|
|
|
|
+ /*plvTdoMask*/0, ucEndDR,
|
|
|
|
+ /*lRunTestTime*/0, /*ucMaxRepeat*/0 );
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXSTATE
|
|
|
|
+ * Description: XSTATE <byte>
|
|
|
|
+ * <byte> == XTAPSTATE;
|
|
|
|
+ * Get the state parameter and transition the TAP to that state.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ unsigned char ucNextState;
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ readByte( &ucNextState );
|
|
|
|
+ iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState );
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXENDXR
|
|
|
|
+ * Description: XENDIR/XENDDR <byte>
|
|
|
|
+ * <byte>: 0 = RUNTEST; 1 = PAUSE.
|
|
|
|
+ * Get the prespecified XENDIR or XENDDR.
|
|
|
|
+ * Both XENDIR and XENDDR use the same implementation.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ unsigned char ucEndState;
|
|
|
|
+
|
|
|
|
+ iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+ readByte( &ucEndState );
|
|
|
|
+ if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) )
|
|
|
|
+ {
|
|
|
|
+ iErrorCode = XSVF_ERROR_ILLEGALSTATE;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ if ( pXsvfInfo->ucCommand == XENDIR )
|
|
|
|
+ {
|
|
|
|
+ if ( ucEndState == XENDXR_RUNTEST )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->ucEndIR = XTAPSTATE_RUNTEST;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->ucEndIR = XTAPSTATE_PAUSEIR;
|
|
|
|
+ }
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " ENDIR State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ pXsvfInfo->ucEndIR ] );
|
|
|
|
+ }
|
|
|
|
+ else /* XENDDR */
|
|
|
|
+ {
|
|
|
|
+ if ( ucEndState == XENDXR_RUNTEST )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->ucEndDR = XTAPSTATE_RUNTEST;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->ucEndDR = XTAPSTATE_PAUSEDR;
|
|
|
|
+ }
|
|
|
|
+ XSVFDBG_PRINTF1( 3, " ENDDR State = %s\n",
|
|
|
|
+ xsvf_pzTapState[ pXsvfInfo->ucEndDR ] );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( iErrorCode != XSVF_ERROR_NONE )
|
|
|
|
+ {
|
|
|
|
+ pXsvfInfo->iErrorCode = iErrorCode;
|
|
|
|
+ }
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXCOMMENT
|
|
|
|
+ * Description: XCOMMENT <text string ending in \0>
|
|
|
|
+ * <text string ending in \0> == text comment;
|
|
|
|
+ * Arbitrary comment embedded in the XSVF.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ /* Use the comment for debugging */
|
|
|
|
+ /* Otherwise, read through the comment to the end '\0' and ignore */
|
|
|
|
+ unsigned char ucText;
|
|
|
|
+
|
|
|
|
+ if ( xsvf_iDebugLevel > 0 )
|
|
|
|
+ {
|
|
|
|
+ putc( ' ' );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ readByte( &ucText );
|
|
|
|
+ if ( xsvf_iDebugLevel > 0 )
|
|
|
|
+ {
|
|
|
|
+ putc( ucText ? ucText : '\n' );
|
|
|
|
+ }
|
|
|
|
+ } while ( ucText );
|
|
|
|
+
|
|
|
|
+ pXsvfInfo->iErrorCode = XSVF_ERROR_NONE;
|
|
|
|
+
|
|
|
|
+ return( pXsvfInfo->iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfDoXWAIT
|
|
|
|
+ * Description: XWAIT <wait_state> <end_state> <wait_time>
|
|
|
|
+ * If not already in <wait_state>, then go to <wait_state>.
|
|
|
|
+ * Wait in <wait_state> for <wait_time> microseconds.
|
|
|
|
+ * Finally, if not already in <end_state>, then goto <end_state>.
|
|
|
|
+ * Parameters: pXsvfInfo - XSVF information pointer.
|
|
|
|
+ * Returns: int - 0 = success; non-zero = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ unsigned char ucWaitState;
|
|
|
|
+ unsigned char ucEndState;
|
|
|
|
+ long lWaitTime;
|
|
|
|
+
|
|
|
|
+ /* Get Parameters */
|
|
|
|
+ /* <wait_state> */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 1 );
|
|
|
|
+ ucWaitState = pXsvfInfo->lvTdi.val[0];
|
|
|
|
+
|
|
|
|
+ /* <end_state> */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 1 );
|
|
|
|
+ ucEndState = pXsvfInfo->lvTdi.val[0];
|
|
|
|
+
|
|
|
|
+ /* <wait_time> */
|
|
|
|
+ readVal( &(pXsvfInfo->lvTdi), 4 );
|
|
|
|
+ lWaitTime = value( &(pXsvfInfo->lvTdi) );
|
|
|
|
+ XSVFDBG_PRINTF2( 3, " XWAIT: state = %s; time = %ld\n",
|
|
|
|
+ xsvf_pzTapState[ ucWaitState ], lWaitTime );
|
|
|
|
+
|
|
|
|
+ /* If not already in <wait_state>, go to <wait_state> */
|
|
|
|
+ if ( pXsvfInfo->ucTapState != ucWaitState )
|
|
|
|
+ {
|
|
|
|
+ xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Wait for <wait_time> microseconds */
|
|
|
|
+ waitTime( lWaitTime );
|
|
|
|
+
|
|
|
|
+ /* If not already in <end_state>, go to <end_state> */
|
|
|
|
+ if ( pXsvfInfo->ucTapState != ucEndState )
|
|
|
|
+ {
|
|
|
|
+ xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return( XSVF_ERROR_NONE );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * Execution Control Functions
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfInitialize
|
|
|
|
+ * Description: Initialize the xsvf player.
|
|
|
|
+ * Call this before running the player to initialize the data
|
|
|
|
+ * in the SXsvfInfo struct.
|
|
|
|
+ * xsvfCleanup is called to clean up the data in SXsvfInfo
|
|
|
|
+ * after the XSVF is played.
|
|
|
|
+ * Parameters: pXsvfInfo - ptr to the XSVF information.
|
|
|
|
+ * Returns: int - 0 = success; otherwise error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfInitialize( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ /* Initialize values */
|
|
|
|
+ pXsvfInfo->iErrorCode = xsvfInfoInit( pXsvfInfo );
|
|
|
|
+
|
|
|
|
+ if ( !pXsvfInfo->iErrorCode )
|
|
|
|
+ {
|
|
|
|
+ /* Initialize the TAPs */
|
|
|
|
+ pXsvfInfo->iErrorCode = xsvfGotoTapState( &(pXsvfInfo->ucTapState),
|
|
|
|
+ XTAPSTATE_RESET );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return( pXsvfInfo->iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfRun
|
|
|
|
+ * Description: Run the xsvf player for a single command and return.
|
|
|
|
+ * First, call xsvfInitialize.
|
|
|
|
+ * Then, repeatedly call this function until an error is detected
|
|
|
|
+ * or until the pXsvfInfo->ucComplete variable is non-zero.
|
|
|
|
+ * Finally, call xsvfCleanup to cleanup any remnants.
|
|
|
|
+ * Parameters: pXsvfInfo - ptr to the XSVF information.
|
|
|
|
+ * Returns: int - 0 = success; otherwise error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfRun( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ /* Process the XSVF commands */
|
|
|
|
+ if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) )
|
|
|
|
+ {
|
|
|
|
+ /* read 1 byte for the instruction */
|
|
|
|
+ readByte( &(pXsvfInfo->ucCommand) );
|
|
|
|
+ ++(pXsvfInfo->lCommandCount);
|
|
|
|
+
|
|
|
|
+ if ( pXsvfInfo->ucCommand < XLASTCMD )
|
|
|
|
+ {
|
|
|
|
+ /* Execute the command. Func sets error code. */
|
|
|
|
+ XSVFDBG_PRINTF1( 2, " %s\n",
|
|
|
|
+ xsvf_pzCommandName[pXsvfInfo->ucCommand] );
|
|
|
|
+ /* If your compiler cannot take this form,
|
|
|
|
+ then convert to a switch statement */
|
|
|
|
+#if 0 /* test-only */
|
|
|
|
+ xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo );
|
|
|
|
+#else
|
|
|
|
+ switch (pXsvfInfo->ucCommand) {
|
|
|
|
+ case 0:
|
|
|
|
+ xsvfDoXCOMPLETE(pXsvfInfo); /* 0 */
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ xsvfDoXTDOMASK(pXsvfInfo); /* 1 */
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ xsvfDoXSIR(pXsvfInfo); /* 2 */
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ xsvfDoXSDR(pXsvfInfo); /* 3 */
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ xsvfDoXRUNTEST(pXsvfInfo); /* 4 */
|
|
|
|
+ break;
|
|
|
|
+ case 5:
|
|
|
|
+ xsvfDoIllegalCmd(pXsvfInfo); /* 5 */
|
|
|
|
+ break;
|
|
|
|
+ case 6:
|
|
|
|
+ xsvfDoIllegalCmd(pXsvfInfo); /* 6 */
|
|
|
|
+ break;
|
|
|
|
+ case 7:
|
|
|
|
+ xsvfDoXREPEAT(pXsvfInfo); /* 7 */
|
|
|
|
+ break;
|
|
|
|
+ case 8:
|
|
|
|
+ xsvfDoXSDRSIZE(pXsvfInfo); /* 8 */
|
|
|
|
+ break;
|
|
|
|
+ case 9:
|
|
|
|
+ xsvfDoXSDRTDO(pXsvfInfo); /* 9 */
|
|
|
|
+ break;
|
|
|
|
+#ifdef XSVF_SUPPORT_COMPRESSION
|
|
|
|
+ case 10:
|
|
|
|
+ xsvfDoXSETSDRMASKS(pXsvfInfo); /* 10 */
|
|
|
|
+ break;
|
|
|
|
+ case 11:
|
|
|
|
+ xsvfDoXSDRINC(pXsvfInfo); /* 11 */
|
|
|
|
+ break;
|
|
|
|
+#else
|
|
|
|
+ case 10:
|
|
|
|
+ xsvfDoIllegalCmd(pXsvfInfo); /* 10 */
|
|
|
|
+ break;
|
|
|
|
+ case 11:
|
|
|
|
+ xsvfDoIllegalCmd(pXsvfInfo); /* 11 */
|
|
|
|
+ break;
|
|
|
|
+#endif /* XSVF_SUPPORT_COMPRESSION */
|
|
|
|
+ case 12:
|
|
|
|
+ xsvfDoXSDRBCE(pXsvfInfo); /* 12 */
|
|
|
|
+ break;
|
|
|
|
+ case 13:
|
|
|
|
+ xsvfDoXSDRBCE(pXsvfInfo); /* 13 */
|
|
|
|
+ break;
|
|
|
|
+ case 14:
|
|
|
|
+ xsvfDoXSDRBCE(pXsvfInfo); /* 14 */
|
|
|
|
+ break;
|
|
|
|
+ case 15:
|
|
|
|
+ xsvfDoXSDRTDOBCE(pXsvfInfo); /* 15 */
|
|
|
|
+ break;
|
|
|
|
+ case 16:
|
|
|
|
+ xsvfDoXSDRTDOBCE(pXsvfInfo); /* 16 */
|
|
|
|
+ break;
|
|
|
|
+ case 17:
|
|
|
|
+ xsvfDoXSDRTDOBCE(pXsvfInfo); /* 17 */
|
|
|
|
+ break;
|
|
|
|
+ case 18:
|
|
|
|
+ xsvfDoXSTATE(pXsvfInfo); /* 18 */
|
|
|
|
+ break;
|
|
|
|
+ case 19:
|
|
|
|
+ xsvfDoXENDXR(pXsvfInfo); /* 19 */
|
|
|
|
+ break;
|
|
|
|
+ case 20:
|
|
|
|
+ xsvfDoXENDXR(pXsvfInfo); /* 20 */
|
|
|
|
+ break;
|
|
|
|
+ case 21:
|
|
|
|
+ xsvfDoXSIR2(pXsvfInfo); /* 21 */
|
|
|
|
+ break;
|
|
|
|
+ case 22:
|
|
|
|
+ xsvfDoXCOMMENT(pXsvfInfo); /* 22 */
|
|
|
|
+ break;
|
|
|
|
+ case 23:
|
|
|
|
+ xsvfDoXWAIT(pXsvfInfo); /* 23 */
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* Illegal command value. Func sets error code. */
|
|
|
|
+ xsvfDoIllegalCmd( pXsvfInfo );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return( pXsvfInfo->iErrorCode );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfCleanup
|
|
|
|
+ * Description: cleanup remnants of the xsvf player.
|
|
|
|
+ * Parameters: pXsvfInfo - ptr to the XSVF information.
|
|
|
|
+ * Returns: void.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+void xsvfCleanup( SXsvfInfo* pXsvfInfo )
|
|
|
|
+{
|
|
|
|
+ xsvfInfoCleanup( pXsvfInfo );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*============================================================================
|
|
|
|
+ * xsvfExecute() - The primary entry point to the XSVF player
|
|
|
|
+ ============================================================================*/
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: xsvfExecute
|
|
|
|
+ * Description: Process, interpret, and apply the XSVF commands.
|
|
|
|
+ * See port.c:readByte for source of XSVF data.
|
|
|
|
+ * Parameters: none.
|
|
|
|
+ * Returns: int - Legacy result values: 1 == success; 0 == failed.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int xsvfExecute(void)
|
|
|
|
+{
|
|
|
|
+ SXsvfInfo xsvfInfo;
|
|
|
|
+
|
|
|
|
+ xsvfInitialize( &xsvfInfo );
|
|
|
|
+
|
|
|
|
+ while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) )
|
|
|
|
+ {
|
|
|
|
+ xsvfRun( &xsvfInfo );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( xsvfInfo.iErrorCode )
|
|
|
|
+ {
|
|
|
|
+ XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[
|
|
|
|
+ ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST )
|
|
|
|
+ ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] );
|
|
|
|
+ XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld. See line #%ld in the XSVF ASCII file.\n",
|
|
|
|
+ xsvfInfo.lCommandCount, xsvfInfo.lCommandCount );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ xsvfCleanup( &xsvfInfo );
|
|
|
|
+
|
|
|
|
+ return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*****************************************************************************
|
|
|
|
+ * Function: do_cpld
|
|
|
|
+ * Description: main function.
|
|
|
|
+ * Specified here for creating stand-alone debug executable.
|
|
|
|
+ * Embedded users should call xsvfExecute() directly.
|
|
|
|
+ * Parameters: iArgc - number of command-line arguments.
|
|
|
|
+ * ppzArgv - array of ptrs to strings (command-line arguments).
|
|
|
|
+ * Returns: int - Legacy return value: 1 = success; 0 = error.
|
|
|
|
+ *****************************************************************************/
|
|
|
|
+int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|
|
|
+{
|
|
|
|
+ int iErrorCode;
|
|
|
|
+ char* pzXsvfFileName;
|
|
|
|
+ unsigned long duration;
|
|
|
|
+ unsigned long long startClock, endClock;
|
|
|
|
+
|
|
|
|
+ iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE );
|
|
|
|
+ pzXsvfFileName = 0;
|
|
|
|
+ xsvf_iDebugLevel = 0;
|
|
|
|
+
|
|
|
|
+ printf("XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION);
|
|
|
|
+ printf("XSVF Filesize = %d bytes\n", filesize);
|
|
|
|
+
|
|
|
|
+ /* Initialize the I/O. SetPort initializes I/O on first call */
|
|
|
|
+ setPort( TMS, 1 );
|
|
|
|
+
|
|
|
|
+ /* Execute the XSVF in the file */
|
|
|
|
+ startClock = get_ticks();
|
|
|
|
+ iErrorCode = xsvfExecute();
|
|
|
|
+ endClock = get_ticks();
|
|
|
|
+ duration = (unsigned long)(endClock - startClock);
|
|
|
|
+ printf("\nExecution Time = %d seconds\n", (int)(duration/get_tbclk()));
|
|
|
|
+
|
|
|
|
+ return( iErrorCode );
|
|
|
|
+}
|
|
|
|
+U_BOOT_CMD(
|
|
|
|
+ cpld, 1, 1, do_cpld,
|
|
|
|
+ "cpld - Program onboard CPLD\n",
|
|
|
|
+ NULL
|
|
|
|
+ );
|