📄 jtagfunc.cpp
字号:
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include "jtagup.h"
extern word DEVICE;
extern byte g_tck;
extern byte g_tms;
extern byte g_tdi;
extern int lpt_address;
void putp1(byte tck, byte tms, byte tdi, byte usX);
int getp1(byte usX);
void error_out(char*);
void TCLKstrobes(word Amount);
//----------------------------------------------------------------------------
/* This function sets the target JTAG state machine (JTAG FSM) back into the
Run-Test/Idle state after a shift access.
*/
void PrepTCLK(void)
{
// JTAG FSM = Exit-DR
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM = Update-DR
g_tms = 0; //ClrTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM = Run-Test/Idle
}
//----------------------------------------------------------------------------
/* Shift a value into TDI (MSB first) and simultaneously shift out a value
from TDO (MSB first).
Note: When defining SPI_MODE the embedded SPI is used to speed up by 2.
Arguments: word Format (number of bits shifted, 8 (F_BYTE) or 16 (F_WORD))
word Data (data to be shifted into TDI)
Result: word (scanned TDO value)
*/
word Shift(word Format, word Data)
{
byte tclk; //= StoreTCLK(); // Store TCLK state;
word TDOword = 0x0000; // Initialize shifted-in word
word MSB = 0x0000;
word i;
/* byte bypassbit;
//bypass PxA
bypassbit = (Format == F_WORD) ? 1 : 5; //PxA DR 1 bit(bypass register), IR 5 bits
g_tdi = (Format == F_WORD) ? 0 : 1; //DR put low,IR put high (bypass IR = 0x1F)
for (i = bypassbit; i > 0; i--) {
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
}
*/
tclk = g_tdi; //StoreTCLK();
(Format == F_WORD) ? (MSB = 0x8000) : (MSB = 0x80);
for (i = Format; i > 0; i--) {
g_tdi = ((Data & MSB) == 0) ? 0 : 1; //((Data & MSB) == 0) ? ClrTDI() : SetTDI();
Data <<= 1;
if (i == 1) // Last bit requires TMS=1
g_tms = 1; //SetTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
TDOword <<= 1; // TDO could be any port pin
if (getp1(1) != 0) //if (ScanTDO() != 0)
TDOword++;
}
//printf("%x\n",TDOword);
// common exit
g_tdi = tclk; //RestoreTCLK(tclk); // restore TCLK state
PrepTCLK(); // Set JTAG FSM back into Run-Test/Idle
return(TDOword);
}
//----------------------------------------------------------------------------
/* Function for shifting a new instruction into the JTAG instruction
register through TDI (MSB first, but with interchanged MSB - LSB, to
simply use the same shifting function, Shift(), as used in DR_Shift16).
Arguments: byte Instruction (8bit JTAG instruction, MSB first)
Result: word TDOword (value shifted out from TDO = JTAG ID)
*/
word IR_Shift(byte instruction)
{
// JTAG FSM state = Run-Test/Idle
g_tms = 1; //SetTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Select DR-Scan
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Select IR-Scan
g_tms = 0; //ClrTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Capture-IR
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Shift-IR, Shift in TDI (8-bit)
return(Shift(F_BYTE, instruction));
// JTAG FSM state = Run-Test/Idle
}
word DR_Shift16(word data)
{
// JTAG FSM state = Run-Test/Idle
g_tms = 1; //SetTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Select DR-Scan
g_tms = 0; //ClrTMS();
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Capture-DR
putp1(0,g_tms,g_tdi,1); //ClrTCK();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM state = Shift-DR, Shift in TDI (16-bit)
return(Shift(F_WORD, data));
// JTAG FSM state = Run-Test/Idle
}
//----------------------------------------------------------------------------
/* Reset target JTAG interface and perform fuse-HW check.
Arguments: None
Result: None
*/
void ResetTAP(void)
{
word i;
g_tms = 1; //SetTMS();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// Perform fuse check
putp1(1,0,1,1); //ClrTMS();
putp1(1,1,1,1); //SetTMS();
putp1(1,0,1,1); //ClrTMS();
putp1(1,1,1,1); //SetTMS();
// Now fuse is checked, Reset JTAG FSM
for (i = 6; i > 0; i--)
{
putp1(0,g_tms,0,1); //ClrTCK();
putp1(1,g_tms,0,1); //SetTCK();
}
// JTAG FSM is now in Test-Logic-Reset
putp1(0,g_tms,g_tdi,1); //ClrTCK();
g_tms = 0; //ClrTMS();
putp1(1,g_tms,g_tdi,1); //SetTCK();
// JTAG FSM is now in Run-Test/IDLE
}
//----------------------------------------------------------------------------
/* Function to set target CPU JTAG FSM into the instruction fetch state
Argument: None
Result: word (STATUS_OK if instr. fetch was set, STATUS_ERROR otherwise)
*/
word SetInstrFetch(void)
{
word i;
IR_Shift(IR_CNTRL_SIG_CAPTURE);
// Wait until CPU is in instr. fetch state, timeout after limited attempts
for (i = 50; i > 0; i--) {
putp1(g_tck,g_tms,0,1); //ClrTCLK();
putp1(g_tck,g_tms,1,1); //SetTCLK();
if ((DR_Shift16(0x0000) & 0x0080) == 0x0080)
return(STATUS_OK);
}
printf("SetInstrFetch error\n");
return(STATUS_ERROR);
}
//----------------------------------------------------------------------------
/* Function to set the CPU into a controlled stop state
*/
void HaltCPU(void)
{
SetInstrFetch(); // Set CPU into instruction fetch mode
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2401);
IR_Shift(IR_DATA_16BIT);
DR_Shift16(0x3FFF); // Send JMP $ instruction
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2409); // Set JTAG_HALT bit
putp1(g_tck,g_tms,1,1); //SetTCLK();
}
//----------------------------------------------------------------------------
/* Function to release the target CPU from the controlled stop state
*/
void ReleaseCPU(void)
{
putp1(g_tck,g_tms,0,1); //ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2401); // Clear the HALT_JTAG bit
IR_Shift(IR_ADDR_CAPTURE);
putp1(g_tck,g_tms,1,1); //SetTCLK();
}
//------------------------------------------------------------------------
/* This function checks if the JTAG access security fuse is blown.
Arguments: None
Result: word (STATUS_OK if fuse is blown, STATUS_ERROR otherwise)
*/
word IsFuseBlown(void)
{
word i;
for (i = 3; i > 0; i--) { // First trial could be wrong
IR_Shift(IR_CNTRL_SIG_CAPTURE);
if (DR_Shift16(0xAAAA) == 0x5555)
return(STATUS_OK); // Fuse is blown
}
return(STATUS_ERROR); // fuse is not blown
}
//----------------------------------------------------------------------------
/* Load a given address into the target CPU's program counter (PC).
Argument: word Addr (destination address)
Result: None
*/
void SetPC(word Addr)
{
SetInstrFetch(); // Set CPU into instruction fetch mode, TCLK=1
// Load PC with address
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x3401); // CPU has control of RW & BYTE.
IR_Shift(IR_DATA_16BIT);
DR_Shift16(0x4030); // "mov #addr,PC" instruction
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
DR_Shift16(Addr); // Send addr value
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK(); // Now the PC should be on Addr
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2401); // JTAG has control of RW & BYTE.
}
//----------------------------------------------------------------------------
/* This function reads one byte/word from a given address in memory
Arguments: word Format (F_BYTE or F_WORD)
word Addr (address of memory)
Result: word (content of the addressed memory location)
*/
word ReadMem(word Format, word Addr)
{
word TDOword;
HaltCPU();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
if (Format == F_WORD)
DR_Shift16(0x2409); // Set word read
else
DR_Shift16(0x2419); // Set byte read
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(Addr); // Set address
IR_Shift(IR_DATA_TO_ADDR);
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
TDOword = DR_Shift16(0x0000); // Shift out 16 bits
putp1(g_tck,g_tms,1,1); //SetTCLK();
ReleaseCPU();
return(Format == F_WORD ? TDOword : TDOword & 0x00FF);
}
//----------------------------------------------------------------------------
/* This function reads an array of words from a memory.
Arguments: word StartAddr (Start address of memory to be read)
word Length (Number of words to be read)
word *DataArray (Pointer to array for the data)
Result: None
*/
void ReadMemQuick(word StartAddr, word Length, word *DataArray)
{
word i;
// Initialize reading:
//SetPC(StartAddr-4);
SetPC(StartAddr-8); //lucas
HaltCPU();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2409); // Set RW to read
IR_Shift(IR_DATA_QUICK);
for (i = 0; i < Length; i++)
{
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
DataArray[i] = DR_Shift16(0x0000); // Shift out the data
// from the target.
}
putp1(g_tck,g_tms,1,1); //SetTCLK();
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function writes one byte/word at a given address ( <0xA00)
Arguments: word Format (F_BYTE or F_WORD)
word Addr (Address of data to be written)
word Data (shifted data)
Result: None
*/
void WriteMem(word Format, word Addr, word Data)
{
HaltCPU();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
if (Format == F_WORD)
DR_Shift16(0x2408); // Set word write
else
DR_Shift16(0x2418); // Set byte write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(Addr); // Set addr
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(Data); // Shift in 16 bits
putp1(g_tck,g_tms,1,1); //SetTCLK();
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* Function to execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register
Arguments: None
Result: word (STATUS_OK if JTAG ID is valid, STATUS_ERROR otherwise)
*/
word ExecutePUC(void)
{
word JTAGVERSION;
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2C01); // Apply Reset
DR_Shift16(0x2401); // Remove Reset
putp1(g_tck,g_tms,0,1); //ClrTCLK();
putp1(g_tck,g_tms,1,1); //SetTCLK();
putp1(g_tck,g_tms,0,1); //ClrTCLK();
putp1(g_tck,g_tms,1,1); //SetTCLK();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -