⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jtag.cpp

📁 C8051F020的下载调试软件和下载线制作电路图。有兴趣做020的朋友可以参考参考。
💻 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 + -