AN 100: In-System Programmability Guidelines

ID 683546
Date 9/22/2014
Public
Document Table of Contents

1.5.2. Porting the Jam Player

The Altera Jam Player (both Byte-Code and ASCII versions) works with a PC parallel port. To port the Jam Player to your processor, you only need to modify the jamstub.c or jbistub.c file (for the ASCII Jam Player or Jam Byte-Code Player, respectively).

All other files must remain the same. If the Jam Player is ported incorrectly, an Unrecognized Device error is generated. The most common causes for this error are:

  • After porting the Jam Player, the TDO value may be read in reversed polarity. This problem may occur because the default I/O code in the Jam Player assumes the use of the PC parallel port.
  • Although the TMS and TDI signals are clocked in on the rising edge of TCK signal, outputs do not change until the falling edge of TCK signal. This situation causes a half TCK clock cycle to lag in reading out the values. If the TDO transition is expected on the rising edge, the data appears to be offset by one clock.
  • Altera recommends using registers to synchronize the output transitions. In addition, some processor data ports use a register to synchronize the output signals. For example, reading and writing to the parallel port of the PC is accomplished by reading and writing to registers. When reading and writing to the JTAG chain, you must take into consideration the use of these registers. Incorrect accounting of these registers can cause the values to either lead or lag the expected value.

You can use a test .jam file to determine if the Jam Player is ported correctly. The following examples show parts of a sample .jam file that helps debug potential porting problems.

Sample 1

NOTE JAM_VERSION "1.1 ";
NOTE DESIGN "IDCODE.jam version 1.4 4/28/98";
'#############################################################################
'#This Jam File compares the IDCODE read from a JTAG chain with the
'#expected IDCODE. There are 5 parameters that can be set when executing
'#this code.
'#
'#COMP_IDCODE_[device #]=1, for example -dCOMP_IDCODE_9400=1
'#compares the IDCODE with an EPM9400 IDCODE.
'#PRE_IR=[IR_LENGTH] is the length of the instruction registers you want
'#to bypass after the target device. The default is 0, so if your
'#JTAG length is 1, you don't need to enter a value.
'#POST_IR=[IR_LENGTH] is the length of the instruction registers you
'#want to bypass before the target device. The default is 0, so if
'#your JTAG length is 1, you don't need to enter a value.
'#PRE_DR=[DR_LENGTH] is the length of the data registers you want
'#to bypass after the target device. The default is 0, so if your
'#JTAG length is 1, you don't need to enter a value.
'#POST_DR=[DR_LENGTH] is the length of the data registers you want
'#to bypass before the target device. The default is 0, so if your
'#JTAG length is 1, you don't need to enter a value.
'#Example: This example reads the IDCODE out of the second device in the
'#chain below:
'#
'#TDI -> EPM7128S -> EPM7064S -> EPM7256S -> EPM7256S -> TDO
'#
'#In this example, the IDCODE is compared to the EPM7064S IDCODE. If the JTAG
'#chain is set up properly, the IDCODEs should match.
'# C:\> jam -dCOMP_IDCODE_7064S=1 -dPRE_IR=20 -dPOST_IR=10 -dPRE_DR=2
'#-dPOST_DR=1 -p378 IDCODE.jam
'#
'#
'# Example: This example reads the IDCODE of a single device JTAG chain
'# and compares it to an EPM9480 IDCODE:
'#
'# C:\> jam -dCOMP_IDCODE_9480=1 -p378 IDCODE.jam
'#############################################################################

Sample 2

' ######################### Initialization ########################
BOOLEAN read_data[32];
BOOLEAN I_IDCODE[10] = BIN 1001101000;
BOOLEAN I_ONES[10] = BIN 1111111111;
BOOLEAN ONES_DATA[32]= HEX FFFFFFFF;
BOOLEAN ID_9320[32] = BIN 10111011000000000100110010010000;
BOOLEAN ID_9400[32] = BIN 10111011000000000000001010010000;
BOOLEAN ID_9480[32] = BIN 10111011000000000001001010010000;
BOOLEAN ID_9560[32] = BIN 10111011000000000110101010010000;
BOOLEAN ID_7032S[32] = BIN 10111011000001001100000011100000;
BOOLEAN ID_7064S[32] = BIN 10111011000000100110000011100000;
BOOLEAN ID_7128S[32] = BIN 10111011000000010100100011100000;
BOOLEAN ID_7128A[32] = BIN 10111011000000010100100011100000;
BOOLEAN ID_7160S[32] = BIN 10111011000000000110100011100000;
BOOLEAN ID_7192S[32] = BIN 10111011000001001001100011100000;
BOOLEAN ID_7256S[32] = BIN 10111011000001101010010011100000;
BOOLEAN ID_7256A[32] = BIN 10111011000001101010010011100000;
BOOLEAN COMP_9320_IDCODE = 0;
BOOLEAN COMP_9400_IDCODE = 0;
BOOLEAN COMP_9480_IDCODE = 0;
BOOLEAN COMP_9560_IDCODE = 0;
BOOLEAN COMP_7032S_IDCODE = 0;
BOOLEAN COMP_7064S_IDCODE = 0;
BOOLEAN COMP_7096S_IDCODE = 0;
BOOLEAN COMP_7128S_IDCODE = 0;
BOOLEAN COMP_7128A_IDCODE = 0;
BOOLEAN COMP_7160S_IDCODE = 0;
BOOLEAN COMP_7192S_IDCODE = 0;
BOOLEAN COMP_7256S_IDCODE = 0;
BOOLEAN COMP_7256A_IDCODE = 0;
BOOLEAN COMP_7032AE_IDCODE = 0;
BOOLEAN COMP_7064AE_IDCODE = 0;
BOOLEAN COMP_7128AE_IDCODE = 0;
BOOLEAN COMP_7256AE_IDCODE = 0;
BOOLEAN COMP_7512AE_IDCODE = 0;
INTEGER PRE_IR = 0;
INTEGER PRE_DR = 0;
INTEGER POST_IR = 0;
INTEGER POST_DR = 0;
BOOLEAN SET_ID_EXPECTED[32];
BOOLEAN COMPARE_FLAG1 = 0;
BOOLEAN COMPARE_FLAG2 = 0;
BOOLEAN COMPARE_FLAG = 0;
' This information is what is expected to be shifted out of the instruction
' register
BOOLEAN expected_data[10] = BIN 0101010101;
BOOLEAN ir_data[10];

Sample 3

' These values default to 0, so if you have a single device JTAG chain, you do
' not have to set these values.
PREIR PRE_IR;
POSTIR POST_IR;
PREDR PRE_DR;
POSTDR POST_DR;
INTEGER i;
' ######################### Determine Action ########################
LET COMPARE_FLAG1= COMP_9320_IDCODE || COMP_9400_IDCODE || COMP_9480_IDCODE ||
COMP_9560_IDCODE || COMP_7032S_IDCODE || COMP_7064S_IDCODE ||
COMP_7096S_IDCODE || COMP_7032AE_IDCODE || COMP_7064AE_IDCODE ||
COMP_7128AE_IDCODE;
LET COMPARE_FLAG2 = COMP_7128S_IDCODE || COMP_7128A_IDCODE || COMP_7160S_IDCODE
|| COMP_7192S_IDCODE || COMP_7256S_IDCODE || COMP_7256A_IDCODE ||
COMP_7256AE_IDCODE || COMP_7512AE_IDCODE;
LET COMPARE_FLAG = COMPARE_FLAG1 || COMPARE_FLAG2;
IF COMPARE_FLAG != 1 THEN GOTO NO_OP;
FOR i=0 to 31;
IF COMP_9320_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9320[i];
IF COMP_9400_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9400[i];
IF COMP_9480_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9480[i];
IF COMP_9560_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9560[i];
IF COMP_7032S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7032S[i];
IF COMP_7064S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7064S[i];
FOR i=0 to 31;
IF COMP_9320_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9320[i];
IF COMP_9400_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9400[i];
IF COMP_9480_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9480[i];
IF COMP_9560_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_9560[i];
IF COMP_7032S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7032S[i];
IF COMP_7064S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7064S[i];
IF COMP_7128S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7128S[i];
IF COMP_7128A_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7128A[i];
IF COMP_7160S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7160S[i];
IF COMP_7192S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7192S[i];
IF COMP_7256S_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7256S[i];
IF COMP_7256A_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7256A[i];
IF COMP_7032AE_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7032AE[i];
IF COMP_7064AE_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7064AE[i];
IF COMP_7128AE_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7128AE[i];
IF COMP_7256AE_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7256AE[i];
IF COMP_7512AE_IDCODE == 1 THEN LET SET_ID_EXPECTED[i] = ID_7512AE[i];

