📄 jtag.cpp
字号:
// jtag.cpp: implementation of the jtag class.
//根据silicon laboratorles 提供的 AN105应用手册编写而成
//硬件使用 altera ByteBlaster 和xilinx PARALLELIII 线缆
//手册上理论支持如下器件:
//C8051F000, C8051F001, C8051F002,
//C8051F005, C8051F006, C8051F010, C8051F011,
//C8051F012, C8051F015, C8051F016,
//C8051F017, C8051F206, C8051F220,
//C8051F221, C8051F226, C8051F230,
//C8051F231, C8051F236, C8051F020,
//C8051F021, C8051F022, and C8051F023.
//
//测试通过:
//C8051f020
//
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "C8051JTAG.h"
#include "jtag.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
jtag::jtag()
{
m_iCcabletype = ALTERABLASTER;
m_nPort = (WORD)0x378;
m_ucWriteValue = 0x00;
b_TDONoInv = TRUE;
SetPortVal(m_nPort, m_ucWriteValue, 1); //SET TMS,TCK,TDI to low
FLCN_LEN = 8; // 8 // number of bits in FLASHCON
FLD_RDLEN = 10; //10 // number of bits in an FLASHDAT read
FLD_WRLEN = 8; //8 // number of bits in an FLASHDAT write
FLA_LEN = 16; //16 // number of bits in FLASHADR
FLSC_LEN = 8; //8 // number of bits in FLASHSCL
ucFCONBIT7 = 0;
}
jtag::~jtag()
{
}
/////////////////////////////////////////////////////////////////////////////
// jtag message handlers
//TCK函数
void jtag::TCK(bool bValue)
{
unsigned char ucTemp;
ucTemp = 0;
ucTemp = 1<<m_woTCKPin;
if(bValue)
{
m_ucWriteValue |= ucTemp;
}
else
{
ucTemp = ~ucTemp;
m_ucWriteValue &= ucTemp;
}
SetPortVal(m_nPort, m_ucWriteValue, 1);
}
void jtag::TMS(bool bValue)
{
unsigned char ucTemp;
ucTemp = 0;
ucTemp = 1<<m_woTMSPin;
if(bValue)
{
m_ucWriteValue |= ucTemp;
}
else
{
ucTemp = ~ucTemp;
m_ucWriteValue &= ucTemp;
}
SetPortVal(m_nPort, m_ucWriteValue, 1);
}
void jtag::TDI(bool bValue)
{
unsigned char ucTemp;
ucTemp = 0;
ucTemp = 1<<m_woTDIPin;
if(bValue)
{
m_ucWriteValue |= ucTemp;
}
else
{
ucTemp = ~ucTemp;
m_ucWriteValue &= ucTemp;
}
SetPortVal(m_nPort, m_ucWriteValue, 1);
}
bool jtag::TDO()
{
//获得控制端口的值,保持高位值不变,将要输出的值从低4位输出,且使连接器上的电位状态与想输出的值一致
DWORD temp_dwPortVal;
unsigned int temp_aa,uiTempPin;
GetPortVal(m_nPort+m_iTDOAddP, &temp_dwPortVal, 1); //reads a BYTE value from an I/O port
temp_aa = (unsigned int)temp_dwPortVal;
uiTempPin = 1<<m_wiTDOPin;
//1
if(uiTempPin & temp_aa)
{
if (b_TDONoInv)
{
return 1;
}
else
return 0;
}
//0
else
{
if (b_TDONoInv)
{
return 0;
}
else
return 1;
}
}
void jtag::JTAG_StrobeTCK()
{
TCK(1);
TCK(0);
}
void jtag::JTAG_Reset()
{
TMS (1);
JTAG_StrobeTCK (); // move to Test Logic Reset state
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
TMS (0);
JTAG_StrobeTCK (); // move to Run_Test/Idle state
}
unsigned int jtag::JTAG_IR_Scan(unsigned int instruction, int num_bits)
{
unsigned int retval; // JTAG instruction read
int i; // JTAG IR bit counter
retval = 0x0;
TMS(1);
JTAG_StrobeTCK (); // move to SelectDR
TMS(1);
JTAG_StrobeTCK (); // move to SelectIR
TMS(0);
JTAG_StrobeTCK (); // move to Capture_IR
TMS(0);
JTAG_StrobeTCK (); // move to Shift_IR state
for (i=0; i < num_bits; i++)
{
TDI(instruction & 0x01); // shift IR, LSB-first
instruction = instruction >> 1;
retval = retval >> 1;
if (TDO())
{
retval |= (0x01 << (num_bits - 1));
}
if (i == (num_bits - 1))
{
TMS(1); // move to Exit1_IR state
}
JTAG_StrobeTCK();
}
TMS(1);
JTAG_StrobeTCK (); // move to Update_IR
TMS(0);
JTAG_StrobeTCK (); // move to RTI state
return retval;
}
unsigned long jtag::JTAG_DR_Scan(unsigned long dat, int num_bits)
{
unsigned long retval; // JTAG return value
int i; // JTAG DR bit counter
retval = 0x0L;
TMS(1);
JTAG_StrobeTCK (); // move to SelectDR
TMS(0);
JTAG_StrobeTCK (); // move to Capture_DR
TMS(0);
JTAG_StrobeTCK (); // move to Shift_DR state
for (i=0; i < num_bits; i++)
{
TDI(dat & 0x01); // shift DR, LSB-first
dat = dat >> 1;
retval = retval >> 1;
if(TDO())
{
retval |= (0x01L << (num_bits - 1));
}
if ( i == (num_bits - 1))
{
TMS(1); // move to Exit1_DR state
}
JTAG_StrobeTCK();
}
TMS(1);
JTAG_StrobeTCK (); // move to Update_DR
TMS(0);
JTAG_StrobeTCK (); // move to RTI state
return retval;
}
void jtag::JTAG_IWrite(unsigned int ireg, unsigned long dat, int num_bits)
{
int done; // TRUE = write complete; FALSE otherwise
JTAG_IR_Scan (ireg, INST_LENGTH); // load IR with <ireg>
dat |= (0x03L << num_bits); // append ‘WRITE’ opcode to data
// load DR with <dat>
JTAG_DR_Scan (dat, num_bits + 2); // initiate the JTAG write
// load DR with ‘0’, and check for BUSY bit to go to ‘0’.
do
{
done = !(JTAG_DR_Scan (0x0L, 1)); // poll for JTAG_BUSY bit
} while (!done);
}
unsigned long jtag::JTAG_IRead(unsigned int ireg, int num_bits)
{
unsigned long retval; // value returned from READ operation
int done; // TRUE = write complete; FALSE otherwise
JTAG_IR_Scan (ireg, INST_LENGTH); // load IR with <ireg>
// load DR with read opcode (0x02)
JTAG_DR_Scan (0x02L, 2); // initiate the JTAG read
do
{
done = !(JTAG_DR_Scan (0x0L, 1)); // poll for JTAG_BUSY bit
} while (!done);
retval = JTAG_DR_Scan (0x0L, num_bits + 1); // allow poll operation to
// read remainder of the bits
retval = retval >> 1; // shift JTAG_BUSY bit off the end
return retval;
}
int jtag::FLASH_ByteWrite(unsigned long addr, unsigned char dat)
{
unsigned long testval; // holds result of FLASHDAT read
int done; // TRUE/FALSE flag
int retval; // TRUE if operation successful
JTAG_IWrite (FLASHSCL, 0x81L, FLSC_LEN); // set FLASHSCL based on SYSCLK
// frequency (2MHz = 0x86)
// set FLASHADR to address to write to
JTAG_IWrite (FLASHADR, (unsigned long) addr, FLA_LEN);
JTAG_IWrite (FLASHCON, 0x10L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for FLASH Write
// operation (0x10)
// initiate the write operation
JTAG_IWrite (FLASHDAT, (unsigned long) dat, FLD_WRLEN);
JTAG_IWrite (FLASHCON, 0x0L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for ‘poll’ operation
do
{
done = !(JTAG_IRead (FLASHDAT, 1)); // poll for FLBusy to de-assert
} while (!done);
testval = JTAG_IRead (FLASHDAT, 2); // read FLBusy and FLFail
retval = (testval & 0x02) ? FALSE:TRUE; // FLFail is next to LSB
return retval; // return FLASH Pass/Fail
}
int jtag::FLASH_PageErase(unsigned long addr)
{
unsigned long testval; // holds result of FLASHDAT read
int done; // TRUE/FALSE flag
int retval; // TRUE if operation successful
JTAG_IWrite (FLASHSCL, 0x81L, FLSC_LEN); // set FLASHSCL based on SYSCLK
// frequency (2MHz = 0x86)
// set FLASHADR to address within page to erase
JTAG_IWrite (FLASHADR, (unsigned long) addr, FLA_LEN);
JTAG_IWrite (FLASHCON, 0x20L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for FLASH Erase
// operation (0x20)
JTAG_IWrite (FLASHDAT, 0xa5L, FLD_WRLEN); // set FLASHDAT to 0xa5 to initiate
// erase procedure
JTAG_IWrite (FLASHCON, 0x0L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for ‘poll’ operation
do
{
done = !(JTAG_IRead (FLASHDAT, 1)); // poll for FLBusy to de-assert
} while (!done);
testval = JTAG_IRead (FLASHDAT, 2); // read FLBusy and FLFail
retval = (testval & 0x02) ? FALSE: TRUE; // FLFail is next to LSB
// set return value based on FLFail bit
return retval; // return FLASH Pass/Fail
}
int jtag::FLASH_ByteRead(unsigned long addr, unsigned char *pdat)
{
unsigned long testval; // holds result of FLASHDAT read
int done; // TRUE/FALSE flag
int retval; // TRUE if operation successful
JTAG_IWrite (FLASHSCL, 0x80L, FLSC_LEN); // set FLASHSCL based on SYSCLK
// frequency (2MHz = 0x86)
// set FLASHADR to address to read from
JTAG_IWrite (FLASHADR, (unsigned long) addr, FLA_LEN);
JTAG_IWrite (FLASHCON, 0x02L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for FLASH Read
// operation (0x02)
JTAG_IRead (FLASHDAT, FLD_RDLEN); // initiate the read operation
JTAG_IWrite (FLASHCON, 0x0L|ucFCONBIT7, FLCN_LEN); // set FLASHCON for ‘poll’ operation
do
{
done = !(JTAG_IRead (FLASHDAT, 1)); // poll for FLBUSY to de-assert
} while (!done);
testval = JTAG_IRead (FLASHDAT, FLD_RDLEN); // read the resulting data
retval = (testval & 0x02) ? FALSE: TRUE; // FLFail is next to LSB
testval = testval >> 2; // shift data.0 into LSB position
*pdat = (unsigned char) testval; // place data in return location
return retval; // return FLASH Pass/Fail
}
unsigned char jtag::CableSetup(unsigned char ucCabtype)
{
DWORD DWTemp;
switch(ucCabtype)
{
case ALTERABLASTER:
{
m_wiTDOPin = 7;
m_iTDOAddP = 1;
m_woTCKPin = 0;
m_woTMSPin = 1;
m_woTDIPin = 6;
b_TDONoInv = FALSE;
SetPortVal(m_nPort+2, 0x0f, 1); //244使能 OE = 0,
GetPortVal(m_nPort+1,&DWTemp,1); //读取
DWTemp = DWTemp & 0x08;
if (!DWTemp) //DB25-15为低,连接OK
{
OutputDebugString("DB25-15连接OK");
}
else
{
OutputDebugString("DB25-15与GND连接失败!");
return 1;
}
//判断DB25 7-10脚是否相连
SetPortVal(m_nPort, 0x20, 1); //设置DB25-7为高,以读取DB25-10的电平
GetPortVal(m_nPort+1,&DWTemp,1); //读取
DWTemp = DWTemp & 0x40; //DB25-10为高,连接OK
if (DWTemp)
{
OutputDebugString("DB25-7 -- 10 高测试OK");
}
else
{
OutputDebugString("DB25-7 -- 10 连接失败");
return 2;
}
SetPortVal(m_nPort, 0x00, 1); //设置DB25-7为高,以读取DB25-10的电平
GetPortVal(m_nPort+1,&DWTemp,1); //读取
DWTemp = DWTemp & 0x40; //DB25-10为低,连接OK
if (!DWTemp)
{
OutputDebugString("DB25-7 -- 10 低测试OK");
}
else
{
OutputDebugString("DB25-7 -- 10 连接失败");
return 3;
}
}break;
case PARALLELIII:
{
m_wiTDOPin = 4;
m_iTDOAddP = 1;
m_woTCKPin = 1;
m_woTMSPin = 2;
m_woTDIPin = 0;
b_TDONoInv = TRUE;
SetPortVal(m_nPort, 0x40, 1); //设置DB25-8为高,以读取Db25- 11,12引脚电平, 74125 C脚低(使能)
GetPortVal(m_nPort+1,&DWTemp,1); //读取11,12电平, 0X1x xxxx
if ((DWTemp | 0x7F)==0x7F) //11脚为低
{
TRACE("连接11(低)脚成功!");
}
else
{
TRACE("连接11(低)脚失败!");
return 3;
}
if ((DWTemp & 0x20)==0x20) //13脚为高
{
TRACE("连接31脚成功!");
}
else
{
TRACE("连接13脚失败!");
return 4;
}
}break;
default:
{
TRACE("Error select cable type!!!");
}
}
JTAG_Reset (); // Reset the JTAG state machine on DUT
return 0;
}
unsigned long jtag::JtagGetIDCode()
{
unsigned long ulid;
JTAG_IR_Scan (RESET, INST_LENGTH); // Reset the DUT
JTAG_IR_Scan (IDCODE, INST_LENGTH); // load IDCODE into IR and HALT the DUT
ulid = JTAG_DR_Scan (0x0L, IDCODE_LEN); // read the IDCODE
TRACE("ID号是:0x%08X",ulid);
return ulid;
}
void jtag::ResetCpu()
{
JTAG_Reset (); // Reset the JTAG state machine on DUT
JTAG_IR_Scan (IDCODE&0x0FFF, INST_LENGTH); // Reset the DUT
}
int jtag::SelectCPU(unsigned int uiCouType)
{
switch(uiCouType)
{
case C8051F020:
{
FLA_LEN = 16; //16 // number of bits in FLASHADR
}break;
case C8051F120:
{
FLA_LEN = 17; //17 // number of bits in FLASHADR
}break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -