home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <conio.h>
- #include <malloc.h>
- #include "jtag.h"
-
-
-
- /* BITSTREAM-HANDLING SUBROUTINES */
-
- /*
- * RTN AllocBits: allocates a bitstream containing at least NumBits.
- */
- bitstream *AllocBits( int NumBits )
- {
- int i, WordLength, NumWords;
- bitstream *bits;
-
- /* compute the number of bitstream words needed to store the
- requested number of bits */
- WordLength = 8 * sizeof(bitstream) / sizeof(char);
- NumWords = (NumBits-1)/WordLength + 1;
-
- /* let's see if we can allocate the bitstream storage */
- if( (bits=NEWV(bitstream, NumWords)) == NULL )
- {
- /* Oops! Guess not! */
- fprintf( stderr, "Out of memory; can't create bitstream\n" );
- assert(0==1); /* this will cause an abort */
- }
-
- /* otherwise, we have the storage so we need to initialize it */
- for( i=0; i<NumWords; i++ )
- bits[i] = 0; /* make it all zeroes */
-
- return( bits ); /* return a pointer to the bitstream storage */
- }
-
- /*
- * RTN FreeBits: free the storage used by a bitstream.
- */
- void FreeBits( bitstream *bits )
- {
- FREE( bits );
- }
-
- /*
- * RTN GetBit: gets the value of a bit from a bitstream.
- */
- unsigned int GetBit( bitstream *bits, int i )
- {
- int WordLength, WordIndex, BitIndex;
-
- /* calculate the number of bits in a bitstream data word
- and use this to calculate what word and bit position in
- that word the requested bit lies in. */
- WordLength = 8 * sizeof(bitstream) / sizeof(char);
- WordIndex = i / WordLength;
- BitIndex = i % WordLength;
-
- /* now get the word and shift it so the requested bit is in the LSB.
- Then mask off the reset and return just a 1 or a 0. */
- return (unsigned int)((bits[WordIndex]>>BitIndex) & 1L);
- }
-
- /*
- * RTN SetBit: sets the value of a bit in a bitstream
- */
- void SetBit( bitstream *bits, int i, int val )
- {
- int WordLength, WordIndex;
- bitstream BitMask;
-
- /* calculate the number of bits in a bitstream data word
- and use this to calculate what word the requested bit lies in
- and to generate a bitmask to mask off that bit. */
- WordLength = 8 * sizeof(bitstream) / sizeof(char);
- WordIndex = i / WordLength;
- BitMask = 1L << (i % WordLength);
-
- /* now use the bitmask to force the requested bit to zero */
- bits[WordIndex] &= ~BitMask;
- /* and then set the requested bit to one if that's needed.
- Otherwise leave it at zero. */
- if( val )
- bits[WordIndex] |= BitMask;
- }
-
- /*
- * RTN CmpBits: mask two bitstreams and then XOR them.
- *
- * This routine compares selected bits of two bitstreams of the same
- * length and places the XOR of them into a result bitstream.
- * Any 1 bits in the result indicate places where the bitstreams differ.
- */
- void CmpBits( int length, bitstream *b1, bitstream *b2,
- bitstream *mask, bitstream *result )
- {
- int i, WordLength, WordIndex, MaxWord;
-
- /* compute the number of bitstream data words in the bitstreams */
- WordLength = 8 * sizeof(bitstream) / sizeof(char);
- MaxWord = (length+WordLength) / WordLength;
-
- /* XOR the bitstreams and store a 1 in the result anywhere the
- two bitstreams differ and the mask is non-zero. */
- for( i=0; i<MaxWord; i++ )
- result[i] = (b1[i] ^ b2[i]) & mask[i];
- }
-
- /*
- * RTN PrintBits: prints a bitstream to the standard output.
- */
- void PrintBits( bitstream *bits, int length )
- {
- int i;
-
- /* start printing with the MSB which is stored at the
- end of the bitstream. Then work your way to the beginning. */
- for( i=length-1; i>=0; i-- )
- printf( "%c", GetBit(bits,i) ? '1':'0' );
- printf( "\n" );
- }
-
-
-
- /* LOW-LEVEL PRINTER PORT SUBROUTINES */
-
- /* We have to store the value we are currently outputing
- through the parallel port since we can't reliably read it back. */
- static int OutPortValue=0xffff;
-
- /* We may want to delay the transitions of signals through the
- printer port if we are going too fast for reliable data transfer. */
- static int PortDelay=0; /* start off with the maximum speed */
-
- /* Here we will store the output and input addresses for the printer port. */
- static int OutPort=0; /* the 0 address will alert us that these */
- static int InPort =0; /* addresses are not initialized yet */
-
- /*
- * RTN SelectPort: select the printer port the JTAG signals go thru.
- *
- * Pass in either 1, 2, or 3 since most PCs support up to three
- * printer ports. The subroutine will warn you if you pick a
- * non-existent port.
- */
- void SelectPort( int PortNum )
- {
- int PortAddresses[4]; /* storage for the printer port addresses */
-
- PortAddresses[3] = 0; /* store a dummy, non-existent port address
- in the final location of the array */
-
- if( PortNum<1 || PortNum>3 )
- PortNum = 4; /* invalid port #, so set to dummy port # */
-
- /* get the parallel port addresses stored in memory
- starting at memory address 0x408 and move them to the
- PortAddresses array. Move the only the first six bytes so the final
- entry in PortAddresses will still be zero. */
- _asm{
- mov ax,0x0
- mov es,ax
- mov bx,es:0x408
- mov PortAddresses[0],bx
- mov bx,es:0x40a
- mov PortAddresses[2],bx
- mov bx,es:0x40c
- mov PortAddresses[4],bx
- }
-
- /* now get the port I/O address for the requested printer port # */
- OutPort = PortAddresses[PortNum-1];
- InPort = OutPort+1; /* the input address is always at the
- output address + 1 */
-
- /* the requested printer port doesn't exist if the
- port address is 0 */
- if( OutPort==0 )
- {
- fprintf( stderr, "The requested printer port does not exist!\n" );
- assert(0==1);
- }
- }
-
- /*
- * RTN PortWait: delay for letting the output port signals settle.
- */
- void PortWait( void )
- {
- int i;
- for( i=PortDelay; i>0; i-- ) ;
- }
-
- /*
- * RTN SetPortDelay: sets the time for letting the printer port settle.
- */
- void SetPortDelay( int delay )
- {
- PortDelay = delay;
- }
-
- /*
- * RTN OutToPort: output a value to the selected printer port.
- */
- void OutToPort( int val )
- {
- /* if a valid printer port has not been selected, then we'll
- select printer port 1 by default */
- if( OutPort==0 )
- SelectPort(1);
-
- /* output the value to the printer port and save the value
- that is being put out */
- outp( OutPort, val );
- OutPortValue = val;
-
- /* {
- bitstream b = OutPortValue;
- PrintBits( &b, 32 );
- } */
-
- /* insert a delay after the output value is changed */
- PortWait();
- }
-
- /*
- * RTN GetOutportValue: get the value currently being output on the
- * printer port.
- */
- int GetOutPortValue( void )
- {
- return OutPortValue;
- }
-
- /*
- * RTN InFromPort: return a value from the selected printer port.
- */
- int InFromPort( void )
- {
- /* if a valid printer port has not been selected, then we'll
- select printer port 1 by default */
- if( InPort==0 )
- SelectPort(1);
-
- /* read the value from the status portion of the selected
- printer port and return it */
- return( inp( InPort) );
- }
-
-
- /* TAP INTERFACE SUBROUTINES */
-
- /* PC parallel port assignments to TAP pins */
- /* Remember! TDO is the bit we put OUT from the PC printer port
- to the TDI pin of the attached chip. TDI is the bit we read
- IN from the TDO pin of the attached chip. In other words, the
- names refer to the simulated TAP of the PC printer port, not to
- the TAP of the attached chip. */
- #define TCKBIT 0
- #define TMSBIT 1
- #define TDOBIT 6
- #define TDIBIT 7
-
- /*
- * RTN SetPortBit: sets a bit of the port to a given value
- */
- void SetPortBit( int bit, int val )
- {
- /* create a masking pattern for the bit */
- unsigned int mask = 1<<bit;
-
- /* set the bit value to 0 */
- int NewValue = GetOutPortValue() & ~mask;
-
- /* now set it to 1 if the val is non-zero */
- if( val )
- NewValue |= mask;
-
- /* now output the updated port value */
- OutToPort( NewValue );
- }
-
- /*
- * RTN GetPortBit: gets the value (0 or 1) of a bit of the port.
- */
- unsigned int GetPortBit( int bit )
- {
- return (GetOutPortValue()>>bit) & 1;
- }
-
- /*
- * RTN SetTMSValue: sets the value of the TMS bit on the TAP.
- */
- void SetTMSValue( int val )
- {
- SetPortBit( TMSBIT, val );
- }
-
- /*
- * RTN GetTMSValue: returns the value of the TMS bit on the TAP.
- */
- unsigned int GetTMSValue( void )
- {
- return GetPortBit( TMSBIT );
- }
-
- /*
- * RTN SetTDOValue: sets the value of the TDO bit on the JTAG port.
- */
- void SetTDOValue( int val )
- {
- SetPortBit( TDOBIT, val );
- }
-
- /*
- * RTN GetTDOValue: gets the value of the TDO bit on the JTAG Port
- */
- unsigned int GetTDOValue( void )
- {
- return GetPortBit( TDOBIT );
- }
-
- /*
- * RTN GetTDIValue: gets the value of the TDI bit from the input port
- * which is fed from the TDO bit of the TAP port of the
- * attached chip.
- */
- unsigned int GetTDIValue( void )
- {
- return ((InFromPort()>>TDIBIT) & 1) ^ 1;
- }
-
- /*
- * RTN GetTCKValue: gets the value of the TCK bit on the output port.
- */
- unsigned int GetTCKValue( void )
- {
- return GetPortBit( TCKBIT );
- }
-
- /*
- * RTN SetTCKValue: sets the value of the TCK bit on the output port.
- */
- void SetTCKValue( int val )
- {
- SetPortBit( TCKBIT, val );
- }
-
- /*
- * RTN JTAGTraceOnOff: enables/disables the trace of TAP signals coming
- * out the printer port.
- */
- static int JTAGTraceFlag = 0; /* start up with trace disabled */
- JTAGTraceOnOff( int OnOff )
- {
- JTAGTraceFlag = OnOff;
- }
-
- /*
- * RTN PulseTCK: put a pulse on the TCK pin by toggling TCK twice.
- */
- char *GetTAPStateText(); /* a declaration so we can use this routine */
- void PulseTCK( void )
- {
- /* get the original value of TCK */
- int OldTCK = GetTCKValue();
-
- if( JTAGTraceFlag )
- printf( "%s\t%1d %1d %1d\n", GetTAPStateText(),
- GetTMSValue(), GetTDOValue(), GetTDIValue() );
-
- /* now toggle it to its opposite value ... */
- SetTCKValue( OldTCK ^ 1 );
- /* and then return it to its original value */
- SetTCKValue( OldTCK );
-
- /* now make a check that TCK is 0. This is the normal
- quiescent value for our system. */
- assert( OldTCK==0 );
- }
-
- /*
- * RTN JTAGPortInit: initialize the JTAG port output value.
- */
- void JTAGPortInit( void )
- {
- SetTMSValue(1);
- SetTCKValue(0);
- HardTAPReset();
- }
-
-
-
- /* TAP CONTROLLER TRANSITION SUBROUTINES */
-
- /* TAP controller state definitions */
- typedef enum
- {
- TestLogicReset, RunTestIdle,
- SelectDRScan, SelectIRScan,
- CaptureDR, CaptureIR,
- ShiftDR, ShiftIR,
- Exit1DR, Exit1IR,
- PauseDR, PauseIR,
- Exit2DR, Exit2IR,
- UpdateDR, UpdateIR
- } JTAGState;
-
- #define NumTAPStates 16 /* number of TAP controller states */
-
- /* This variable records the current state of TAP controller */
- static JTAGState CurrentTAPState = TestLogicReset;
-
- /* The following array stores the transition table for the TAP
- controller. It tells us what the next state will be by placing the
- current state code in the first index and the value of
- the TMS input in the second index. */
- static JTAGState NextTAPState[NumTAPStates][2] =
- {
- /* TMS=0 */ /* TMS=1 */ /* current TAP state */
- { RunTestIdle, TestLogicReset }, /* TestLogicReset */
- { RunTestIdle, SelectDRScan }, /* RunTestIdle */
- { CaptureDR, SelectIRScan }, /* SelectDRScan */
- { CaptureIR, TestLogicReset }, /* SelectIRScan */
- { ShiftDR, Exit1DR }, /* CaptureDR */
- { ShiftIR, Exit1IR }, /* CaptureIR */
- { ShiftDR, Exit1DR }, /* ShiftDR */
- { ShiftIR, Exit1IR }, /* ShiftIR */
- { PauseDR, UpdateDR }, /* Exit1DR */
- { PauseIR, UpdateIR }, /* Exit1IR */
- { PauseDR, Exit2DR }, /* PauseDR */
- { PauseIR, Exit2IR }, /* PauseIR */
- { ShiftDR, UpdateDR }, /* Exit2DR */
- { ShiftIR, UpdateIR }, /* Exit2IR */
- { RunTestIdle, SelectDRScan }, /* UpdateDR */
- { RunTestIdle, SelectDRScan }, /* UpdateIR */
- };
-
- /*
- * RTN TAPStateToText: converts the TAP controller state into its
- * textual name.
- */
- char *TAPStateToText( JTAGState TAPState )
- {
- switch( TAPState )
- {
- case TestLogicReset: return "Test-Logic-Reset";
- case RunTestIdle: return "Run-Test/Idle";
- case SelectDRScan: return "Select_DR-Scan";
- case SelectIRScan: return "Select_IR-Scan";
- case CaptureDR: return "Capture-DR";
- case CaptureIR: return "Capture-IR";
- case ShiftDR: return "Shift-DR";
- case ShiftIR: return "Shift-IR";
- case Exit1DR: return "Exit1-DR";
- case Exit1IR: return "Exit1-IR";
- case PauseDR: return "Pause-DR";
- case PauseIR: return "Pause-IR";
- case Exit2DR: return "Exit2-DR";
- case Exit2IR: return "Exit2-IR";
- case UpdateDR: return "Update-DR";
- default:
- case UpdateIR: return "Update-IR";
- }
- }
-
- /*
- * RTN HardTAPReset: guarantees the TAP controller is in
- * Test-Logic-Reset state.
- */
- void HardTAPReset( void )
- {
- CurrentTAPState = TestLogicReset;
-
- /* the TAP controller will always be reset by raising TMS to 1
- and then pulsing the TCK five times */
- SetTMSValue(1);
- PulseTCK();
- PulseTCK();
- PulseTCK();
- PulseTCK();
- PulseTCK();
- }
-
- /*
- * RTN UpdateTAPState: use the current TAP controller state and TMS
- * bit to compute the next TAP controller state.
- *
- * This routine keeps the copy of the TAP controller state in the
- * program up-to-date with the TAP controller state in the chip
- * (we hope).
- */
- void UpdateTAPState( void )
- {
- CurrentTAPState = NextTAPState[ CurrentTAPState ][ GetTMSValue() ];
- }
-
- char *GetTAPStateText( void )
- {
- return TAPStateToText(CurrentTAPState);
- }
-
- /*
- * RTN GotoNextTAPState: sets the TMS line to the appropriate value
- * such that the next TCK pulse will move the TAP controller
- * to the requested NextState.
- *
- * If the new state of the TAP controller doesn't match the requested
- * state, the subroutine will cause the program to abort.
- */
- char *TAPStateToText( JTAGState s );
-
- void GotoNextTAPState( JTAGState NextState )
- {
- /* determine the correct TMS value to move to the desired state */
- if( NextTAPState[CurrentTAPState][0] == NextState )
- SetTMSValue(0);
- else /* ( NextTAPState[CurrentTAPState][1] == NextState ) */
- SetTMSValue(1);
-
- /* now transition the chip TAP controller to the new state */
- PulseTCK();
-
- /* update the internal copy of the TAP controller state */
- UpdateTAPState();
-
- /* check to make sure the current state matches what was requested */
- assert( CurrentTAPState==NextState );
- }
-
- /*
- * RTN GoThruTAPSequence: moves through a sequence of TAP controller states.
- *
- * The desired TAP controller state sequences is entered as an argument
- * string terminated with a -1.
- */
- void GoThruTAPSequence( JTAGState NextState, ... )
- {
- /* progress through the states until a -1 is seen */
- va_list ap;
- for( va_start(ap,NextState); NextState != -1;
- NextState=va_arg(ap,JTAGState) )
- GotoNextTAPState( NextState );
- va_end( ap );
- }
-
-
-
- /* BSDR and BSIR INPUT/OUTPUT SUBROUTINES */
-
- /*
- * RTN SendRcvBit: get the current bit from TDI, send a bit through TDO,
- * and pulse TCLK.
- *
- * This subroutine assumes that the TCK is 0 and the TAP controller state
- * is Shift-DR or Shift-IR upon entry. That's why we pick up the value
- * coming in through TDI right away.
- */
- unsigned int SendRcvBit( unsigned SendBit )
- {
- unsigned int TDIValue;
-
- /* Make sure we are in the Shift-IR or Shift-DR state. Gathering
- and shifting out data isn't legal otherwise. */
- assert( CurrentTAPState==ShiftIR || CurrentTAPState==ShiftDR );
-
- /* get the value on the TDI input when TCK is low */
- TDIValue = GetTDIValue();
-
- /* now output the specified value on TDO */
- SetTDOValue( SendBit & 1 );
-
- /* pulse TCK to move the BSIR or BSDR by one bit */
- PulseTCK(); /* clock goes high then low */
-
- /* update the current TAP controller state */
- UpdateTAPState();
-
- /* return the value we captured off TDI */
- return TDIValue;
- }
-
- /*
- * RTN SendRcvBitstream: transmit a bitstream through TDO while receiving
- * a bitstream through TDI.
- *
- * This subroutine assumes the TAP controller state is
- * Shift-IR or Shift-DR upon entry. Upon termination, this subroutine
- * will leave the TAP controller in the Exit1-IR or Exit1-DR state.
- *
- * Either SendBits or RcvBits can be NULL if you don't want to transmit
- * or receive bits during a particular call to this subroutine.
- * For example, you may want to load the BSDR with a bit pattern but
- * you might not care what data gets shifted out of the BSDR during
- * the loading.
- *
- * SendBits and RcvBits can point to the same bitstream without
- * causing problems.
- *
- * Note that the LSB of a bitstream has an index of 0.
- */
- void SendRcvBitstream( int length, bitstream *SendBits, bitstream *RcvBits )
- {
- int i, j, WordLength, NumWords;
- bitstream SendWord;
-
- /* compute the number of words in the bitstream */
- WordLength = 8 * sizeof(bitstream)/sizeof(char);
-
- /* it's nonsense to operate on a zero-length bitstream, so
- abort if that's the case. */
- assert( length>0 );
-
- /* lower the TMS line to make sure the TAP controller stays
- in the Shift-IR or Shift-DR state for the first length-1 cycles */
- SetTMSValue(0);
-
- for( i=0; i<length; i++ )
- {
- unsigned int sendbit, rcvbit;
-
- /* On the last bit, raise the TMS line so the TAP
- controller will move out of the Shift state into
- the Exit1 state. */
- if( i==length-1 )
- SetTMSValue(1);
-
- /* send the next bit if the bitstream is not NULL ... */
- if( SendBits!=NULL )
- rcvbit = SendRcvBit(GetBit(SendBits,i));
- /* else just shift in a zero */
- else
- rcvbit = SendRcvBit(0);
-
- /* store the received bit if the bitstream is not NULL */
- if( RcvBits!=NULL )
- SetBit( RcvBits, i, rcvbit );
- }
- }
-
- /*
- * RTN LoadBSIRthenBSDR: load the BSIR, execute the instruction, and
- * then capture and reload the BSDR.
- *
- * This subroutine assumes the TAP controller is in the Test-Logic-Reset
- * or Run-Test/Idle state upon entry. The TAP controller is returned to the
- * Run-Test/Idle state upon exit.
- */
- void LoadBSIRthenBSDR( int BSIRLength, bitstream *instruction,
- int BSDRLength, bitstream *send, bitstream *recv )
- {
- /* move the TAP controller from the Test-Logic-Reset or
- Run-Test/Idle state to the Shift-IR state */
- GoThruTAPSequence( RunTestIdle, SelectDRScan,
- SelectIRScan, CaptureIR, ShiftIR, -1 );
-
- /* now load the opcode instruction into the BSIR and
- enter the Exit1-IR state when this is done */
- SendRcvBitstream( BSIRLength, instruction, NULL );
-
- /* now activate the instruction by entering the Update-IR state. */
- GoThruTAPSequence( UpdateIR, -1 );
-
- /* if the BSDR length is non-zero, then select the BSDR by moving
- into the Capture-DR state so that the new pin data is
- parallel-loaded into the BSDR. Then move into the
- Shift-DR state so that the captured data can be shifted out
- while a new pattern is shifted in. Finally, output the
- newly loaded data onto the parallel output of the BSDR by moving
- into the Update-DR state. */
- if( BSDRLength > 0 )
- {
- GoThruTAPSequence( SelectDRScan, CaptureDR, ShiftDR, -1 );
-
- /* now shift out the captured data while
- new data is shifted in */
- SendRcvBitstream( BSDRLength, send, recv );
-
- /* output the freshly loaded data onto the parallel output
- of the BSDR */
- GoThruTAPSequence( UpdateDR, -1 );
- }
-
- /* return to the idle state */
- GoThruTAPSequence( RunTestIdle, -1 );
- }
-
-
-
- /* EPX780 JTAG INSTRUCTION SUBROUTINES */
-
- /* JTAG public instruction opcodes for the EPX780 FPGA */
- typedef enum
- {
- EXTEST = 0, /* drives outputs with pre-loaded data */
- SAMPLE = 1, /* read current pins; pre-load next pin state */
- IDCODE = 2, /* read manufacturers ID code */
- LDVECT = 5, /* load vector into PROGRAM shift register */
- FREAD = 6, /* read EPROM */
- SWRITE = 15, /* write SRAM */
- SREAD = 16, /* read SRAM */
- PORST = 20, /* power-on reset; restarts device architecture */
- FPGM = 21, /* program EPROM */
- HIGHZ = 29, /* 3-state all outputs */
- UESCODE = 22, /* shift out user-defined electronic signature code */
- RADLOAD = 24, /* load row address */
- ISCAN = 30, /* internal scan of device */
- BYPASS = 31 /* bypass the device JTAG mechanism */
- } EPX780JTAGOpcode;
-
- #define EPX780OpcodeLength 5 /* the bit length of the EPX780 JTAG opcodes */
- #define EPX780IDCodeLength 32 /* Device ID code register length */
- #define EPX780BSDRLength 264 /* boundary-scan data register length */
- #define EPX780UESLength 600 /* user-electronic-signature register length */
-
- /*
- * RTN EPX780IDCode: read the manufacturer's Device ID code.
- *
- * The ID code is stored into the memory pointed to by DeviceIDCode.
- */
- void EPX780IDCode( bitstream *DeviceIDCode )
- {
- bitstream instr = IDCODE;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
- EPX780IDCodeLength, NULL, DeviceIDCode );
- }
-
- /*
- * RTN EPX780UES: read the user-loaded User Electronic Signature.
- *
- * The signature is stored into the memory pointed to by UESig.
- */
- void EPX780UES( bitstream *UESig )
- {
- bitstream instr = UESCODE;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
- EPX780UESLength, NULL, UESig );
- }
-
- /*
- * RTN EPX780SamplePreload: read current pin state and preload next state.
- *
- * The BSDR is loaded with the data pointed to by send and the sampled pin
- * values shifted out of the BSDR are stored into the memory pointed to
- * by recv.
- */
- void EPX780SamplePreload( bitstream *send, bitstream *recv )
- {
- bitstream instr = SAMPLE;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
- EPX780BSDRLength, send, recv );
- }
-
- /*
- * RTN EPX780Extest: drive outputs with preloaded data.
- *
- * The BSDR is loaded with the new pin values pointed to by send and the
- * old pin values shifted out of the BSDR are stored into the memory
- * pointed to by recv.
- */
- void EPX780Extest( bitstream *send, bitstream *recv )
- {
- bitstream instr = EXTEST;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr,
- EPX780BSDRLength, send, recv );
- }
-
- /*
- * RTN EPX780HighZ: tristate all the outputs.
- */
- void EPX780HighZ(void)
- {
- bitstream instr = HIGHZ;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr, 0, NULL, NULL );
- }
-
- /*
- * RTN EPX780Bypass: bypass the data register.
- */
- void EPX780Bypass(void)
- {
- bitstream instr = BYPASS;
-
- LoadBSIRthenBSDR( EPX780OpcodeLength, &instr, 0, NULL, NULL );
- }
-
-
- /* EPX780 JTAG BSDR ASSIGNMENTS */
-
- /*
- * The following enumeration is the order of the scan cells in the
- * BSDR for the EPX780 FPGA (both 84-pin and 132-pin versions).
- * We got this from the I780_84.BSD file included with PLDshell.
- * The list starts with the LSB and ends with the MSB of the scan path.
- * Each macrocell scan cell has three bits associated with it: an
- * OE cell which enables the tristate buffer when set to 1, an OUT cell
- * whose value is output on the pin when the tristate buffer is enabled,
- * and an IN cell which captures the value placed on the pin.
- * The CLK1 and CLK2 scan cells are able to capture the values on the clock
- * inputs. The IN0..IN21 scan cells can capture the values on the
- * dedicated inputs, but these inputs exist only on the 132-pin
- * version of the EPX780, not on the 84-pin version.
- */
- typedef enum {
- IO09OE, IO09OUT, IO09IN,
- IO08OE, IO08OUT, IO08IN,
- IO07OE, IO07OUT, IO07IN,
- IO06OE, IO06OUT, IO06IN,
- IO05OE, IO05OUT, IO05IN,
- IO04OE, IO04OUT, IO04IN,
- IO03OE, IO03OUT, IO03IN,
- IO02OE, IO02OUT, IO02IN,
- IO01OE, IO01OUT, IO01IN,
- IO00OE, IO00OUT, IO00IN,
- CLK1,
- IO10OE, IO10OUT, IO10IN,
- IO11OE, IO11OUT, IO11IN,
- IO12OE, IO12OUT, IO12IN,
- IO13OE, IO13OUT, IO13IN,
- IO14OE, IO14OUT, IO14IN,
- IO15OE, IO15OUT, IO15IN,
- IO16OE, IO16OUT, IO16IN,
- IO17OE, IO17OUT, IO17IN,
- IO18OE, IO18OUT, IO18IN,
- IO19OE, IO19OUT, IO19IN,
- IN0, IN1, IN2, IN3, IN4, IN5,
- IO39OE, IO39OUT, IO39IN,
- IO38OE, IO38OUT, IO38IN,
- IO37OE, IO37OUT, IO37IN,
- IO36OE, IO36OUT, IO36IN,
- IO35OE, IO35OUT, IO35IN,
- IO34OE, IO34OUT, IO34IN,
- IO33OE, IO33OUT, IO33IN,
- IO32OE, IO32OUT, IO32IN,
- IO31OE, IO31OUT, IO31IN,
- IO30OE, IO30OUT, IO30IN,
- IO50OE, IO50OUT, IO50IN,
- IO51OE, IO51OUT, IO51IN,
- IO52OE, IO52OUT, IO52IN,
- IO53OE, IO53OUT, IO53IN,
- IO54OE, IO54OUT, IO54IN,
- IO55OE, IO55OUT, IO55IN,
- IO56OE, IO56OUT, IO56IN,
- IO57OE, IO57OUT, IO57IN,
- IO58OE, IO58OUT, IO58IN,
- IO59OE, IO59OUT, IO59IN,
- IN6, IN7, IN8, IN9, IN10,
- IO79OE, IO79OUT, IO79IN,
- IO78OE, IO78OUT, IO78IN,
- IO77OE, IO77OUT, IO77IN,
- IO76OE, IO76OUT, IO76IN,
- IO75OE, IO75OUT, IO75IN,
- IO74OE, IO74OUT, IO74IN,
- IO73OE, IO73OUT, IO73IN,
- IO72OE, IO72OUT, IO72IN,
- IO71OE, IO71OUT, IO71IN,
- IO70OE, IO70OUT, IO70IN,
- CLK2,
- IO60OE, IO60OUT, IO60IN,
- IO61OE, IO61OUT, IO61IN,
- IO62OE, IO62OUT, IO62IN,
- IO63OE, IO63OUT, IO63IN,
- IO64OE, IO64OUT, IO64IN,
- IO65OE, IO65OUT, IO65IN,
- IO66OE, IO66OUT, IO66IN,
- IO67OE, IO67OUT, IO67IN,
- IO68OE, IO68OUT, IO68IN,
- IO69OE, IO69OUT, IO69IN,
- IN11, IN12, IN13, IN14, IN15, IN16,
- IO49OE, IO49OUT, IO49IN,
- IO48OE, IO48OUT, IO48IN,
- IO47OE, IO47OUT, IO47IN,
- IO46OE, IO46OUT, IO46IN,
- IO45OE, IO45OUT, IO45IN,
- IO44OE, IO44OUT, IO44IN,
- IO43OE, IO43OUT, IO43IN,
- IO42OE, IO42OUT, IO42IN,
- IO41OE, IO41OUT, IO41IN,
- IO40OE, IO40OUT, IO40IN,
- IO20OE, IO20OUT, IO20IN,
- IO21OE, IO21OUT, IO21IN,
- IO22OE, IO22OUT, IO22IN,
- IO23OE, IO23OUT, IO23IN,
- IO24OE, IO24OUT, IO24IN,
- IO25OE, IO25OUT, IO25IN,
- IO26OE, IO26OUT, IO26IN,
- IO27OE, IO27OUT, IO27IN,
- IO28OE, IO28OUT, IO28IN,
- IO29OE, IO29OUT, IO29IN,
- IN17, IN18, IN19, IN20, IN21
- } EPX780ScanPosition;
-
-
- /*
- * The following array lets us recall the names for each scan cell in the
- * EPX780 BSDR.
- */
- static char *EPX780ScanPosNames[] = {
- "IO09OE", "IO09OUT", "IO09IN",
- "IO08OE", "IO08OUT", "IO08IN",
- "IO07OE", "IO07OUT", "IO07IN",
- "IO06OE", "IO06OUT", "IO06IN",
- "IO05OE", "IO05OUT", "IO05IN",
- "IO04OE", "IO04OUT", "IO04IN",
- "IO03OE", "IO03OUT", "IO03IN",
- "IO02OE", "IO02OUT", "IO02IN",
- "IO01OE", "IO01OUT", "IO01IN",
- "IO00OE", "IO00OUT", "IO00IN",
- "CLK1",
- "IO10OE", "IO10OUT", "IO10IN",
- "IO11OE", "IO11OUT", "IO11IN",
- "IO12OE", "IO12OUT", "IO12IN",
- "IO13OE", "IO13OUT", "IO13IN",
- "IO14OE", "IO14OUT", "IO14IN",
- "IO15OE", "IO15OUT", "IO15IN",
- "IO16OE", "IO16OUT", "IO16IN",
- "IO17OE", "IO17OUT", "IO17IN",
- "IO18OE", "IO18OUT", "IO18IN",
- "IO19OE", "IO19OUT", "IO19IN",
- "IN0", "IN1", "IN2", "IN3", "IN4", "IN5",
- "IO39OE", "IO39OUT", "IO39IN",
- "IO38OE", "IO38OUT", "IO38IN",
- "IO37OE", "IO37OUT", "IO37IN",
- "IO36OE", "IO36OUT", "IO36IN",
- "IO35OE", "IO35OUT", "IO35IN",
- "IO34OE", "IO34OUT", "IO34IN",
- "IO33OE", "IO33OUT", "IO33IN",
- "IO32OE", "IO32OUT", "IO32IN",
- "IO31OE", "IO31OUT", "IO31IN",
- "IO30OE", "IO30OUT", "IO30IN",
- "IO50OE", "IO50OUT", "IO50IN",
- "IO51OE", "IO51OUT", "IO51IN",
- "IO52OE", "IO52OUT", "IO52IN",
- "IO53OE", "IO53OUT", "IO53IN",
- "IO54OE", "IO54OUT", "IO54IN",
- "IO55OE", "IO55OUT", "IO55IN",
- "IO56OE", "IO56OUT", "IO56IN",
- "IO57OE", "IO57OUT", "IO57IN",
- "IO58OE", "IO58OUT", "IO58IN",
- "IO59OE", "IO59OUT", "IO59IN",
- "IN6", "IN7", "IN8", "IN9", "IN10",
- "IO79OE", "IO79OUT", "IO79IN",
- "IO78OE", "IO78OUT", "IO78IN",
- "IO77OE", "IO77OUT", "IO77IN",
- "IO76OE", "IO76OUT", "IO76IN",
- "IO75OE", "IO75OUT", "IO75IN",
- "IO74OE", "IO74OUT", "IO74IN",
- "IO73OE", "IO73OUT", "IO73IN",
- "IO72OE", "IO72OUT", "IO72IN",
- "IO71OE", "IO71OUT", "IO71IN",
- "IO70OE", "IO70OUT", "IO70IN",
- "CLK2",
- "IO60OE", "IO60OUT", "IO60IN",
- "IO61OE", "IO61OUT", "IO61IN",
- "IO62OE", "IO62OUT", "IO62IN",
- "IO63OE", "IO63OUT", "IO63IN",
- "IO64OE", "IO64OUT", "IO64IN",
- "IO65OE", "IO65OUT", "IO65IN",
- "IO66OE", "IO66OUT", "IO66IN",
- "IO67OE", "IO67OUT", "IO67IN",
- "IO68OE", "IO68OUT", "IO68IN",
- "IO69OE", "IO69OUT", "IO69IN",
- "IN11", "IN12", "IN13", "IN14", "IN15", "IN16",
- "IO49OE", "IO49OUT", "IO49IN",
- "IO48OE", "IO48OUT", "IO48IN",
- "IO47OE", "IO47OUT", "IO47IN",
- "IO46OE", "IO46OUT", "IO46IN",
- "IO45OE", "IO45OUT", "IO45IN",
- "IO44OE", "IO44OUT", "IO44IN",
- "IO43OE", "IO43OUT", "IO43IN",
- "IO42OE", "IO42OUT", "IO42IN",
- "IO41OE", "IO41OUT", "IO41IN",
- "IO40OE", "IO40OUT", "IO40IN",
- "IO20OE", "IO20OUT", "IO20IN",
- "IO21OE", "IO21OUT", "IO21IN",
- "IO22OE", "IO22OUT", "IO22IN",
- "IO23OE", "IO23OUT", "IO23IN",
- "IO24OE", "IO24OUT", "IO24IN",
- "IO25OE", "IO25OUT", "IO25IN",
- "IO26OE", "IO26OUT", "IO26IN",
- "IO27OE", "IO27OUT", "IO27IN",
- "IO28OE", "IO28OUT", "IO28IN",
- "IO29OE", "IO29OUT", "IO29IN",
- "IN17", "IN18", "IN19", "IN20", "IN21"
- };
-
- /*
- * The following array gives the positions in the BSDR bitstream for
- * all the macrocell scan cells. Each macrocell is a bidirectional I/O
- * pin and so has three associated scan cells: one for controlling the
- * tristate buffer, one for output, and one for input. You can get the
- * position of any macrocell scan cell in the BSDR by indexing this array
- * with the index of the macrocell and the index of the output enable, output,
- * or input cell you want.
- */
- #define OE 0 /* first column lists tristate control scan cell positions */
- #define OUT 1 /* next column lists output scan cell positions */
- #define IN 2 /* last column lists input scan cell positions */
-
- int EPX780MacrocellPosition[][3] =
- {
- /* CFB 0 macrocells */
- { IO00OE, IO00OUT, IO00IN },
- { IO01OE, IO01OUT, IO01IN },
- { IO02OE, IO02OUT, IO02IN },
- { IO03OE, IO03OUT, IO03IN },
- { IO04OE, IO04OUT, IO04IN },
- { IO05OE, IO05OUT, IO05IN },
- { IO06OE, IO06OUT, IO06IN },
- { IO07OE, IO07OUT, IO07IN },
- { IO08OE, IO08OUT, IO08IN },
- { IO09OE, IO09OUT, IO09IN },
- /* CFB 1 macrocells */
- { IO10OE, IO10OUT, IO10IN },
- { IO11OE, IO11OUT, IO11IN },
- { IO12OE, IO12OUT, IO12IN },
- { IO13OE, IO13OUT, IO13IN },
- { IO14OE, IO14OUT, IO14IN },
- { IO15OE, IO15OUT, IO15IN },
- { IO16OE, IO16OUT, IO16IN },
- { IO17OE, IO17OUT, IO17IN },
- { IO18OE, IO18OUT, IO18IN },
- { IO19OE, IO19OUT, IO19IN },
- /* CFB 2 macrocells */
- { IO20OE, IO20OUT, IO20IN },
- { IO21OE, IO21OUT, IO21IN },
- { IO22OE, IO22OUT, IO22IN },
- { IO23OE, IO23OUT, IO23IN },
- { IO24OE, IO24OUT, IO24IN },
- { IO25OE, IO25OUT, IO25IN },
- { IO26OE, IO26OUT, IO26IN },
- { IO27OE, IO27OUT, IO27IN },
- { IO28OE, IO28OUT, IO28IN },
- { IO29OE, IO29OUT, IO29IN },
- /* CFB 3 macrocells */
- { IO30OE, IO30OUT, IO30IN },
- { IO31OE, IO31OUT, IO31IN },
- { IO32OE, IO32OUT, IO32IN },
- { IO33OE, IO33OUT, IO33IN },
- { IO34OE, IO34OUT, IO34IN },
- { IO35OE, IO35OUT, IO35IN },
- { IO36OE, IO36OUT, IO36IN },
- { IO37OE, IO37OUT, IO37IN },
- { IO38OE, IO38OUT, IO38IN },
- { IO39OE, IO39OUT, IO39IN },
- /* CFB 4 macrocells */
- { IO40OE, IO40OUT, IO40IN },
- { IO41OE, IO41OUT, IO41IN },
- { IO42OE, IO42OUT, IO42IN },
- { IO43OE, IO43OUT, IO43IN },
- { IO44OE, IO44OUT, IO44IN },
- { IO45OE, IO45OUT, IO45IN },
- { IO46OE, IO46OUT, IO46IN },
- { IO47OE, IO47OUT, IO47IN },
- { IO48OE, IO48OUT, IO48IN },
- { IO49OE, IO49OUT, IO49IN },
- /* CFB 5 macrocells */
- { IO50OE, IO50OUT, IO50IN },
- { IO51OE, IO51OUT, IO51IN },
- { IO52OE, IO52OUT, IO52IN },
- { IO53OE, IO53OUT, IO53IN },
- { IO54OE, IO54OUT, IO54IN },
- { IO55OE, IO55OUT, IO55IN },
- { IO56OE, IO56OUT, IO56IN },
- { IO57OE, IO57OUT, IO57IN },
- { IO58OE, IO58OUT, IO58IN },
- { IO59OE, IO59OUT, IO59IN },
- /* CFB 6 macrocells */
- { IO60OE, IO60OUT, IO60IN },
- { IO61OE, IO61OUT, IO61IN },
- { IO62OE, IO62OUT, IO62IN },
- { IO63OE, IO63OUT, IO63IN },
- { IO64OE, IO64OUT, IO64IN },
- { IO65OE, IO65OUT, IO65IN },
- { IO66OE, IO66OUT, IO66IN },
- { IO67OE, IO67OUT, IO67IN },
- { IO68OE, IO68OUT, IO68IN },
- { IO69OE, IO69OUT, IO69IN },
- /* CFB 7 macrocells */
- { IO70OE, IO70OUT, IO70IN },
- { IO71OE, IO71OUT, IO71IN },
- { IO72OE, IO72OUT, IO72IN },
- { IO73OE, IO73OUT, IO73IN },
- { IO74OE, IO74OUT, IO74IN },
- { IO75OE, IO75OUT, IO75IN },
- { IO76OE, IO76OUT, IO76IN },
- { IO77OE, IO77OUT, IO77IN },
- { IO78OE, IO78OUT, IO78IN },
- { IO79OE, IO79OUT, IO79IN },
- };
-
- /*
- * This is similar to the previous array. It lets you get the position
- * in the BSDR for the scan cells associated with the clock inputs.
- */
- int EPX780ClockPosition[] =
- {
- -1, CLK1, CLK2
- };
-
- /*
- * This is similar to the previous arrays. It lets you get the position
- * in the BSDR for the scan cells associated with the dedicated inputs.
- */
- int EPX780InputPosition[] =
- {
- IN0, IN1, IN2, IN3, IN4, IN5, IN6, IN7, IN8, IN9,
- IN10, IN11, IN12, IN13, IN14, IN15, IN16, IN17, IN18, IN19,
- IN20, IN21
- };
-
-
- /*
- * RTN SetMacrocellDirection: sets the given macrocell (0..79) to be
- * an output (dir=1) or an input (dir=0).
- */
- void SetMacrocellDirection( bitstream *bsdr, int macrocell, int dir )
- {
- SetBit( bsdr, EPX780MacrocellPosition[macrocell][OE], dir );
- }
-
- /*
- * RTN GetMacrocellDirection: returns the IO setting for the macrocell.
- */
- int GetMacrocellDirection( bitstream *bsdr, int macrocell )
- {
- return GetBit( bsdr, EPX780MacrocellPosition[macrocell][OE] );
- }
-
- /*
- * RTN SetMacrocellOutput: sets the value stored in the output cell of
- * the BSDR for the given macrocell (0..79).
- */
- void SetMacrocellOutput( bitstream *bsdr, int macrocell, int value )
- {
- SetBit( bsdr, EPX780MacrocellPosition[macrocell][OUT], value );
- }
-
- /*
- * RTN GetMacrocellOutput: gets the value stored in the output cell of
- * the BSDR for the given macrocell (0..79).
- */
- int GetMacrocellOutput( bitstream *bsdr, int macrocell )
- {
- return GetBit( bsdr, EPX780MacrocellPosition[macrocell][OUT] );
- }
-
- /*
- * RTN SetMacrocellInput: sets the value stored in the input cell of
- * the BSDR for the given macrocell (0..79).
- */
- void SetMacrocellInput( bitstream *bsdr, int macrocell, int value )
- {
- SetBit( bsdr, EPX780MacrocellPosition[macrocell][IN], value );
- }
-
- /*
- * RTN GetMacrocellInput: gets the value stored in the input cell of
- * the BSDR for the given macrocell (0..79).
- */
- int GetMacrocellInput( bitstream *bsdr, int macrocell )
- {
- return GetBit( bsdr, EPX780MacrocellPosition[macrocell][IN] );
- }
-
- /*
- * RTN SetSyncClock: Sets the value stored in the input cell of
- * the BSDR for the given synchronous clock input (1..2).
- */
- void SetSyncCLOCK( bitstream *bsdr, int clock, int value )
- {
- SetBit( bsdr, EPX780ClockPosition[clock], value );
- }
-
- /*
- * RTN GetSyncClock: gets the value stored in the input cell of
- * the BSDR for the given synchronous clock input (1..2).
- */
- int GetSyncClock( bitstream *bsdr, int clock )
- {
- return GetBit( bsdr, EPX780ClockPosition[clock] );
- }
-
- /*
- * RTN SetDedicatedInput: Sets the value stored in the input cell of the
- * BSDR for the given dedicated input (0..21).
- */
- void SetDedicatedInput( bitstream *bsdr, int input, int value )
- {
- return SetBit( bsdr, EPX780InputPosition[input], value );
- }
-
- /*
- * RTN GetDedicatedInput: Gets the value stored in the input cell of the
- * BSDR for the given dedicated input (0..21).
- */
- int GetDedicatedInput( bitstream *bsdr, int input )
- {
- return GetBit( bsdr, EPX780InputPosition[input] );
- }
-
-