NEXT I;

Sample 4

' ######################### Actual Loading ########################
IRSTOP IRPAUSE;
STATE RESET;
IRSCAN 10, I_IDCODE[0..9], CAPTURE ir_data[0..9];
STATE IDLE;
DRSCAN 32, ONES_DATA[0..31], CAPTURE read_data[0..31];
' ######################### Printing ########################
PRINT "EXPECTED IRSCAN : 1010101010";
PRINT "ACTUAL IRSCAN: ",ir_data[0], ir_data[1], ir_data[2], ir_data[3],
ir_data[4], ir_data[5], ir_data[6], ir_data[7], ir_data[8], ir_data[9];
PRINT "";PRINT "EXPECTED IDCODE : ", SET_ID_EXPECTED[0], SET_ID_EXPECTED[1],
SET_ID_EXPECTED[2], SET_ID_EXPECTED[3], SET_ID_EXPECTED[4],
SET_ID_EXPECTED[5], SET_ID_EXPECTED[6], SET_ID_EXPECTED[7],
SET_ID_EXPECTED[8], SET_ID_EXPECTED[9], SET_ID_EXPECTED[10],
SET_ID_EXPECTED[11], SET_ID_EXPECTED[12], SET_ID_EXPECTED[13],
SET_ID_EXPECTED[14], SET_ID_EXPECTED[15], SET_ID_EXPECTED[16],
SET_ID_EXPECTED[17], SET_ID_EXPECTED[18], SET_ID_EXPECTED[19],
SET_ID_EXPECTED[20], SET_ID_EXPECTED[21], SET_ID_EXPECTED[22],
SET_ID_EXPECTED[23], SET_ID_EXPECTED[24], SET_ID_EXPECTED[25],
SET_ID_EXPECTED[26], SET_ID_EXPECTED[27], SET_ID_EXPECTED[28],
SET_ID_EXPECTED[29], SET_ID_EXPECTED[30], SET_ID_EXPECTED[31];
PRINT "ACTUAL IDCODE : ", READ_DATA[0], READ_DATA[1], READ_DATA[2],
READ_DATA[3], READ_DATA[4], READ_DATA[5], READ_DATA[6], READ_DATA[7],
READ_DATA[8], READ_DATA[9], READ_DATA[10], READ_DATA[11], READ_DATA[12],
READ_DATA[13], READ_DATA[14], READ_DATA[15], READ_DATA[16], READ_DATA[17],
READ_DATA[18], READ_DATA[19], READ_DATA[20], READ_DATA[21], READ_DATA[22],
READ_DATA[23], READ_DATA[24], READ_DATA[25], READ_DATA[26], READ_DATA[27],
READ_DATA[28], READ_DATA[29], READ_DATA[30], READ_DATA[31];
GOTO END;
' ######################### If no parameters are set ########################
NO_OP: PRINT "jam [-d<var=val>] [-p<port>] [-s<port>] IDCODE.jam";
PRINT "-d : initialize variable to specified value";
PRINT "-p : parallel port number or address <for ByteBlaster>";
PRINT "-s : serial port name <for BitBlaster>";
PRINT " ";
PRINT "Example: To compare IDCODE of the 4th device in a chain of 5 Altera "; PRINT
"devices with EPM7192S IDCODE";
PRINT " ";
PRINT "jam -dCOMP_7192S_IDCODE=1 -dPRE_IR=10 -dPOST_IR=30 -dPRE_DR=1";
PRINT "dPOST_DR=3 -p378 IDCODE.jam";
PRINT " ";
END:
EXIT 0;