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

📄 jtag_ana.c

📁 JTAG协议分析软件,配合周立功的LA1032逻辑分析仪使用,可以观察各种JTAG仿真器的通信过程.
💻 C
字号:
/*
	B0		--		RST
	B1		--		TMS
	B2		--		TCK
	B3		--		TDI
	B4		--		TRST
	B5		--		NU
	B6		--		CHK
	B7		--		TDO
*/

#include "stdio.h"
#include "string.h"
#include "conio.h"
#include "stdlib.h"

#define BIT_REVERSE

#define JTAG_STAT_RESET 0
#define JTAG_STAT_IDLE 1
#define JTAG_STAT_SELECT_DR_SCAN 2
#define JTAG_STAT_CAPTURE_DR 3
#define JTAG_STAT_SHIFT_DR 4
#define JTAG_STAT_EXIT1_DR 5
#define JTAG_STAT_PAUSE_DR 6
#define JTAG_STAT_EXIT2_DR 7
#define JTAG_STAT_UPDATE_DR 8
#define JTAG_STAT_SELECT_IR_SCAN 9
#define JTAG_STAT_CAPTURE_IR 10
#define JTAG_STAT_SHIFT_IR 11
#define JTAG_STAT_EXIT1_IR 12
#define JTAG_STAT_PAUSE_IR 13
#define JTAG_STAT_EXIT2_IR 14
#define JTAG_STAT_UPDATE_IR 15



#define U8 unsigned char
#define UINT unsigned int
#define ULONG unsigned long

#define RST_POS		12
#define TMS_POS		RST_POS+2
#define TCK_POS		TMS_POS+2
#define TDI_POS		TCK_POS+2
#define TRST_POS	TDI_POS+2
#define TDO_POS		TRST_POS+6

typedef union tagPortStatus
{
	struct
	{
		UINT RST : 1;
		UINT TMS : 1;
		UINT TCK : 1;
		UINT TDI : 1;
		UINT TRST : 1;
		UINT CHK : 1;
		UINT TDO : 1;
	}BitField;

	U8 ucValue;
}PortStatus,*pPortStatus;


int main(char argn,char * argv[]);
U8 GetCurrentStatus(void);
void StatemachineProcess(void);
void ShiftIR(void);
void ShiftDR(void);
ULONG BitReverse(ULONG ucDataIn,U8 BitCount);


U8 g_ucCurrentStateMachine;
char g_strCurrentTime[12];

ULONG g_uIRDataIn;
ULONG g_uIRDataOut;
U8 g_ucIRBitCount;

ULONG g_uDRDataIn;
ULONG g_uDRDataOut;
U8 g_ucDRBitCount;

U8 g_bProcessShiftDR;
U8 g_bProcessShiftIR;

FILE * fp;

PortStatus g_PS;


int main(char argn,char * argv[])
{
	U8 bLastTCKStatus = 1;
	U8 bLastRSTStatus = 0;
	PortStatus * pPS;
	char strFilename[100];

	ULONG x = 0x10;

	x=BitReverse(x, 5);

	printf("\n\n");

	if(argn != 2)
	{
		printf("usage: jatg_ana filename\n");
		exit(0);
	}

	pPS = &g_PS;

	strcpy(strFilename,argv[1]);
	if((fp=fopen(strFilename,"rt")) == NULL)
	{
		printf("Open file:%s Error!\n");
		exit(0);
	}

	g_bProcessShiftDR = 0;
	g_bProcessShiftIR = 0;

	g_ucCurrentStateMachine = 0;

	g_ucIRBitCount = 0;
	g_uIRDataIn = 0;
	g_uIRDataOut = 0;

	g_ucDRBitCount = 0;
	g_uDRDataIn = 0;
	g_uDRDataOut = 0;

	fscanf(fp,"%s\n",strFilename);

	if(!GetCurrentStatus())
	{
		printf("Found EOF,Exit!\n");
		fclose(fp);
		exit(0);
	}
	bLastTCKStatus = g_PS.BitField.TCK;
	bLastRSTStatus = g_PS.BitField.RST;

	while(GetCurrentStatus())
	{
		if(bLastRSTStatus != g_PS.BitField.RST)
		{/* Found Reset Change */
			bLastRSTStatus = g_PS.BitField.RST;
			if(g_PS.BitField.RST)
				printf("%s\tRST Assert!\n",g_strCurrentTime);
			else
				printf("%s\tRST DeAssert!\n",g_strCurrentTime);
			bLastTCKStatus = g_PS.BitField.TCK;
			g_ucCurrentStateMachine = JTAG_STAT_RESET;
			continue;
		}

		if((bLastTCKStatus == 0) && (g_PS.BitField.TCK == 1))
		{/* Found a rising edge */
			if(!g_PS.BitField.TRST)
			{
				printf("%s\tTRST Assert!\n",g_strCurrentTime);
				g_ucCurrentStateMachine = JTAG_STAT_RESET;
				bLastTCKStatus = g_PS.BitField.TCK;
				continue;
			}

			StatemachineProcess();
			if(g_bProcessShiftDR)
			{/* Shift DR */
				g_bProcessShiftDR = 0;
				ShiftDR();
				bLastTCKStatus = g_PS.BitField.TCK;
				continue;
			}
			if(g_bProcessShiftIR)
			{
				g_bProcessShiftIR = 0;
				ShiftIR();
				bLastTCKStatus = g_PS.BitField.TCK;
				continue;
			}
		}
		bLastTCKStatus = g_PS.BitField.TCK;
	}
	printf("Found EOF,Exit!\n");
	fclose(fp);
	getch();
	return 0;
}

U8 GetCurrentStatus(void)
{
	char strLine[200];
	char c;
	if(feof(fp))
		return 0;
	fscanf(fp,"%s\n",strLine);

	if(strlen(strLine)<10)
		return 0;

	memcpy(g_strCurrentTime,strLine,11);
	memset(g_strCurrentTime+12,0,1);

	c = strLine[RST_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.RST = 0;
	else
		g_PS.BitField.RST = 1;

	c = strLine[TMS_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.TMS = 0;
	else
		g_PS.BitField.TMS = 1;

	c = strLine[TCK_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.TCK = 0;
	else
		g_PS.BitField.TCK = 1;

	c = strLine[TDI_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.TDI = 0;
	else
		g_PS.BitField.TDI = 1;

	c = strLine[TRST_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.TRST = 0;
	else
		g_PS.BitField.TRST = 1;

	c = strLine[TDO_POS];
	if((c!='0') && (c!='1'))
	{/* File Error */
		printf("File error\n");
		fclose(fp);
		exit(-1);
	}
	if(c == '0')
		g_PS.BitField.TDO = 0;
	else
		g_PS.BitField.TDO = 1;

	return 1;
}

void StatemachineProcess(void)
{
	switch(g_ucCurrentStateMachine)
	{

	case JTAG_STAT_RESET:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_IDLE;
			printf("%s\tEnter IDLE State\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_IDLE :
		if(g_PS.BitField.TMS == 1)
		{
			g_ucCurrentStateMachine = JTAG_STAT_SELECT_DR_SCAN;
			printf("%s\tSELECT_DR_SCAN\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_SELECT_DR_SCAN:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_CAPTURE_DR;
			printf("%s\t\tCAPTURE DR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_SELECT_IR_SCAN;
			printf("%s\tSELECT_IR_SCAN\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_CAPTURE_DR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_SHIFT_DR;
			g_ucDRBitCount = 0;
			g_uDRDataIn = 0;
			g_uDRDataOut = 0;
			printf("%s\t\tSHIFT DR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_EXIT1_DR;
			printf("%s\t\tEXIT1 DR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_SHIFT_DR:
		if(g_PS.BitField.TMS == 1)
		{
			ShiftDR();
			g_ucCurrentStateMachine = JTAG_STAT_EXIT1_DR;
#ifdef BIT_REVERSE
			g_uDRDataIn = BitReverse(g_uDRDataIn,g_ucDRBitCount);
			g_uDRDataOut = BitReverse(g_uDRDataOut,g_ucDRBitCount);
#endif
			printf("%s\t\tEXIT1 DR with In:0x%08X,Out:0x%08X,Bits:%d\n",g_strCurrentTime,g_uDRDataIn,g_uDRDataOut,g_ucDRBitCount);
		}
		else
		{
			g_bProcessShiftDR = 1;
		}
		break;

	case JTAG_STAT_EXIT1_DR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_PAUSE_DR;
			printf("%s\t\tPAUSE DR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_UPDATE_DR;
			printf("%s\t\tUPDATE DR\n",g_strCurrentTime);

		}
		break;

	case JTAG_STAT_PAUSE_DR:
		if(g_PS.BitField.TMS == 1)
		{
			g_ucCurrentStateMachine = JTAG_STAT_EXIT2_DR;
			printf("%s\t\tEXIT2 DR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_EXIT2_DR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_SHIFT_DR;
			g_ucDRBitCount = 0;
			g_uDRDataIn = 0;
			g_uDRDataOut = 0;
			printf("%s\t\tSHIFT DR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_UPDATE_DR;
			printf("%s\t\tUPDATE DR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_UPDATE_DR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_IDLE;
			printf("%s\tEnter IDLE State\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_SELECT_DR_SCAN;
			printf("%s\tSELECT_DR_SCAN\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_SELECT_IR_SCAN:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_CAPTURE_IR;
			printf("%s\t\tCAPTURE IR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_RESET;
			printf("%s\tJTAG RESET\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_CAPTURE_IR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_SHIFT_IR;
			g_ucIRBitCount = 0;
			g_uIRDataIn = 0;
			g_uIRDataOut = 0;
			printf("%s\t\tSHIFT IR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_EXIT1_IR;
			printf("%s\t\tEXIT1 IR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_SHIFT_IR:
		if(g_PS.BitField.TMS == 1)
		{
			ShiftIR();
			g_ucCurrentStateMachine = JTAG_STAT_EXIT1_IR;
#ifdef BIT_REVERSE
			g_uIRDataIn = BitReverse(g_uIRDataIn,g_ucIRBitCount);
			g_uIRDataOut = BitReverse(g_uIRDataOut,g_ucIRBitCount);
#endif

			printf("%s\t\tEXIT1 IR with In:0x%X,Out:0x%X,Bits:%d\n",g_strCurrentTime,g_uIRDataIn,g_uIRDataOut,g_ucIRBitCount);
		}
		else
		{
			g_bProcessShiftIR = 1;
		}
		break;

	case JTAG_STAT_EXIT1_IR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_PAUSE_IR;
			printf("%s\t\tPAUSE IR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_UPDATE_IR;
			printf("%s\t\tUPDATE IR\n",g_strCurrentTime);

		}
		break;

	case JTAG_STAT_PAUSE_IR:
		if(g_PS.BitField.TMS == 1)
		{
			g_ucCurrentStateMachine = JTAG_STAT_EXIT2_IR;
			printf("%s\t\tEXIT2 IR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_EXIT2_IR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_SHIFT_IR;
			g_ucIRBitCount = 0;
			g_uIRDataIn = 0;
			g_uIRDataOut = 0;
			printf("%s\t\tSHIFT IR\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_UPDATE_IR;
			printf("%s\t\tUPDATE IR\n",g_strCurrentTime);
		}
		break;

	case JTAG_STAT_UPDATE_IR:
		if(g_PS.BitField.TMS == 0)
		{
			g_ucCurrentStateMachine = JTAG_STAT_IDLE;
			printf("%s\tEnter IDLE State\n",g_strCurrentTime);
		}
		else
		{
			g_ucCurrentStateMachine = JTAG_STAT_SELECT_DR_SCAN;
			printf("%s\tSELECT_DR_SCAN\n",g_strCurrentTime);
		}
		break;
	default:
		printf("JTAG State machine Error!\n");
		fclose(fp);
		exit(0);
	}
}

void ShiftIR(void)
{
	if(g_PS.BitField.TDI)
	{
		g_uIRDataIn = (g_uIRDataIn<<1)+1;
	}
	else
	{
		g_uIRDataIn <<= 1;
	}

	if(g_PS.BitField.TDO)
	{
		g_uIRDataOut = (g_uIRDataOut<<1)+1;
	}
	else
	{
		g_uIRDataOut <<= 1;
	}

	g_ucIRBitCount ++;
}

void ShiftDR(void)
{
	if(g_PS.BitField.TDI)
	{
		g_uDRDataIn =(g_uDRDataIn<<1)+1;
	}
	else
	{
		g_uDRDataIn <<= 1;
	}

	if(g_PS.BitField.TDO)
	{
		g_uDRDataOut = (g_uDRDataOut<<1)+1;
	}
	else
	{
		g_uDRDataOut <<= 1;
	}

	g_ucDRBitCount ++;
}

ULONG BitReverse(ULONG ucDataIn,U8 BitCount)
{
	unsigned char i;
	ULONG uRet=0;
	for(i=0;i<32;i++)
	{
		uRet |= ((ucDataIn & (1<<i)) >> i) << (31-i);
	}

	uRet >>=  32-BitCount;
	return uRet;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -