From 6b810edd7890fab8436b18a4efc6934aa5b5906b Mon Sep 17 00:00:00 2001 From: gstellenberg Date: Sun, 28 Jun 2009 22:33:02 -0500 Subject: [PATCH 1/2] Added pinprocfw, a utility to verify/update the P-ROC's firmware (FPGA image). --- CMakeLists.txt | 3 +- include/pinproc.h | 35 + src/PRDevice.cpp | 46 +- src/PRDevice.h | 6 + src/PRHardware.cpp | 38 + src/PRHardware.h | 33 +- src/pinproc.cpp | 28 + utils/pinprocfw/lenval.cpp | 190 ++++ utils/pinprocfw/lenval.h | 94 ++ utils/pinprocfw/pinprocfw.cpp | 1952 +++++++++++++++++++++++++++++++++ utils/pinprocfw/pinprocfw.h | 64 ++ utils/temp/micro.cpp | 1951 ++++++++++++++++++++++++++++++++ utils/temp/micro.h | 42 + utils/temp/ports.cpp | 127 +++ utils/temp/ports.h | 31 + 15 files changed, 4637 insertions(+), 3 deletions(-) create mode 100644 utils/pinprocfw/lenval.cpp create mode 100644 utils/pinprocfw/lenval.h create mode 100644 utils/pinprocfw/pinprocfw.cpp create mode 100644 utils/pinprocfw/pinprocfw.h create mode 100644 utils/temp/micro.cpp create mode 100644 utils/temp/micro.h create mode 100644 utils/temp/ports.cpp create mode 100644 utils/temp/ports.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 87eeeeb..e5f4b6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,5 +14,6 @@ set(FILES src/pinproc.cpp src/PRDevice.cpp src/PRHardware.cpp) add_library(pinproc ${FILES}) add_executable(pinproctest examples/pinproctest/pinproctest.cpp examples/pinproctest/drivers.cpp examples/pinproctest/dmd.cpp examples/pinproctest/switches.cpp) +add_executable(pinprocfw utils/pinprocfw/pinprocfw.cpp utils/pinprocfw/lenval.cpp) target_link_libraries(pinproctest pinproc usb ftdi yaml-cpp) - +target_link_libraries(pinprocfw pinproc usb ftdi) diff --git a/include/pinproc.h b/include/pinproc.h index fbbf097..1a8cc3d 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -387,6 +387,41 @@ PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots); /** @} */ // End of DMD + +// JTAG + +/** + * @defgroup jtag JTAG interface control + * @{ + */ + +typedef struct PRJTAGStatus { + bool_t commandComplete; + bool_t tdi; +} PRJTAGStatus; + +typedef struct PRJTAGOutputs { + bool_t tckMask; + bool_t tmsMask; + bool_t tdoMask; + bool_t tck; + bool_t tms; + bool_t tdo; +} PRJTAGOutputs; + +/** Force JTAG outputs (TCK, TDO, TMS) to specific values. Optionally toggle the clock when driving only TDO and/or TMS.*/ +PR_EXPORT PRResult PRJTAGDriveOutputs(PRHandle handle, PRJTAGOutputs * jtagOutputs, bool_t toggleClk); +/** Store data to be shifted out on TDO */ +PR_EXPORT PRResult PRJTAGWriteTDOMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData); +/** Shift stored TDO data onto the TDO pin, toggling TCK on every bit. */ +PR_EXPORT PRResult PRJTAGShiftTDOData(PRHandle handle, uint16_t numBits, bool_t dataBlockComplete); +/** Get the contents of the TDI memory. */ +PR_EXPORT PRResult PRJTAGReadTDIMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData); +/** Read the JTAG status register for the command complete bit and JTAG pin states. */ +PR_EXPORT PRResult PRJTAGGetStatus(PRHandle handle, PRJTAGStatus * status); + +/** @} */ // End of DMD + /** @cond */ PR_EXTERN_C_END /** @endcond */ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 84fbe0b..d73a3ef 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -623,7 +623,51 @@ PRResult PRDevice::DMDDraw(uint8_t * dots) //} } +PRResult PRDevice::PRJTAGDriveOutputs(PRJTAGOutputs * jtagOutputs, bool_t toggleClk) +{ + const int burstSize = 2; + uint32_t burst[burstSize]; + if (toggleClk) CreateJTAGLatchOutputsBurst( burst, jtagOutputs ); + else CreateJTAGForceOutputsBurst( burst, jtagOutputs ); + return WriteData(burst, burstSize); +} + +PRResult PRDevice::PRJTAGWriteTDOMemory(uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData) +{ + int32_t i; + const int maxBurstSize = 513; + uint32_t burst[maxBurstSize]; + + burst[0] = CreateBurstCommand(P_ROC_BUS_JTAG_SELECT, P_ROC_JTAG_TDO_MEMORY_BASE_ADDR + tableOffset, numWords); + for (i=0; icommandComplete = rdBuffer[0] >> P_ROC_JTAG_STATUS_DONE_SHIFT; + status->tdi = rdBuffer[0] >> P_ROC_JTAG_STATUS_TDI_SHIFT; +} ///////////////////////////////////////////////////////////////////////////////////////////// // Device I/O @@ -798,7 +842,7 @@ PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, in PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) { uint32_t rc; - uint8_t i; + uint32_t i; // Send out the request. rc = RequestData(moduleSelect, startingAddr, numReadWords); diff --git a/src/PRDevice.h b/src/PRDevice.h index 2e32363..ce6b105 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -73,6 +73,12 @@ public: PRResult DMDUpdateConfig(PRDMDConfig *dmdConfig); PRResult DMDDraw(uint8_t * dots); + PRResult PRJTAGDriveOutputs(PRJTAGOutputs * jtagOutputs, bool_t toggleClk); + PRResult PRJTAGWriteTDOMemory(uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData); + PRResult PRJTAGShiftTDOData(uint16_t numBits, bool_t dataBlockComplete); + PRResult PRJTAGReadTDIMemory(uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData); + PRResult PRJTAGGetStatus(PRJTAGStatus * status); + protected: // Device I/O diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index c698e7c..90da372 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -234,6 +234,44 @@ int32_t CreateDMDUpdateConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config) return kPRSuccess; } +int32_t CreateJTAGForceOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs) { + burst[0] = CreateBurstCommand (P_ROC_BUS_JTAG_SELECT, P_ROC_JTAG_COMMAND_REG_BASE_ADDR, 1 ); + burst[1] = 0; + burst[1] = 1 << P_ROC_JTAG_CMD_START_SHIFT | + 1 << P_ROC_JTAG_CMD_OE_SHIFT | + P_ROC_JTAG_CMD_SET_PORTS << P_ROC_JTAG_CMD_CMD_SHIFT | + jtagOutputs->tckMask << P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT | + jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | + jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | + jtagOutputs->tck << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TCK_SHIFT; + return kPRSuccess; + +} +int32_t CreateJTAGLatchOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs) { + burst[0] = CreateBurstCommand (P_ROC_BUS_JTAG_SELECT, P_ROC_JTAG_COMMAND_REG_BASE_ADDR, 1 ); + burst[1] = 0; + burst[1] = 1 << P_ROC_JTAG_CMD_START_SHIFT | + 1 << P_ROC_JTAG_CMD_OE_SHIFT | + P_ROC_JTAG_CMD_TRANSITION << P_ROC_JTAG_CMD_CMD_SHIFT | + jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | + jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | + jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TMS_SHIFT; + return kPRSuccess; + +} +int32_t CreateJTAGShiftTDODataBurst ( uint32_t * burst, uint16_t numBits, bool_t dataBlockComplete) { + burst[0] = CreateBurstCommand (P_ROC_BUS_JTAG_SELECT, P_ROC_JTAG_COMMAND_REG_BASE_ADDR, 1 ); + burst[1] = 0; + burst[1] = 1 << P_ROC_JTAG_CMD_START_SHIFT | + 1 << P_ROC_JTAG_CMD_OE_SHIFT | + P_ROC_JTAG_CMD_SHIFT << P_ROC_JTAG_CMD_CMD_SHIFT | + dataBlockComplete << P_ROC_JTAG_SHIFT_EXIT_SHIFT | + numBits << P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT; + return kPRSuccess; +} /** * This is where all FTDI driver-specific code should go. diff --git a/src/PRHardware.h b/src/PRHardware.h index 6329f20..7465e10 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -64,7 +64,7 @@ const uint32_t P_ROC_REG_ADDR_SHIFT = 0; const uint32_t P_ROC_MODULE_SELECT_SHIFT = 16; const uint32_t P_ROC_MANAGER_SELECT = 0; -const uint32_t P_ROC_BUS_MASTER_SELECT = 1; +const uint32_t P_ROC_BUS_JTAG_SELECT = 1; const uint32_t P_ROC_BUS_SWITCH_CTRL_SELECT = 2; const uint32_t P_ROC_BUS_DRIVER_CTRL_SELECT = 3; const uint32_t P_ROC_BUS_STATE_CHANGE_PROC_SELECT = 4; @@ -80,6 +80,33 @@ const uint32_t P_ROC_MANAGER_WATCHDOG_EXPIRED_SHIFT = 30; const uint32_t P_ROC_MANAGER_WATCHDOG_ENABLE_SHIFT = 14; const uint32_t P_ROC_MANAGER_WATCHDOG_RESET_TIME_SHIFT = 0; +const uint32_t P_ROC_JTAG_SHIFT_EXIT_SHIFT = 16; +const uint32_t P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT = 0; + +const uint32_t P_ROC_JTAG_CMD_CHANGE_STATE = 0; +const uint32_t P_ROC_JTAG_CMD_SHIFT = 1; +const uint32_t P_ROC_JTAG_CMD_TRANSITION = 2; +const uint32_t P_ROC_JTAG_CMD_SET_PORTS = 3; + +const uint32_t P_ROC_JTAG_CMD_START_SHIFT = 31; +const uint32_t P_ROC_JTAG_CMD_OE_SHIFT = 30; +const uint32_t P_ROC_JTAG_CMD_CMD_SHIFT = 24; + +const uint32_t P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT = 6; +const uint32_t P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT = 5; +const uint32_t P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT = 4; +const uint32_t P_ROC_JTAG_TRANSITION_TCK_SHIFT = 2; +const uint32_t P_ROC_JTAG_TRANSITION_TDO_SHIFT = 1; +const uint32_t P_ROC_JTAG_TRANSITION_TMS_SHIFT = 0; + +const uint32_t P_ROC_JTAG_STATUS_DONE_SHIFT = 31; +const uint32_t P_ROC_JTAG_STATUS_TDI_SHIFT = 16; + +const uint32_t P_ROC_JTAG_COMMAND_REG_BASE_ADDR = 0x0; +const uint32_t P_ROC_JTAG_STATUS_REG_BASE_ADDR = 0x1; +const uint32_t P_ROC_JTAG_TDO_MEMORY_BASE_ADDR = 0x400; +const uint32_t P_ROC_JTAG_TDI_MEMORY_BASE_ADDR = 0x800; + const uint32_t P_ROC_SWITCH_CTRL_STATE_BASE_ADDR = 4; const uint32_t P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR = 11; @@ -187,6 +214,10 @@ void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *event int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType); int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType); +int32_t CreateJTAGLatchOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs); +int32_t CreateJTAGForceOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs); +int32_t CreateJTAGShiftTDODataBurst ( uint32_t * burst, uint16_t numBits, bool_t dataBlockComplete); + PRResult PRHardwareOpen(); void PRHardwareClose(); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index d9191dc..3f82789 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -293,6 +293,8 @@ PR_EXPORT PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates return handleAsDevice->SwitchGetStates(switchStates, numSwitches); } +// DMD + PR_EXPORT int32_t PRDMDUpdateConfig(PRHandle handle, PRDMDConfig *dmdConfig) { return handleAsDevice->DMDUpdateConfig(dmdConfig); @@ -302,3 +304,29 @@ PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots) return handleAsDevice->DMDDraw(dots); } +// JTAG + +PR_EXPORT PRResult PRJTAGDriveOutputs(PRHandle handle, PRJTAGOutputs * jtagOutputs, bool_t toggleClk) +{ + return handleAsDevice->PRJTAGDriveOutputs(jtagOutputs, toggleClk); +} + +PR_EXPORT PRResult PRJTAGWriteTDOMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData) +{ + return handleAsDevice->PRJTAGWriteTDOMemory(tableOffset, numWords, tdoData); +} + +PR_EXPORT PRResult PRJTAGShiftTDOData(PRHandle handle, uint16_t numBits, bool_t dataBlockComplete) +{ + return handleAsDevice->PRJTAGShiftTDOData(numBits, dataBlockComplete); +} + +PR_EXPORT PRResult PRJTAGReadTDIMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData) +{ + return handleAsDevice->PRJTAGReadTDIMemory(tableOffset, numWords, tdiData); +} + +PR_EXPORT PRResult PRJTAGGetStatus(PRHandle handle, PRJTAGStatus * status) +{ + return handleAsDevice->PRJTAGGetStatus(status); +} diff --git a/utils/pinprocfw/lenval.cpp b/utils/pinprocfw/lenval.cpp new file mode 100644 index 0000000..87d378f --- /dev/null +++ b/utils/pinprocfw/lenval.cpp @@ -0,0 +1,190 @@ +/*******************************************************/ +/* file: lenval.c */ +/* abstract: This file contains routines for using */ +/* the lenVal data structure. */ +/*******************************************************/ +#include "lenval.h" +#include "pinprocfw.h" + +/***************************************************************************** +* Function: value +* Description: Extract the long value from the lenval array. +* Parameters: plvValue - ptr to lenval. +* Returns: long - the extracted value. +*****************************************************************************/ +long value( lenVal* plvValue ) +{ + long lValue; /* result to hold the accumulated result */ + short sIndex; + + lValue = 0; + for ( sIndex = 0; sIndex < plvValue->len ; ++sIndex ) + { + lValue <<= 8; /* shift the accumulated result */ + lValue |= plvValue->val[ sIndex]; /* get the last byte first */ + } + + return( lValue ); +} + +/***************************************************************************** +* Function: initLenVal +* Description: Initialize the lenval array with the given value. +* Assumes lValue is less than 256. +* Parameters: plv - ptr to lenval. +* lValue - the value to set. +* Returns: void. +*****************************************************************************/ +void initLenVal( lenVal* plv, + long lValue ) +{ + plv->len = 1; + plv->val[0] = (unsigned char)lValue; +} + +/***************************************************************************** +* Function: EqualLenVal +* Description: Compare two lenval arrays with an optional mask. +* Parameters: plvTdoExpected - ptr to lenval #1. +* plvTdoCaptured - ptr to lenval #2. +* plvTdoMask - optional ptr to mask (=0 if no mask). +* Returns: short - 0 = mismatch; 1 = equal. +*****************************************************************************/ +short EqualLenVal( lenVal* plvTdoExpected, + lenVal* plvTdoCaptured, + lenVal* plvTdoMask ) +{ + short sEqual; + short sIndex; + unsigned char ucByteVal1; + unsigned char ucByteVal2; + unsigned char ucByteMask; + + sEqual = 1; + sIndex = plvTdoExpected->len; + + while ( sEqual && sIndex-- ) + { + ucByteVal1 = plvTdoExpected->val[ sIndex ]; + ucByteVal2 = plvTdoCaptured->val[ sIndex ]; + if ( plvTdoMask ) + { + ucByteMask = plvTdoMask->val[ sIndex ]; + ucByteVal1 &= ucByteMask; + ucByteVal2 &= ucByteMask; + } + if ( ucByteVal1 != ucByteVal2 ) + { + sEqual = 0; + } + } + + return( sEqual ); +} + + +/***************************************************************************** +* Function: RetBit +* Description: return the (byte, bit) of lv (reading from left to right). +* Parameters: plv - ptr to lenval. +* iByte - the byte to get the bit from. +* iBit - the bit number (0=msb) +* Returns: short - the bit value. +*****************************************************************************/ +short RetBit( lenVal* plv, + int iByte, + int iBit ) +{ + /* assert( ( iByte >= 0 ) && ( iByte < plv->len ) ); */ + /* assert( ( iBit >= 0 ) && ( iBit < 8 ) ); */ + return( (short)( ( plv->val[ iByte ] >> ( 7 - iBit ) ) & 0x1 ) ); +} + +/***************************************************************************** +* Function: SetBit +* Description: set the (byte, bit) of lv equal to val +* Example: SetBit("00000000",byte, 1) equals "01000000". +* Parameters: plv - ptr to lenval. +* iByte - the byte to get the bit from. +* iBit - the bit number (0=msb). +* sVal - the bit value to set. +* Returns: void. +*****************************************************************************/ +void SetBit( lenVal* plv, + int iByte, + int iBit, + short sVal ) +{ + unsigned char ucByteVal; + unsigned char ucBitMask; + + ucBitMask = (unsigned char)(1 << ( 7 - iBit )); + ucByteVal = (unsigned char)(plv->val[ iByte ] & (~ucBitMask)); + + if ( sVal ) + { + ucByteVal |= ucBitMask; + } + plv->val[ iByte ] = ucByteVal; +} + +/***************************************************************************** +* Function: AddVal +* Description: add val1 to val2 and store in resVal; +* assumes val1 and val2 are of equal length. +* Parameters: plvResVal - ptr to result. +* plvVal1 - ptr of addendum. +* plvVal2 - ptr of addendum. +* Returns: void. +*****************************************************************************/ +void addVal( lenVal* plvResVal, + lenVal* plvVal1, + lenVal* plvVal2 ) +{ + unsigned char ucCarry; + unsigned short usSum; + unsigned short usVal1; + unsigned short usVal2; + short sIndex; + + plvResVal->len = plvVal1->len; /* set up length of result */ + + /* start at least significant bit and add bytes */ + ucCarry = 0; + sIndex = plvVal1->len; + while ( sIndex-- ) + { + usVal1 = plvVal1->val[ sIndex ]; /* i'th byte of val1 */ + usVal2 = plvVal2->val[ sIndex ]; /* i'th byte of val2 */ + + /* add the two bytes plus carry from previous addition */ + usSum = (unsigned short)( usVal1 + usVal2 + ucCarry ); + + /* set up carry for next byte */ + ucCarry = (unsigned char)( ( usSum > 255 ) ? 1 : 0 ); + + /* set the i'th byte of the result */ + plvResVal->val[ sIndex ] = (unsigned char)usSum; + } +} + +/***************************************************************************** +* Function: readVal +* Description: read from XSVF numBytes bytes of data into x. +* Parameters: plv - ptr to lenval in which to put the bytes read. +* sNumBytes - the number of bytes to read. +* Returns: void. +*****************************************************************************/ +void readVal( lenVal* plv, + short sNumBytes ) +{ + unsigned char* pucVal; + + plv->len = sNumBytes; /* set the length of the lenVal */ + for ( pucVal = plv->val; sNumBytes; --sNumBytes, ++pucVal ) + { + /* read a byte of data into the lenVal */ + readByte( pucVal ); + } +} + diff --git a/utils/pinprocfw/lenval.h b/utils/pinprocfw/lenval.h new file mode 100644 index 0000000..28af600 --- /dev/null +++ b/utils/pinprocfw/lenval.h @@ -0,0 +1,94 @@ +/*******************************************************/ +/* file: lenval.h */ +/* abstract: This file contains a description of the */ +/* data structure "lenval". */ +/*******************************************************/ + +#ifndef lenval_dot_h +#define lenval_dot_h + +/* the lenVal structure is a byte oriented type used to store an */ +/* arbitrary length binary value. As an example, the hex value */ +/* 0x0e3d is represented as a lenVal with len=2 (since 2 bytes */ +/* and val[0]=0e and val[1]=3d. val[2-MAX_LEN] are undefined */ + +/* maximum length (in bytes) of value to read in */ +/* this needs to be at least 4, and longer than the */ +/* length of the longest SDR instruction. If there is, */ +/* only 1 device in the chain, MAX_LEN must be at least */ +/* ceil(27/8) == 4. For 6 devices in a chain, MAX_LEN */ +/* must be 5, for 14 devices MAX_LEN must be 6, for 20 */ +/* devices MAX_LEN must be 7, etc.. */ +/* You can safely set MAX_LEN to a smaller number if you*/ +/* know how many devices will be in your chain. */ +/* #define MAX_LEN (Actual #define is below this comment block) + This #define defines the maximum length (in bytes) of predefined + buffers in which the XSVF player stores the current shift data. + This length must be greater than the longest shift length (in bytes) + in the XSVF files that will be processed. 7000 is a very conservative + number. The buffers are stored on the stack and if you have limited + stack space, you may decrease the MAX_LEN value. + + How to find the "shift length" in bits? + Look at the ASCII version of the XSVF (generated with the -a option + for the SVF2XSVF translator) and search for the XSDRSIZE command + with the biggest parameter. XSDRSIZE is equivalent to the SVF's + SDR length plus the lengths of applicable HDR and TDR commands. + Remember that the MAX_LEN is defined in bytes. Therefore, the + minimum MAX_LEN = ceil( max( XSDRSIZE ) / 8 ); + + The following MAX_LEN values have been tested and provide relatively + good margin for the corresponding devices: + + DEVICE MAX_LEN Resulting Shift Length Max (in bits) + --------- ------- ---------------------------------------------- + XC9500/XL/XV 32 256 + + CoolRunner/II 256 2048 - actual max 1 device = 1035 bits + + FPGA 128 1024 - svf2xsvf -rlen 1024 + + XC18V00/XCF00 + 1100 8800 - no blank check performed (default) + - actual max 1 device = 8192 bits verify + - max 1 device = 4096 bits program-only + + XC18V00/XCF00 when using the optional Blank Check operation + 2500 20000 - required for blank check + - blank check max 1 device = 16384 bits +*/ +//#define MAX_LEN 7000 +#define MAX_LEN 1100 + + +typedef struct var_len_byte +{ + short len; /* number of chars in this value */ + unsigned char val[MAX_LEN+1]; /* bytes of data */ +} lenVal; + + +/* return the long representation of a lenVal */ +extern long value(lenVal *x); + +/* set lenVal equal to value */ +extern void initLenVal(lenVal *x, long value); + +/* check if expected equals actual (taking the mask into account) */ +extern short EqualLenVal(lenVal *expected, lenVal *actual, lenVal *mask); + +/* add val1+val2 and put the result in resVal */ +extern void addVal(lenVal *resVal, lenVal *val1, lenVal *val2); + +/* return the (byte, bit) of lv (reading from left to right) */ +extern short RetBit(lenVal *lv, int byte, int bit); + +/* set the (byte, bit) of lv equal to val (e.g. SetBit("00000000",byte, 1) + equals "01000000" */ +extern void SetBit(lenVal *lv, int byte, int bit, short val); + +/* read from XSVF numBytes bytes of data into x */ +extern void readVal(lenVal *x, short numBytes); + +#endif + diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp new file mode 100644 index 0000000..b032b49 --- /dev/null +++ b/utils/pinprocfw/pinprocfw.cpp @@ -0,0 +1,1952 @@ +/* +* file: pinprocfw.cpp +* abstract: This is a command line program used to play xsvf files +* through the P-ROC board. xsvf files contain JTAG TAP +* command to erase, verify, and/or program the P-ROCs EEPROM, +* which is used to load the FPGA on power-up. +* +* This program is based off of Xilinx application note Xapp058 +* and the source code contained in that note. The majority +* of deviations from the original source deal with the different +* way the P-ROC can drive the JTAG signals, versus using a simple +* GPIO system. Additionally, since the P-ROC accepts commands +* over a USB bus, the latency implications had to be handled. +*****************************************************************************/ + +/*============================================================================ +* #pragmas +============================================================================*/ +#ifdef _MSC_VER + #pragma warning( disable : 4100 ) +#endif /* _MSC_VER */ + +/*============================================================================ +* #include files +============================================================================*/ +#define DEBUG_MODE +#ifdef DEBUG_MODE + #include + #include + #include + #include + #include +#endif /* DEBUG_MODE */ + +#include "pinprocfw.h" +#include "lenval.h" +#include + +#include "../../include/pinproc.h" // Include libpinproc's header. +PRMachineType machineType = kPRMachineWPC; + +/*============================================================================ +* XSVF #define +============================================================================*/ + +#define XSVF_VERSION "5.01" + +/***************************************************************************** +* 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 */ + + +/***************************************************************************** +* Define: XSVF_MAIN +* Description: Define this to compile with a main function for standalone +* debugging. +*****************************************************************************/ +#ifndef XSVF_MAIN + #ifdef DEBUG_MODE + #define XSVF_MAIN 1 + #endif /* DEBUG_MODE */ +#endif /* XSVF_MAIN */ + + +/*============================================================================ +* DEBUG_MODE #define +============================================================================*/ + +#ifdef DEBUG_MODE + #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat ); } + #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat, arg1 ); } + #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat, arg1, arg2 ); } + #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, 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 */ +PRHandle proc; +static int g_iTCK = 0; /* For xapp058_example .exe */ +static int g_iTMS = 0; /* For xapp058_example .exe */ +static int g_iTDI = 0; /* For xapp058_example .exe */ + +/*============================================================================ +* 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 ) + { + fprintf(stderr, "0x" ); + for ( i = 0; i < plv->len; ++i ) + { + fprintf(stderr, "%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 tms ) +{ + PRJTAGOutputs jtagOutputs; + + //uint32_t wrBuffer[1]; + //wrBuffer[0] = 0xC2000010 | tms; + //PRWriteData(proc, 1, 0, 1, wrBuffer); + + jtagOutputs.tckMask = 0; + jtagOutputs.tdoMask = 0; + jtagOutputs.tmsMask = 1; + jtagOutputs.tms = tms; + PRJTAGDriveOutputs(proc, &jtagOutputs, true); +} + +/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ +/* if in debugging mode, then just set the variables */ +void setPort(short p,short val) +{ + PRJTAGOutputs jtagOutputs; + /* Printing code for the xapp058_example.exe. You must set the specified + JTAG signal (p) to the new value (v). See the above, old Win95 code + as an implementation example. */ + if (p==TMS) + g_iTMS = val; + if (p==TDI) + g_iTDI = val; + if (p==TCK) { + g_iTCK = val; + } + uint32_t buffer[1]; + + // Set up the data and mask bits depending on which bit is being changed. + jtagOutputs.tckMask = p==TCK; + jtagOutputs.tdoMask = p==TDI; + jtagOutputs.tmsMask = p==TMS; + jtagOutputs.tck = g_iTCK; + jtagOutputs.tdo = g_iTDI; + jtagOutputs.tms = g_iTMS; + + //if (p==TMS) buffer[0] = 0xC3000010 | g_iTMS; + //if (p==TDI) buffer[0] = 0xC3000020 | g_iTDI << 1; + //if (p==TCK) buffer[0] = 0xC3000040 | g_iTCK << 2; + //PRWriteData(proc, 1, 0, 1, buffer); + //const uint8_t tckMask = p==TCK; + //const uint8_t tdoMask = p==TDI; + //const uint8_t tmsMask = p==TMS; + PRJTAGDriveOutputs(proc, &jtagOutputs, false); +} + + +// Toggle TCK. +void pulseClock() +{ + setPort(TCK,0); /* set the TCK port to low */ + setPort(TCK,1); /* set the TCK port to high */ +} + + +void readByte(unsigned char *data) +{ + // read in a byte of data from the xsvf file + *data = (unsigned char)fgetc( in ); +} + +unsigned char readTDOBit() +{ + PRJTAGStatus jtagStatus; + + // Read the TDO bit. + // The JTAG module's status register contains the TDO bit. (It's TDI from the + // perspective of the JTAG module.) + PRJTAGGetStatus(proc, &jtagStatus); + + if (jtagStatus.tdi) return ( (unsigned char) 1 ); + return( (unsigned char) 0 ); +} + +void waitTime(long microsec) +{ + long i; + PRJTAGStatus jtagStatus; + // Estimation: each PRReadData request takes approx 2ms. + // Always do at least one. This means the minimum delay time is approx 2ms. + // This makes it impossible for a USB write before and after the delay + // to be squeezed together by USB burst logic. + + // Use the system sleep() if needing a 50ms delay or more due to timing + // error of PRReadData loops adding up. + if ( microsec >= 50000L ) + { + // Make sure TCK is low during wait for XC18V00/XCFxxS + setPort( TCK, 0 ); + + // Read the JTAG status register to exercise the USB bus + PRJTAGGetStatus(proc, &jtagStatus); + + sleep( ( microsec - 2000L ) / 1000000L); + } + else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ + { + + setPort( TCK, 0 ); + + // Always do at least 1 cycle. So minimum delay time is approx 2 ms. + for ( i = 0; i < (microsec-1)/2000 + 1; ++i ) + { + PRJTAGGetStatus(proc, &jtagStatus); + } + //{ + //sleep( ( microsec + 19999L ) / 1000000L ); + //sleep( 1 ); + //pulseClock(); + //} + } +} + +/***************************************************************************** +* 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 */ + for ( i = 0; i < 6; ++i ) xsvfTmsTransition( 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; + int byteCtr; + uint32_t dataBuffer[512]; + uint32_t tempWord1 = 0, tempWord2 = 0; + int numBytes, numWords; + uint32_t addr; + PRJTAGStatus jtagStatus; + + /* 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; + + // Calculate number of bytes and words for later use. + numBytes = (int)( ( lNumBits + 7L ) / 8L ); + numWords = (numBytes + 3) / 4; + + const uint32_t PROC_TDO_TABLE_BASE_ADDR_OFFSET = 0x400; + addr = PROC_TDO_TABLE_BASE_ADDR_OFFSET; + for (i=0; i 40) sleep(1); + //PRWriteData (proc, 1, 0x0, 1, dataBuffer); + PRJTAGShiftTDOData(proc, (uint16_t) lNumBits, (bool_t) iExitShift); + //if (numBytes > 40) sleep(1); + + jtagStatus.commandComplete = 0; + while (!(jtagStatus.commandComplete)) + { + //printf ("."); + PRJTAGGetStatus( proc, &jtagStatus ); + } + + if (pucTdo) { + PRJTAGReadTDIMemory( proc, tableOffset, numWords, dataBuffer ); + + // Move returning words into pucTdo + for (i=0; i> 8*(i%4)) & 0xff ); + } + } +} + + + + +/***************************************************************************** +* 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 ); + //iMismatch = 0; + } + + 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 ); + //waitTime( lRunTestTime * 73); + } + } + } 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 +* 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> +* 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> +* 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", 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 +* 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 +* 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 +* 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 +* 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 +* 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 +* +* 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 +* ... +* 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 +* 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 +* 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 +* == 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 +* : 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 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 ) + { + putchar( ' ' ); + } + + do + { + readByte( &ucText ); + if ( xsvf_iDebugLevel > 0 ) + { + putchar( ucText ? ucText : '\n' ); + } + } while ( ucText ); + + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXWAIT +* Description: XWAIT +* If not already in , then go to . +* Wait in for microseconds. +* Finally, if not already in , then goto . +* 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 */ + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucWaitState = pXsvfInfo->lvTdi.val[0]; + + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucEndState = pXsvfInfo->lvTdi.val[0]; + + /* */ + 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 , go to */ + if ( pXsvfInfo->ucTapState != ucWaitState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); + } + + /* Wait for microseconds */ + waitTime( lWaitTime ); + + /* If not already in , go to */ + 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 */ + xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); + } + 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() +{ + 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 - Operation completed successfully. Cycle P-ROC power to activate any changes.\n" ); + } + + xsvfCleanup( &xsvfInfo ); + + return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); +} + + +/*============================================================================ +* main +============================================================================*/ + +/***************************************************************************** +* Function: main +* Description: main function. +* Specified here for creating stand-alone debug executable. +* Embedded users should call xsvfExecute() directly. +* Parameters: argc - number of command-line arguments. +* argv - array of ptrs to strings (command-line arguments). +* Returns: int - Legacy return value: 1 = success; 0 = error. +*****************************************************************************/ +#ifdef XSVF_MAIN +int main( int argc, char** argv ) +{ + int iErrorCode; + char* pzXsvfFileName; + int i; + clock_t startClock; + clock_t endClock; + + // Set a signal handler so that we can exit gracefully on Ctrl-C: + //signal(SIGINT, sigint); + + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); + pzXsvfFileName = 0; + + //printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); + + for ( i = 1; i < argc ; ++i ) + { + if ( !strcmp( argv[ i ], "-v" ) ) + { + ++i; + if ( i >= argc ) + { + printf( "ERROR: missing parameter for -v option.\n" ); + } + else + { + xsvf_iDebugLevel = atoi( argv[ i ] ); + printf( "Verbose level = %d\n", xsvf_iDebugLevel ); + } + } + else + { + pzXsvfFileName = argv[ i ]; + printf( "XSVF file = %s\n", pzXsvfFileName ); + } + } + + if (!(pzXsvfFileName) ) + { + fprintf(stderr, "USAGE: %s \n", argv[0] ); + fprintf(stderr, " filename.xsvf = the XSVF file to execute.\n" ); + } + else + { + + /* read from the XSVF file instead of a real prom */ + in = fopen( pzXsvfFileName, "rb" ); + if ( !in ) + { + fprintf(stderr, "ERROR: Cannot open file %s\n", pzXsvfFileName ); + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); + } + else + { + // Instantiate the P-ROC device: + XSVFDBG_PRINTF( 1, "Opening P-ROC.\n"); + proc = PRCreate(machineType); + if (proc == kPRHandleInvalid) + { + fprintf(stderr, "ERROR: Unable to open P-ROC: %s\n", PRGetLastErrorText()); + return 1; + } + PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device. + + /* Execute the XSVF in the file */ + fprintf(stderr, "Updating P-ROC. This may take a couple of minutes.\n"); + fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); + startClock = clock(); + iErrorCode = xsvfExecute(); + endClock = clock(); + fclose( in ); + + // Destroy the P-ROC device handle: + PRDelete(proc); + proc = kPRHandleInvalid; + } + } + + return( iErrorCode ); +} +#endif /* XSVF_MAIN */ + diff --git a/utils/pinprocfw/pinprocfw.h b/utils/pinprocfw/pinprocfw.h new file mode 100644 index 0000000..ece2544 --- /dev/null +++ b/utils/pinprocfw/pinprocfw.h @@ -0,0 +1,64 @@ +/***************************************************************************** +* File: micro.h +* Description: This header file contains the function prototype to the +* primary interface function for the XSVF player. +* Usage: FIRST - PORTS.C +* Customize the ports.c function implementations to establish +* the correct protocol for communicating with your JTAG ports +* (setPort() and readTDOBit()) and tune the waitTime() delay +* function. Also, establish access to the XSVF data source +* in the readByte() function. +* FINALLY - Call xsvfExecute(). +*****************************************************************************/ +#ifndef PINPROCFW_H +#define PINPROCFW_H + +/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ +#define XSVF_LEGACY_SUCCESS 1 +#define XSVF_LEGACY_ERROR 0 + +/* 4.04 [NEW] Error codes for xsvfExecute. */ +/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ +#define XSVF_ERROR_NONE 0 +#define XSVF_ERROR_UNKNOWN 1 +#define XSVF_ERROR_TDOMISMATCH 2 +#define XSVF_ERROR_MAXRETRIES 3 /* TDO mismatch after max retries */ +#define XSVF_ERROR_ILLEGALCMD 4 +#define XSVF_ERROR_ILLEGALSTATE 5 +#define XSVF_ERROR_DATAOVERFLOW 6 /* Data > lenVal MAX_LEN buffer size*/ +/* Insert new errors here */ +#define XSVF_ERROR_LAST 7 + +/***************************************************************************** +* Function: xsvfExecute +* Description: Process, interpret, and apply the XSVF commands. +* See port.c:readByte for source of XSVF data. +* Parameters: none. +* Returns: int - For error codes see above. +*****************************************************************************/ +extern int xsvfExecute(); + +/* these constants are used to send the appropriate ports to setPort */ +/* they should be enumerated types, but some of the microcontroller */ +/* compilers don't like enumerated types */ +#define TCK (short) 0 +#define TMS (short) 1 +#define TDI (short) 2 + +/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ +void setPort(short p, short val); + +/* read the TDO bit and store it in val */ +unsigned char readTDOBit(); + +/* make clock go down->up->down*/ +void pulseClock(); + +/* read the next byte of data from the xsvf file */ +void readByte(unsigned char *data); + +void waitTime(long microsec); + + +#endif /* PINPROCFW_H */ + diff --git a/utils/temp/micro.cpp b/utils/temp/micro.cpp new file mode 100644 index 0000000..6d95745 --- /dev/null +++ b/utils/temp/micro.cpp @@ -0,0 +1,1951 @@ +/* +* file: pinprocfw.cpp +* abstract: This is a command line program used to play xsvf files +* through the P-ROC board. xsvf files contain JTAG TAP +* command to erase, verify, and/or program the P-ROCs EEPROM, +* which is used to load the FPGA on power-up. +* +* This program is based off of Xilinx application note Xapp058 +* and the source code contained in that note. The majority +* of deviations from the original source deal with the different +* way the P-ROC can drive the JTAG signals, versus using a simple +* GPIO system. Additionally, since the P-ROC accepts commands +* over a USB bus, the latency implications had to be handled. +*****************************************************************************/ + +/*============================================================================ +* #pragmas +============================================================================*/ +#ifdef _MSC_VER + #pragma warning( disable : 4100 ) +#endif /* _MSC_VER */ + +/*============================================================================ +* #include files +============================================================================*/ +#define DEBUG_MODE +#ifdef DEBUG_MODE + #include + #include + #include + #include + #include +#endif /* DEBUG_MODE */ + +#include "pinprocfw.h" +#include + +#include "../../include/pinproc.h" // Include libpinproc's header. +PRMachineType machineType = kPRMachineWPC; + +/*============================================================================ +* XSVF #define +============================================================================*/ + +#define XSVF_VERSION "5.01" + +/***************************************************************************** +* 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 */ + + +/***************************************************************************** +* Define: XSVF_MAIN +* Description: Define this to compile with a main function for standalone +* debugging. +*****************************************************************************/ +#ifndef XSVF_MAIN + #ifdef DEBUG_MODE + #define XSVF_MAIN 1 + #endif /* DEBUG_MODE */ +#endif /* XSVF_MAIN */ + + +/*============================================================================ +* DEBUG_MODE #define +============================================================================*/ + +#ifdef DEBUG_MODE + #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat ); } + #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat, arg1 ); } + #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, pzFormat, arg1, arg2 ); } + #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ + { if ( xsvf_iDebugLevel >= iDebugLevel ) \ + fprintf(stderr, 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 */ +PRHandle proc; +static int g_iTCK = 0; /* For xapp058_example .exe */ +static int g_iTMS = 0; /* For xapp058_example .exe */ +static int g_iTDI = 0; /* For xapp058_example .exe */ + +/*============================================================================ +* 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 ) + { + fprintf(stderr, "0x" ); + for ( i = 0; i < plv->len; ++i ) + { + fprintf(stderr, "%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 tms ) +{ + PRJTAGOutputs jtagOutputs; + + //uint32_t wrBuffer[1]; + //wrBuffer[0] = 0xC2000010 | tms; + //PRWriteData(proc, 1, 0, 1, wrBuffer); + + jtagOutputs.tckMask = 0; + jtagOutputs.tdoMask = 0; + jtagOutputs.tmsMask = 1; + jtagOutputs.tms = tms; + PRJTAGDriveOutputs(proc, &jtagOutputs, true); +} + +/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ +/* if in debugging mode, then just set the variables */ +void setPort(short p,short val) +{ + PRJTAGOutputs jtagOutputs; + /* Printing code for the xapp058_example.exe. You must set the specified + JTAG signal (p) to the new value (v). See the above, old Win95 code + as an implementation example. */ + if (p==TMS) + g_iTMS = val; + if (p==TDI) + g_iTDI = val; + if (p==TCK) { + g_iTCK = val; + } + uint32_t buffer[1]; + + // Set up the data and mask bits depending on which bit is being changed. + jtagOutputs.tckMask = p==TCK; + jtagOutputs.tdoMask = p==TDI; + jtagOutputs.tmsMask = p==TMS; + jtagOutputs.tck = g_iTCK; + jtagOutputs.tdo = g_iTDI; + jtagOutputs.tms = g_iTMS; + + //if (p==TMS) buffer[0] = 0xC3000010 | g_iTMS; + //if (p==TDI) buffer[0] = 0xC3000020 | g_iTDI << 1; + //if (p==TCK) buffer[0] = 0xC3000040 | g_iTCK << 2; + //PRWriteData(proc, 1, 0, 1, buffer); + //const uint8_t tckMask = p==TCK; + //const uint8_t tdoMask = p==TDI; + //const uint8_t tmsMask = p==TMS; + PRJTAGDriveOutputs(proc, &jtagOutputs, false); +} + + +// Toggle TCK. +void pulseClock() +{ + setPort(TCK,0); /* set the TCK port to low */ + setPort(TCK,1); /* set the TCK port to high */ +} + + +void readByte(unsigned char *data) +{ + // read in a byte of data from the xsvf file + *data = (unsigned char)fgetc( in ); +} + +unsigned char readTDOBit() +{ + PRJTAGStatus jtagStatus; + + // Read the TDO bit. + // The JTAG module's status register contains the TDO bit. (It's TDI from the + // perspective of the JTAG module.) + PRJTAGGetStatus(proc, &jtagStatus); + + if (jtagStatus.tdi) return ( (unsigned char) 1 ); + return( (unsigned char) 0 ); +} + +void waitTime(long microsec) +{ + long i; + PRJTAGStatus jtagStatus; + // Estimation: each PRReadData request takes approx 2ms. + // Always do at least one. This means the minimum delay time is approx 2ms. + // This makes it impossible for a USB write before and after the delay + // to be squeezed together by USB burst logic. + + // Use the system sleep() if needing a 50ms delay or more due to timing + // error of PRReadData loops adding up. + if ( microsec >= 50000L ) + { + // Make sure TCK is low during wait for XC18V00/XCFxxS + setPort( TCK, 0 ); + + // Read the JTAG status register to exercise the USB bus + PRJTAGGetStatus(proc, &jtagStatus); + + sleep( ( microsec - 2000L ) / 1000000L); + } + else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ + { + + setPort( TCK, 0 ); + + // Always do at least 1 cycle. So minimum delay time is approx 2 ms. + for ( i = 0; i < (microsec-1)/2000 + 1; ++i ) + { + PRJTAGGetStatus(proc, &jtagStatus); + } + //{ + //sleep( ( microsec + 19999L ) / 1000000L ); + //sleep( 1 ); + //pulseClock(); + //} + } +} + +/***************************************************************************** +* 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 */ + for ( i = 0; i < 6; ++i ) xsvfTmsTransition( 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; + int byteCtr; + uint32_t dataBuffer[512]; + uint32_t tempWord1 = 0, tempWord2 = 0; + int numBytes, numWords; + uint32_t addr; + PRJTAGStatus jtagStatus; + + /* 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; + + // Calculate number of bytes and words for later use. + numBytes = (int)( ( lNumBits + 7L ) / 8L ); + numWords = (numBytes + 3) / 4; + + const uint32_t PROC_TDO_TABLE_BASE_ADDR_OFFSET = 0x400; + addr = PROC_TDO_TABLE_BASE_ADDR_OFFSET; + for (i=0; i 40) sleep(1); + //PRWriteData (proc, 1, 0x0, 1, dataBuffer); + PRJTAGShiftTDOData(proc, (uint16_t) lNumBits, (bool_t) iExitShift); + //if (numBytes > 40) sleep(1); + + jtagStatus.commandComplete = 0; + while (!(jtagStatus.commandComplete)) + { + //printf ("."); + PRJTAGGetStatus( proc, &jtagStatus ); + } + + if (pucTdo) { + PRJTAGReadTDIMemory( proc, tableOffset, numWords, dataBuffer ); + + // Move returning words into pucTdo + for (i=0; i> 8*(i%4)) & 0xff ); + } + } +} + + + + +/***************************************************************************** +* 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 ); + //iMismatch = 0; + } + + 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 ); + //waitTime( lRunTestTime * 73); + } + } + } 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 +* 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> +* 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> +* 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", 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 +* 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 +* 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 +* 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 +* 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 +* 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 +* +* 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 +* ... +* 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 +* 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 +* 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 +* == 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 +* : 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 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 ) + { + putchar( ' ' ); + } + + do + { + readByte( &ucText ); + if ( xsvf_iDebugLevel > 0 ) + { + putchar( ucText ? ucText : '\n' ); + } + } while ( ucText ); + + pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; + + return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** +* Function: xsvfDoXWAIT +* Description: XWAIT +* If not already in , then go to . +* Wait in for microseconds. +* Finally, if not already in , then goto . +* 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 */ + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucWaitState = pXsvfInfo->lvTdi.val[0]; + + /* */ + readVal( &(pXsvfInfo->lvTdi), 1 ); + ucEndState = pXsvfInfo->lvTdi.val[0]; + + /* */ + 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 , go to */ + if ( pXsvfInfo->ucTapState != ucWaitState ) + { + xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); + } + + /* Wait for microseconds */ + waitTime( lWaitTime ); + + /* If not already in , go to */ + 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 */ + xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); + } + 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() +{ + 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 - Operation completed successfully. Cycle P-ROC power to activate any changes.\n" ); + } + + xsvfCleanup( &xsvfInfo ); + + return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); +} + + +/*============================================================================ +* main +============================================================================*/ + +/***************************************************************************** +* Function: main +* Description: main function. +* Specified here for creating stand-alone debug executable. +* Embedded users should call xsvfExecute() directly. +* Parameters: argc - number of command-line arguments. +* argv - array of ptrs to strings (command-line arguments). +* Returns: int - Legacy return value: 1 = success; 0 = error. +*****************************************************************************/ +#ifdef XSVF_MAIN +int main( int argc, char** argv ) +{ + int iErrorCode; + char* pzXsvfFileName; + int i; + clock_t startClock; + clock_t endClock; + + // Set a signal handler so that we can exit gracefully on Ctrl-C: + //signal(SIGINT, sigint); + + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); + pzXsvfFileName = 0; + + //printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); + + for ( i = 1; i < argc ; ++i ) + { + if ( !strcmp( argv[ i ], "-v" ) ) + { + ++i; + if ( i >= argc ) + { + printf( "ERROR: missing parameter for -v option.\n" ); + } + else + { + xsvf_iDebugLevel = atoi( argv[ i ] ); + printf( "Verbose level = %d\n", xsvf_iDebugLevel ); + } + } + else + { + pzXsvfFileName = argv[ i ]; + printf( "XSVF file = %s\n", pzXsvfFileName ); + } + } + + if (!(pzXsvfFileName) ) + { + fprintf(stderr, "USAGE: %s \n", argv[0] ); + fprintf(stderr, " filename.xsvf = the XSVF file to execute.\n" ); + } + else + { + + /* read from the XSVF file instead of a real prom */ + in = fopen( pzXsvfFileName, "rb" ); + if ( !in ) + { + fprintf(stderr, "ERROR: Cannot open file %s\n", pzXsvfFileName ); + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); + } + else + { + // Instantiate the P-ROC device: + XSVFDBG_PRINTF( 1, "Opening P-ROC.\n"); + proc = PRCreate(machineType); + if (proc == kPRHandleInvalid) + { + fprintf(stderr, "ERROR: Unable to open P-ROC: %s\n", PRGetLastErrorText()); + return 1; + } + PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device. + + /* Execute the XSVF in the file */ + fprintf(stderr, "Updating P-ROC. This may take a couple of minutes.\n"); + fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); + startClock = clock(); + iErrorCode = xsvfExecute(); + endClock = clock(); + fclose( in ); + + // Destroy the P-ROC device handle: + PRDelete(proc); + proc = kPRHandleInvalid; + } + } + + return( iErrorCode ); +} +#endif /* XSVF_MAIN */ + diff --git a/utils/temp/micro.h b/utils/temp/micro.h new file mode 100644 index 0000000..7525805 --- /dev/null +++ b/utils/temp/micro.h @@ -0,0 +1,42 @@ +/***************************************************************************** +* File: micro.h +* Description: This header file contains the function prototype to the +* primary interface function for the XSVF player. +* Usage: FIRST - PORTS.C +* Customize the ports.c function implementations to establish +* the correct protocol for communicating with your JTAG ports +* (setPort() and readTDOBit()) and tune the waitTime() delay +* function. Also, establish access to the XSVF data source +* in the readByte() function. +* FINALLY - Call xsvfExecute(). +*****************************************************************************/ +#ifndef XSVF_MICRO_H +#define XSVF_MICRO_H + +/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ +#define XSVF_LEGACY_SUCCESS 1 +#define XSVF_LEGACY_ERROR 0 + +/* 4.04 [NEW] Error codes for xsvfExecute. */ +/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ +#define XSVF_ERROR_NONE 0 +#define XSVF_ERROR_UNKNOWN 1 +#define XSVF_ERROR_TDOMISMATCH 2 +#define XSVF_ERROR_MAXRETRIES 3 /* TDO mismatch after max retries */ +#define XSVF_ERROR_ILLEGALCMD 4 +#define XSVF_ERROR_ILLEGALSTATE 5 +#define XSVF_ERROR_DATAOVERFLOW 6 /* Data > lenVal MAX_LEN buffer size*/ +/* Insert new errors here */ +#define XSVF_ERROR_LAST 7 + +/***************************************************************************** +* Function: xsvfExecute +* Description: Process, interpret, and apply the XSVF commands. +* See port.c:readByte for source of XSVF data. +* Parameters: none. +* Returns: int - For error codes see above. +*****************************************************************************/ +extern int xsvfExecute(); + +#endif /* XSVF_MICRO_H */ + diff --git a/utils/temp/ports.cpp b/utils/temp/ports.cpp new file mode 100644 index 0000000..cc55825 --- /dev/null +++ b/utils/temp/ports.cpp @@ -0,0 +1,127 @@ +/*******************************************************/ +/* file: ports.c */ +/* abstract: This file contains the routines to */ +/* output values on the JTAG ports, to read */ +/* the TDO bit, and to read a byte of data */ +/* from the prom */ +/* Revisions: */ +/* 12/01/2008: Same code as before (original v5.01). */ +/* Updated comments to clarify instructions.*/ +/* Add print in setPort for xapp058_example.exe.*/ +/*******************************************************/ +#include "ports.h" +/*#include "prgispx.h"*/ + +#include "stdio.h" +extern FILE *in; +static int g_iTCK = 0; /* For xapp058_example .exe */ +static int g_iTMS = 0; /* For xapp058_example .exe */ +static int g_iTDI = 0; /* For xapp058_example .exe */ + +#include +#include +#include +#include "../../include/pinproc.h" // Include libpinproc's header. +extern PRHandle proc; + +/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ +/* if in debugging mode, then just set the variables */ +void setPort(short p,short val) +{ + PRJTAGOutputs jtagOutputs; + /* Printing code for the xapp058_example.exe. You must set the specified + JTAG signal (p) to the new value (v). See the above, old Win95 code + as an implementation example. */ + if (p==TMS) + g_iTMS = val; + if (p==TDI) + g_iTDI = val; + if (p==TCK) { + g_iTCK = val; + } + uint32_t buffer[1]; + + // Set up the data and mask bits depending on which bit is being changed. + jtagOutputs.tckMask = p==TCK; + jtagOutputs.tdoMask = p==TDI; + jtagOutputs.tmsMask = p==TMS; + jtagOutputs.tck = g_iTCK; + jtagOutputs.tdo = g_iTDI; + jtagOutputs.tms = g_iTMS; + + //if (p==TMS) buffer[0] = 0xC3000010 | g_iTMS; + //if (p==TDI) buffer[0] = 0xC3000020 | g_iTDI << 1; + //if (p==TCK) buffer[0] = 0xC3000040 | g_iTCK << 2; + //PRWriteData(proc, 1, 0, 1, buffer); + //const uint8_t tckMask = p==TCK; + //const uint8_t tdoMask = p==TDI; + //const uint8_t tmsMask = p==TMS; + PRJTAGDriveOutputs(proc, &jtagOutputs, false); +} + + +// Toggle TCK. +void pulseClock() +{ + setPort(TCK,0); /* set the TCK port to low */ + setPort(TCK,1); /* set the TCK port to high */ +} + + +void readByte(unsigned char *data) +{ + // read in a byte of data from the xsvf file + *data = (unsigned char)fgetc( in ); +} + +unsigned char readTDOBit() +{ + PRJTAGStatus jtagStatus; + + // Read the TDO bit. + // The JTAG module's status register contains the TDO bit. (It's TDI from the + // perspective of the JTAG module.) + PRJTAGGetStatus(proc, &jtagStatus); + + if (jtagStatus.tdi) return ( (unsigned char) 1 ); + return( (unsigned char) 0 ); +} + +void waitTime(long microsec) +{ + long i; + PRJTAGStatus jtagStatus; + // Estimation: each PRReadData request takes approx 2ms. + // Always do at least one. This means the minimum delay time is approx 2ms. + // This makes it impossible for a USB write before and after the delay + // to be squeezed together by USB burst logic. + + // Use the system sleep() if needing a 50ms delay or more due to timing + // error of PRReadData loops adding up. + if ( microsec >= 50000L ) + { + // Make sure TCK is low during wait for XC18V00/XCFxxS + setPort( TCK, 0 ); + + // Read the JTAG status register to exercise the USB bus + PRJTAGGetStatus(proc, &jtagStatus); + + sleep( ( microsec - 2000L ) / 1000000L); + } + else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ + { + + setPort( TCK, 0 ); + + // Always do at least 1 cycle. So minimum delay time is approx 2 ms. + for ( i = 0; i < (microsec-1)/2000 + 1; ++i ) + { + PRJTAGGetStatus(proc, &jtagStatus); + } + //{ + //sleep( ( microsec + 19999L ) / 1000000L ); + //sleep( 1 ); + //pulseClock(); + //} + } +} diff --git a/utils/temp/ports.h b/utils/temp/ports.h new file mode 100644 index 0000000..e09d95e --- /dev/null +++ b/utils/temp/ports.h @@ -0,0 +1,31 @@ +/*******************************************************/ +/* file: ports.h */ +/* abstract: This file contains extern declarations */ +/* for providing stimulus to the JTAG ports.*/ +/*******************************************************/ + +#ifndef ports_dot_h +#define ports_dot_h + +/* these constants are used to send the appropriate ports to setPort */ +/* they should be enumerated types, but some of the microcontroller */ +/* compilers don't like enumerated types */ +#define TCK (short) 0 +#define TMS (short) 1 +#define TDI (short) 2 + +/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ +extern void setPort(short p, short val); + +/* read the TDO bit and store it in val */ +extern unsigned char readTDOBit(); + +/* make clock go down->up->down*/ +extern void pulseClock(); + +/* read the next byte of data from the xsvf file */ +extern void readByte(unsigned char *data); + +extern void waitTime(long microsec); + +#endif From 1c0a034d9a147658299378b00253b371263d9cb3 Mon Sep 17 00:00:00 2001 From: gstellenberg Date: Sun, 28 Jun 2009 22:35:04 -0500 Subject: [PATCH 2/2] removing unused files. --- utils/temp/micro.cpp | 1951 ------------------------------------------ utils/temp/micro.h | 42 - utils/temp/ports.cpp | 127 --- utils/temp/ports.h | 31 - 4 files changed, 2151 deletions(-) delete mode 100644 utils/temp/micro.cpp delete mode 100644 utils/temp/micro.h delete mode 100644 utils/temp/ports.cpp delete mode 100644 utils/temp/ports.h diff --git a/utils/temp/micro.cpp b/utils/temp/micro.cpp deleted file mode 100644 index 6d95745..0000000 --- a/utils/temp/micro.cpp +++ /dev/null @@ -1,1951 +0,0 @@ -/* -* file: pinprocfw.cpp -* abstract: This is a command line program used to play xsvf files -* through the P-ROC board. xsvf files contain JTAG TAP -* command to erase, verify, and/or program the P-ROCs EEPROM, -* which is used to load the FPGA on power-up. -* -* This program is based off of Xilinx application note Xapp058 -* and the source code contained in that note. The majority -* of deviations from the original source deal with the different -* way the P-ROC can drive the JTAG signals, versus using a simple -* GPIO system. Additionally, since the P-ROC accepts commands -* over a USB bus, the latency implications had to be handled. -*****************************************************************************/ - -/*============================================================================ -* #pragmas -============================================================================*/ -#ifdef _MSC_VER - #pragma warning( disable : 4100 ) -#endif /* _MSC_VER */ - -/*============================================================================ -* #include files -============================================================================*/ -#define DEBUG_MODE -#ifdef DEBUG_MODE - #include - #include - #include - #include - #include -#endif /* DEBUG_MODE */ - -#include "pinprocfw.h" -#include - -#include "../../include/pinproc.h" // Include libpinproc's header. -PRMachineType machineType = kPRMachineWPC; - -/*============================================================================ -* XSVF #define -============================================================================*/ - -#define XSVF_VERSION "5.01" - -/***************************************************************************** -* 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 */ - - -/***************************************************************************** -* Define: XSVF_MAIN -* Description: Define this to compile with a main function for standalone -* debugging. -*****************************************************************************/ -#ifndef XSVF_MAIN - #ifdef DEBUG_MODE - #define XSVF_MAIN 1 - #endif /* DEBUG_MODE */ -#endif /* XSVF_MAIN */ - - -/*============================================================================ -* DEBUG_MODE #define -============================================================================*/ - -#ifdef DEBUG_MODE - #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ - { if ( xsvf_iDebugLevel >= iDebugLevel ) \ - fprintf(stderr, pzFormat ); } - #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ - { if ( xsvf_iDebugLevel >= iDebugLevel ) \ - fprintf(stderr, pzFormat, arg1 ); } - #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ - { if ( xsvf_iDebugLevel >= iDebugLevel ) \ - fprintf(stderr, pzFormat, arg1, arg2 ); } - #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ - { if ( xsvf_iDebugLevel >= iDebugLevel ) \ - fprintf(stderr, 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 */ -PRHandle proc; -static int g_iTCK = 0; /* For xapp058_example .exe */ -static int g_iTMS = 0; /* For xapp058_example .exe */ -static int g_iTDI = 0; /* For xapp058_example .exe */ - -/*============================================================================ -* 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 ) - { - fprintf(stderr, "0x" ); - for ( i = 0; i < plv->len; ++i ) - { - fprintf(stderr, "%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 tms ) -{ - PRJTAGOutputs jtagOutputs; - - //uint32_t wrBuffer[1]; - //wrBuffer[0] = 0xC2000010 | tms; - //PRWriteData(proc, 1, 0, 1, wrBuffer); - - jtagOutputs.tckMask = 0; - jtagOutputs.tdoMask = 0; - jtagOutputs.tmsMask = 1; - jtagOutputs.tms = tms; - PRJTAGDriveOutputs(proc, &jtagOutputs, true); -} - -/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ -/* if in debugging mode, then just set the variables */ -void setPort(short p,short val) -{ - PRJTAGOutputs jtagOutputs; - /* Printing code for the xapp058_example.exe. You must set the specified - JTAG signal (p) to the new value (v). See the above, old Win95 code - as an implementation example. */ - if (p==TMS) - g_iTMS = val; - if (p==TDI) - g_iTDI = val; - if (p==TCK) { - g_iTCK = val; - } - uint32_t buffer[1]; - - // Set up the data and mask bits depending on which bit is being changed. - jtagOutputs.tckMask = p==TCK; - jtagOutputs.tdoMask = p==TDI; - jtagOutputs.tmsMask = p==TMS; - jtagOutputs.tck = g_iTCK; - jtagOutputs.tdo = g_iTDI; - jtagOutputs.tms = g_iTMS; - - //if (p==TMS) buffer[0] = 0xC3000010 | g_iTMS; - //if (p==TDI) buffer[0] = 0xC3000020 | g_iTDI << 1; - //if (p==TCK) buffer[0] = 0xC3000040 | g_iTCK << 2; - //PRWriteData(proc, 1, 0, 1, buffer); - //const uint8_t tckMask = p==TCK; - //const uint8_t tdoMask = p==TDI; - //const uint8_t tmsMask = p==TMS; - PRJTAGDriveOutputs(proc, &jtagOutputs, false); -} - - -// Toggle TCK. -void pulseClock() -{ - setPort(TCK,0); /* set the TCK port to low */ - setPort(TCK,1); /* set the TCK port to high */ -} - - -void readByte(unsigned char *data) -{ - // read in a byte of data from the xsvf file - *data = (unsigned char)fgetc( in ); -} - -unsigned char readTDOBit() -{ - PRJTAGStatus jtagStatus; - - // Read the TDO bit. - // The JTAG module's status register contains the TDO bit. (It's TDI from the - // perspective of the JTAG module.) - PRJTAGGetStatus(proc, &jtagStatus); - - if (jtagStatus.tdi) return ( (unsigned char) 1 ); - return( (unsigned char) 0 ); -} - -void waitTime(long microsec) -{ - long i; - PRJTAGStatus jtagStatus; - // Estimation: each PRReadData request takes approx 2ms. - // Always do at least one. This means the minimum delay time is approx 2ms. - // This makes it impossible for a USB write before and after the delay - // to be squeezed together by USB burst logic. - - // Use the system sleep() if needing a 50ms delay or more due to timing - // error of PRReadData loops adding up. - if ( microsec >= 50000L ) - { - // Make sure TCK is low during wait for XC18V00/XCFxxS - setPort( TCK, 0 ); - - // Read the JTAG status register to exercise the USB bus - PRJTAGGetStatus(proc, &jtagStatus); - - sleep( ( microsec - 2000L ) / 1000000L); - } - else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ - { - - setPort( TCK, 0 ); - - // Always do at least 1 cycle. So minimum delay time is approx 2 ms. - for ( i = 0; i < (microsec-1)/2000 + 1; ++i ) - { - PRJTAGGetStatus(proc, &jtagStatus); - } - //{ - //sleep( ( microsec + 19999L ) / 1000000L ); - //sleep( 1 ); - //pulseClock(); - //} - } -} - -/***************************************************************************** -* 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 */ - for ( i = 0; i < 6; ++i ) xsvfTmsTransition( 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; - int byteCtr; - uint32_t dataBuffer[512]; - uint32_t tempWord1 = 0, tempWord2 = 0; - int numBytes, numWords; - uint32_t addr; - PRJTAGStatus jtagStatus; - - /* 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; - - // Calculate number of bytes and words for later use. - numBytes = (int)( ( lNumBits + 7L ) / 8L ); - numWords = (numBytes + 3) / 4; - - const uint32_t PROC_TDO_TABLE_BASE_ADDR_OFFSET = 0x400; - addr = PROC_TDO_TABLE_BASE_ADDR_OFFSET; - for (i=0; i 40) sleep(1); - //PRWriteData (proc, 1, 0x0, 1, dataBuffer); - PRJTAGShiftTDOData(proc, (uint16_t) lNumBits, (bool_t) iExitShift); - //if (numBytes > 40) sleep(1); - - jtagStatus.commandComplete = 0; - while (!(jtagStatus.commandComplete)) - { - //printf ("."); - PRJTAGGetStatus( proc, &jtagStatus ); - } - - if (pucTdo) { - PRJTAGReadTDIMemory( proc, tableOffset, numWords, dataBuffer ); - - // Move returning words into pucTdo - for (i=0; i> 8*(i%4)) & 0xff ); - } - } -} - - - - -/***************************************************************************** -* 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 ); - //iMismatch = 0; - } - - 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 ); - //waitTime( lRunTestTime * 73); - } - } - } 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 -* 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> -* 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> -* 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", 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 -* 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 -* 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 -* 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 -* 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 -* 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 -* -* 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 -* ... -* 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 -* 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 -* 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 -* == 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 -* : 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 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 ) - { - putchar( ' ' ); - } - - do - { - readByte( &ucText ); - if ( xsvf_iDebugLevel > 0 ) - { - putchar( ucText ? ucText : '\n' ); - } - } while ( ucText ); - - pXsvfInfo->iErrorCode = XSVF_ERROR_NONE; - - return( pXsvfInfo->iErrorCode ); -} - -/***************************************************************************** -* Function: xsvfDoXWAIT -* Description: XWAIT -* If not already in , then go to . -* Wait in for microseconds. -* Finally, if not already in , then goto . -* 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 */ - /* */ - readVal( &(pXsvfInfo->lvTdi), 1 ); - ucWaitState = pXsvfInfo->lvTdi.val[0]; - - /* */ - readVal( &(pXsvfInfo->lvTdi), 1 ); - ucEndState = pXsvfInfo->lvTdi.val[0]; - - /* */ - 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 , go to */ - if ( pXsvfInfo->ucTapState != ucWaitState ) - { - xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); - } - - /* Wait for microseconds */ - waitTime( lWaitTime ); - - /* If not already in , go to */ - 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 */ - xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); - } - 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() -{ - 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 - Operation completed successfully. Cycle P-ROC power to activate any changes.\n" ); - } - - xsvfCleanup( &xsvfInfo ); - - return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); -} - - -/*============================================================================ -* main -============================================================================*/ - -/***************************************************************************** -* Function: main -* Description: main function. -* Specified here for creating stand-alone debug executable. -* Embedded users should call xsvfExecute() directly. -* Parameters: argc - number of command-line arguments. -* argv - array of ptrs to strings (command-line arguments). -* Returns: int - Legacy return value: 1 = success; 0 = error. -*****************************************************************************/ -#ifdef XSVF_MAIN -int main( int argc, char** argv ) -{ - int iErrorCode; - char* pzXsvfFileName; - int i; - clock_t startClock; - clock_t endClock; - - // Set a signal handler so that we can exit gracefully on Ctrl-C: - //signal(SIGINT, sigint); - - iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); - pzXsvfFileName = 0; - - //printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); - - for ( i = 1; i < argc ; ++i ) - { - if ( !strcmp( argv[ i ], "-v" ) ) - { - ++i; - if ( i >= argc ) - { - printf( "ERROR: missing parameter for -v option.\n" ); - } - else - { - xsvf_iDebugLevel = atoi( argv[ i ] ); - printf( "Verbose level = %d\n", xsvf_iDebugLevel ); - } - } - else - { - pzXsvfFileName = argv[ i ]; - printf( "XSVF file = %s\n", pzXsvfFileName ); - } - } - - if (!(pzXsvfFileName) ) - { - fprintf(stderr, "USAGE: %s \n", argv[0] ); - fprintf(stderr, " filename.xsvf = the XSVF file to execute.\n" ); - } - else - { - - /* read from the XSVF file instead of a real prom */ - in = fopen( pzXsvfFileName, "rb" ); - if ( !in ) - { - fprintf(stderr, "ERROR: Cannot open file %s\n", pzXsvfFileName ); - iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); - } - else - { - // Instantiate the P-ROC device: - XSVFDBG_PRINTF( 1, "Opening P-ROC.\n"); - proc = PRCreate(machineType); - if (proc == kPRHandleInvalid) - { - fprintf(stderr, "ERROR: Unable to open P-ROC: %s\n", PRGetLastErrorText()); - return 1; - } - PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device. - - /* Execute the XSVF in the file */ - fprintf(stderr, "Updating P-ROC. This may take a couple of minutes.\n"); - fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); - startClock = clock(); - iErrorCode = xsvfExecute(); - endClock = clock(); - fclose( in ); - - // Destroy the P-ROC device handle: - PRDelete(proc); - proc = kPRHandleInvalid; - } - } - - return( iErrorCode ); -} -#endif /* XSVF_MAIN */ - diff --git a/utils/temp/micro.h b/utils/temp/micro.h deleted file mode 100644 index 7525805..0000000 --- a/utils/temp/micro.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* File: micro.h -* Description: This header file contains the function prototype to the -* primary interface function for the XSVF player. -* Usage: FIRST - PORTS.C -* Customize the ports.c function implementations to establish -* the correct protocol for communicating with your JTAG ports -* (setPort() and readTDOBit()) and tune the waitTime() delay -* function. Also, establish access to the XSVF data source -* in the readByte() function. -* FINALLY - Call xsvfExecute(). -*****************************************************************************/ -#ifndef XSVF_MICRO_H -#define XSVF_MICRO_H - -/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ -#define XSVF_LEGACY_SUCCESS 1 -#define XSVF_LEGACY_ERROR 0 - -/* 4.04 [NEW] Error codes for xsvfExecute. */ -/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ -#define XSVF_ERROR_NONE 0 -#define XSVF_ERROR_UNKNOWN 1 -#define XSVF_ERROR_TDOMISMATCH 2 -#define XSVF_ERROR_MAXRETRIES 3 /* TDO mismatch after max retries */ -#define XSVF_ERROR_ILLEGALCMD 4 -#define XSVF_ERROR_ILLEGALSTATE 5 -#define XSVF_ERROR_DATAOVERFLOW 6 /* Data > lenVal MAX_LEN buffer size*/ -/* Insert new errors here */ -#define XSVF_ERROR_LAST 7 - -/***************************************************************************** -* Function: xsvfExecute -* Description: Process, interpret, and apply the XSVF commands. -* See port.c:readByte for source of XSVF data. -* Parameters: none. -* Returns: int - For error codes see above. -*****************************************************************************/ -extern int xsvfExecute(); - -#endif /* XSVF_MICRO_H */ - diff --git a/utils/temp/ports.cpp b/utils/temp/ports.cpp deleted file mode 100644 index cc55825..0000000 --- a/utils/temp/ports.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*******************************************************/ -/* file: ports.c */ -/* abstract: This file contains the routines to */ -/* output values on the JTAG ports, to read */ -/* the TDO bit, and to read a byte of data */ -/* from the prom */ -/* Revisions: */ -/* 12/01/2008: Same code as before (original v5.01). */ -/* Updated comments to clarify instructions.*/ -/* Add print in setPort for xapp058_example.exe.*/ -/*******************************************************/ -#include "ports.h" -/*#include "prgispx.h"*/ - -#include "stdio.h" -extern FILE *in; -static int g_iTCK = 0; /* For xapp058_example .exe */ -static int g_iTMS = 0; /* For xapp058_example .exe */ -static int g_iTDI = 0; /* For xapp058_example .exe */ - -#include -#include -#include -#include "../../include/pinproc.h" // Include libpinproc's header. -extern PRHandle proc; - -/* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ -/* if in debugging mode, then just set the variables */ -void setPort(short p,short val) -{ - PRJTAGOutputs jtagOutputs; - /* Printing code for the xapp058_example.exe. You must set the specified - JTAG signal (p) to the new value (v). See the above, old Win95 code - as an implementation example. */ - if (p==TMS) - g_iTMS = val; - if (p==TDI) - g_iTDI = val; - if (p==TCK) { - g_iTCK = val; - } - uint32_t buffer[1]; - - // Set up the data and mask bits depending on which bit is being changed. - jtagOutputs.tckMask = p==TCK; - jtagOutputs.tdoMask = p==TDI; - jtagOutputs.tmsMask = p==TMS; - jtagOutputs.tck = g_iTCK; - jtagOutputs.tdo = g_iTDI; - jtagOutputs.tms = g_iTMS; - - //if (p==TMS) buffer[0] = 0xC3000010 | g_iTMS; - //if (p==TDI) buffer[0] = 0xC3000020 | g_iTDI << 1; - //if (p==TCK) buffer[0] = 0xC3000040 | g_iTCK << 2; - //PRWriteData(proc, 1, 0, 1, buffer); - //const uint8_t tckMask = p==TCK; - //const uint8_t tdoMask = p==TDI; - //const uint8_t tmsMask = p==TMS; - PRJTAGDriveOutputs(proc, &jtagOutputs, false); -} - - -// Toggle TCK. -void pulseClock() -{ - setPort(TCK,0); /* set the TCK port to low */ - setPort(TCK,1); /* set the TCK port to high */ -} - - -void readByte(unsigned char *data) -{ - // read in a byte of data from the xsvf file - *data = (unsigned char)fgetc( in ); -} - -unsigned char readTDOBit() -{ - PRJTAGStatus jtagStatus; - - // Read the TDO bit. - // The JTAG module's status register contains the TDO bit. (It's TDI from the - // perspective of the JTAG module.) - PRJTAGGetStatus(proc, &jtagStatus); - - if (jtagStatus.tdi) return ( (unsigned char) 1 ); - return( (unsigned char) 0 ); -} - -void waitTime(long microsec) -{ - long i; - PRJTAGStatus jtagStatus; - // Estimation: each PRReadData request takes approx 2ms. - // Always do at least one. This means the minimum delay time is approx 2ms. - // This makes it impossible for a USB write before and after the delay - // to be squeezed together by USB burst logic. - - // Use the system sleep() if needing a 50ms delay or more due to timing - // error of PRReadData loops adding up. - if ( microsec >= 50000L ) - { - // Make sure TCK is low during wait for XC18V00/XCFxxS - setPort( TCK, 0 ); - - // Read the JTAG status register to exercise the USB bus - PRJTAGGetStatus(proc, &jtagStatus); - - sleep( ( microsec - 2000L ) / 1000000L); - } - else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ - { - - setPort( TCK, 0 ); - - // Always do at least 1 cycle. So minimum delay time is approx 2 ms. - for ( i = 0; i < (microsec-1)/2000 + 1; ++i ) - { - PRJTAGGetStatus(proc, &jtagStatus); - } - //{ - //sleep( ( microsec + 19999L ) / 1000000L ); - //sleep( 1 ); - //pulseClock(); - //} - } -} diff --git a/utils/temp/ports.h b/utils/temp/ports.h deleted file mode 100644 index e09d95e..0000000 --- a/utils/temp/ports.h +++ /dev/null @@ -1,31 +0,0 @@ -/*******************************************************/ -/* file: ports.h */ -/* abstract: This file contains extern declarations */ -/* for providing stimulus to the JTAG ports.*/ -/*******************************************************/ - -#ifndef ports_dot_h -#define ports_dot_h - -/* these constants are used to send the appropriate ports to setPort */ -/* they should be enumerated types, but some of the microcontroller */ -/* compilers don't like enumerated types */ -#define TCK (short) 0 -#define TMS (short) 1 -#define TDI (short) 2 - -/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ -extern void setPort(short p, short val); - -/* read the TDO bit and store it in val */ -extern unsigned char readTDOBit(); - -/* make clock go down->up->down*/ -extern void pulseClock(); - -/* read the next byte of data from the xsvf file */ -extern void readByte(unsigned char *data); - -extern void waitTime(long microsec); - -#endif