📄 jtag.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// JTAG.cpp //
//////////////////////////////////////////////////////////////////////////////
/*
ByteBlasterMV on LPT1
Programming conventions:
- functions have JTAG state transition commented. other functions begin/end with 'run test idle'
- maximum throughput should be achieved using inline & assembly
States transitions:
state TMS TMS=>0 TMS=>1
------------------- ------- ------------------- ----------------
test logic reset 1 run test idle test logic reset
run test idle 0 run test idle select DR scan
select DR scan 1 capture select IR scan
select IR scan 1 capture test logic reset
capture 0 shift exit1
shift 0 shift exit1
exit1 1 pause update
pause 0 pause exit2
exit2 1 shift update
update 1 run testidle select DR scan
Clock timings:
TDI and TMS are sampled on the rising edge of TCK
TDO output at falling edge of TCK
*/
//////////////////////////////////////////////////////////////////////////////
// Includes //
//////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include "JTAG.h"
#include "Device.h"
//////////////////////////////////////////////////////////////////////////////
// Namespace //
//////////////////////////////////////////////////////////////////////////////
namespace JTAG
{
//////////////////////////////////////////////////////////////////////////////
// Defines //
//////////////////////////////////////////////////////////////////////////////
#define PORT 0x378
#define TCK 0x01
#define TMS 0x02
#define TDI 0x40
#define TDO ((unsigned char)~_inp(PORT+1) >> 7)
#define OUTP(tms,tdi,tck) _outp(PORT, tms*TMS + tdi*TDI + tck*TCK)
#define TMS_IDLE_CAPTURE_SHIFT_PAUSE 0
#define TMS_RESET_SELECT_EXIT_UPDATE 1
#define TMS_RESET 1 // idle -> reset
#define TMS_SELECT 1 // idle/select IR -> select/select DR
#define TMS_CAPTURE 0 // select -> capture
#define TMS_SHIFT 0 // capture -> shift
#define TMS_UPDATE 1 // shift -> update
#define TMS_IDLE 0 // update -> idle
#define TMS_EXIT 1 // shift/pause -> exit1/exit2
#define TMS_PAUSE 0 // exit1 -> pause
//////////////////////////////////////////////////////////////////////////////
// Variables //
//////////////////////////////////////////////////////////////////////////////
int currentCommand = -1; // cached instruction register
int currentDataChain = -1; // cached chain number
int dataLength = -1; // data register register length
int instructionLength = 4; // instruction register length
//////////////////////////////////////////////////////////////////////////////
// TMS //
//////////////////////////////////////////////////////////////////////////////
// state transition
__forceinline void NextState(int tms)
{
int tdi = 1;
OUTP(tms,tdi,0);
OUTP(tms,tdi,1);
}
//////////////////////////////////////////////////////////////////////////////
// ReadBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> shift
__forceinline int ReadBit()
{
int tdi = 1;
int tms = 0;
//OUTP(tms,tdi,0); // added by DF
OUTP(tms,tdi,1);
OUTP(tms,tdi,0);
return TDO;
}
//////////////////////////////////////////////////////////////////////////////
// ReadLastBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> exit1
__forceinline int ReadLastBit()
{
int tdi = 1;
int tms = 1;
//OUTP(tms,tdi,0); // added by DF
OUTP(tms,tdi,1);
OUTP(tms,tdi,0);
return TDO;
}
//////////////////////////////////////////////////////////////////////////////
// WriteBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> shift
__forceinline void WriteBit(int tdi)
{
int tms = 0;
OUTP(tms,tdi,0);
OUTP(tms,tdi,1);
}
//////////////////////////////////////////////////////////////////////////////
// WriteLastBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> exit1
__forceinline void WriteLastBit(int tdi)
{
int tms = 1;
OUTP(tms,tdi,0);
OUTP(tms,tdi,1);
}
//////////////////////////////////////////////////////////////////////////////
// TransferBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> shift
__forceinline int TransferBit(int tdi = 1)
{
int tms = 0;
//OUTP(tms,tdi,0); // added by DF
OUTP(tms,tdi,1);
OUTP(tms,tdi,0);
return TDO;
}
//////////////////////////////////////////////////////////////////////////////
// TransferLastBit //
//////////////////////////////////////////////////////////////////////////////
// shift -> exit1
__forceinline int TransferLastBit(int tdi = 1)
{
int tms = 1;
//OUTP(tms,tdi,0); // added by DF
OUTP(tms,tdi,1);
OUTP(tms,tdi,0);
return TDO;
}
//////////////////////////////////////////////////////////////////////////////
// Reset //
//////////////////////////////////////////////////////////////////////////////
// * -> test logic reset
__forceinline void Reset()
{
for (int i=0; i<5; i++)
{
NextState(TMS_RESET_SELECT_EXIT_UPDATE); // * -> test logic reset
}
}
//////////////////////////////////////////////////////////////////////////////
// ResetToIdle //
//////////////////////////////////////////////////////////////////////////////
// * -> run test idle
__forceinline void ResetToIdle()
{
Reset();
NextState(TMS_IDLE_CAPTURE_SHIFT_PAUSE); // test logic reset -> run test idle
}
//////////////////////////////////////////////////////////////////////////////
// Idle //
//////////////////////////////////////////////////////////////////////////////
void Idle(int n=1)
{
for (int i=0; i<n; i++)
{
NextState(TMS_IDLE_CAPTURE_SHIFT_PAUSE);
}
}
//////////////////////////////////////////////////////////////////////////////
// ReadIR //
//////////////////////////////////////////////////////////////////////////////
// always returns 1
/*unsigned int ReadIR()
{
NextState(TMS_SELECT);
NextState(TMS_SELECT);
NextState(TMS_CAPTURE);
NextState(TMS_SHIFT);
int bits = instructionLength;
unsigned int readData = 0;
for (int bit=0; bit<bits-1; bit++) // do all except last bit
{
readData += ReadBit() << bit;
}
readData += ReadLastBit() << (bits-1); // do last bit
//return readData;
NextState(TMS_UPDATE);
NextState(TMS_IDLE);
printf("ReadIR returns %08X (%d)\n", readData, instructionLength);
return readData;
}*/
//////////////////////////////////////////////////////////////////////////////
// WriteIR //
//////////////////////////////////////////////////////////////////////////////
/*void WriteIR(unsigned int writeData)
{
printf("WriteIR %s\n", Device::sCommands[writeData]);
NextState(TMS_SELECT);
NextState(TMS_SELECT);
NextState(TMS_CAPTURE);
NextState(TMS_SHIFT);
int bits = instructionLength;
while (--bits) // do all except last bit
{
WriteBit(writeData & 1);
writeData >>= 1;
}
WriteLastBit(writeData & 1); // do last bit
NextState(TMS_UPDATE);
NextState(TMS_IDLE);
}*/
//////////////////////////////////////////////////////////////////////////////
// Command //
//////////////////////////////////////////////////////////////////////////////
void Command(unsigned int command)
{
if (currentCommand == command) return;
//printf("command %01X to %s\n", currentCommand, Device::sCommands[command]);
currentCommand = command;
//printf("currentCommand = %X, currentDataChain = %d, dataLength = %d\n", currentCommand, currentDataChain, dataLength);
printf("%s\n", Device::sCommands[command]);
NextState(TMS_SELECT);
NextState(TMS_SELECT);
NextState(TMS_CAPTURE);
NextState(TMS_SHIFT);
unsigned int writeData = command;
int bits = instructionLength;
while (--bits) // do all except last bit
{
WriteBit(writeData & 1);
writeData >>= 1;
}
WriteLastBit(writeData & 1); // do last bit
NextState(TMS_UPDATE);
NextState(TMS_IDLE);
if (Device::commandDataLength[currentCommand] >= 0) dataLength = Device::commandDataLength[currentCommand];
}
//////////////////////////////////////////////////////////////////////////////
// Chain //
//////////////////////////////////////////////////////////////////////////////
void Chain(int chain)
{
if (currentDataChain == chain) return;
printf("{\n");
currentDataChain = chain;
//printf("currentCommand = %X, currentDataChain = %d, dataLength = %d\n", currentCommand, currentDataChain, dataLength);
int oldCommand = currentCommand;
Command(Device::SCAN_N);
Write(chain);
printf("%s\n", Device::sChains[chain]);
Command(oldCommand);
if (Device::chainLength[currentDataChain] >= 0) dataLength = Device::chainLength[currentDataChain];
printf("}\n");
}
//////////////////////////////////////////////////////////////////////////////
// Read //
//////////////////////////////////////////////////////////////////////////////
unsigned int Read()
{
NextState(TMS_SELECT);
NextState(TMS_CAPTURE);
NextState(TMS_SHIFT);
int bits = dataLength;
//printf("Read %d\n", bits);
unsigned int readData = 0;
for (int bit=0; bit<bits-1; bit++) // do all except last bit
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -