www.pudn.com > C8051JTAG_SRC.rar > 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<> 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  
	dat |= (0x03L << num_bits);			// append ‘WRITE’ opcode to data 
										// load DR with  
	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  
	// 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; 
}