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

📄 jtag.c

📁 使用JTAG口对AT91R40008芯片进行FLASH编程的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		Current_Scan_Chain = -1;	//* necessary to execute the next select_scan_chain
		
		//* Be Careful, there is a bug on polling bits at 32kHz
		//* Wait States are needed
		if (bug){
			for (i=0; i<ADD_WAIT_STATE; i++);	
		}
		
		//* Polling of the bits DBGACK and nMREQ 
		if (JTAG_Test_Is_Breaked(WATCHDOG) != 1){
			at91_print(&COM0,"\n\rTHE CORE IS NOT STOPPED !!!\n\r");	
		}	

		
		//* Return to Debug Scan chain
		JTAG_Select_Scan_Chain(DEBUG);
    
    //* Read the result in R1
	JTAG_Read_Register(1, value);	
    
    //* Restore registers values
    JTAG_Write_Register(0, reg0);    
    JTAG_Write_Register(1, reg1);
	
	return;	
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Write_Memory
//* Object              : Set a value in memory
//* Input Parameters    : address
//* Output Parameters   : value
//* Functions called    : JTAG_Nop, JTAG_Execute
//*----------------------------------------------------------------------------
void JTAG_Write_Memory(u_int address, u_int value, u_short halfword, u_short bug){

	u_int i;    
    u_int reg0, reg1;
    
    //* Backup the value of R0 and R1
	JTAG_Read_Register(0, &reg0);    
    JTAG_Read_Register(1, &reg1);
    
    //* Load the value in R1
	JTAG_Write_Register(1, value);
 
    //* Load the address in R0
	JTAG_Write_Register(0, address);
    
    //*********************************************
    //* Execute str r1, [r0], #4 at system speed 
    //*********************************************
   
		//* Select the Debug Scan Chain
		JTAG_Select_Scan_Chain(DEBUG);

		//* Execute a nop to clean the pipe ???
		JTAG_Nop();

		//* Put the system speed flag for the next instruction to execute  
		JTAG_Nop_System_Speed();

		if (halfword){
			//* Execute STRH R1, [R0], #4
			JTAG_Execute(WRITE_MEM_HALFWORD, NULL);
		} else {
			//* Execute STR R1, [R0], #4
			JTAG_Execute(WRITE_MEM, NULL);	
		}
		
		JTAG_Nop();
	
		//* Restart at system speed 
   		JTAG_Shift_ir(RESTART, JTAG_NO_IDLE);	//* Shift RESTART instruction	
	
		Current_Scan_Chain = -1; //* necessary to execute the next select_scan_chain

		//* Be Careful, there is a bug on polling bits at 32kHz
		//* Wait States are needed
		if (bug){
			for (i=0; i<ADD_WAIT_STATE; i++);	
		}
		
		//* Polling of the bits DBGACK and nMREQ 
		if (JTAG_Test_Is_Breaked(WATCHDOG) != 1){
			at91_print(&COM0,"\n\rTHE CORE IS NOT STOPPED !!!\n\r");	
		}
    
    //* Restore registers values
    JTAG_Write_Register(0, reg0);
    JTAG_Write_Register(1, reg1);
	
	return;	
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Stop
//* Object              : Stop the core and put it in debug mode
//* Input Parameters    : none
//* Output Parameters   : none
//* Functions called    : JTAG_Write_ICEBreaker
//*----------------------------------------------------------------------------
void JTAG_Stop(){
	
	//* Set a break on all address activity
	JTAG_Write_ICEBreaker(ICE_WTP0_ADDR_VAL, 0x00000000);
	JTAG_Write_ICEBreaker(ICE_WTP0_ADDR_MASK, 0xFFFFFFFF);	
	
	//* Set a break on all data activity
	JTAG_Write_ICEBreaker(ICE_WTP0_DATA_VAL, 0x00000000);
	JTAG_Write_ICEBreaker(ICE_WTP0_DATA_MASK, 0xFFFFFFFF);

	//* Set the Control registers
	JTAG_Write_ICEBreaker(ICE_WTP0_CTRL_VAL, 0x00000100);	//* Enable bit
	JTAG_Write_ICEBreaker(ICE_WTP0_CTRL_MASK, 0xFFFFFFF7);  

	//* Wait a watchpoint break from the ARM
	at91_print(&COM0,"\n\rWaiting for the ARM to break\n\r");

	Current_Scan_Chain = -1; //* Used for the Test_Is_Breaked function

	//* Polling of the bits DBGACK and nMREQ 	
	if (JTAG_Test_Is_Breaked(WATCHDOG) == TRUE){
		at91_print(&COM0,"The ARM is in debug mode\n\r");
		
		//* Set the Control registers
		JTAG_Write_ICEBreaker(ICE_WTP0_CTRL_VAL, 0x00000000);	//* Disable	Watchpoints
	}	
	else{
		at91_print(&COM0,"The core is NOT stopped !!!\n\r");	
	}

	//* Problem, a reset is needed after a stop
	JTAG_Reset();

	//* Problem on the first read of a register after a stop
	JTAG_Read_Register(R0, NULL);

	return;
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Write_ICEBreaker
//* Object              : Write a data in the register specified by the address
//* Input Parameters    : address, data
//* Output Parameters   : none
//* Functions called    : JTAG_Select_Scan_Chain, JTAG_Write_Bkru
//*----------------------------------------------------------------------------
void JTAG_Write_ICEBreaker(u_char address, u_int data){

	//* Select ICE Breaker Scan Chain
	JTAG_Select_Scan_Chain(ICE_BREAKER);

	//* Write data in the specified register
	JTAG_Write_Bkru(address, data);

	return;
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Read_ICEBreaker
//* Object              : Read a data in the register specified by the address
//* Input Parameters    : address, data
//* Output Parameters   : none
//* Functions called    : JTAG_Select_Scan_Chain, JTAG_Write_Bkru
//*----------------------------------------------------------------------------
void JTAG_Read_ICEBreaker(u_char address, u_int *data){

	//* Select ICE Breaker Scan Chain
	JTAG_Select_Scan_Chain(ICE_BREAKER);

	//* Write data in the specified register
	JTAG_Read_Bkru(address, data);

	return;
}


//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Store_Multiple
//* Object              : Store the specified registers in memory
//* Input Parameters    : address, data
//* Output Parameters   : none
//* Functions called    : JTAG_Select_Scan_Chain, JTAG_Write_Register
//* 					  JTAG_Nop, JTAG_Nop_System_Speed, JTAG_Execute
//* 					  JTAG_Shift_ir, JTAG_Test_Is_Breaked 
//*----------------------------------------------------------------------------
void JTAG_Store_Multiple(u_int address, u_int mask){

	//* Select Debug Scan Chain
	JTAG_Select_Scan_Chain(DEBUG);

	//* Store the address in LR (R14)
	JTAG_Write_Register(LR, address);

	//* Send a nop to clean the pipe ???
	JTAG_Nop();
	
	//* Put the system speed flag for the next instruction to execute  
	JTAG_Nop_System_Speed();

	//* Execute the STM instruction ( stmia R14!, {Ri} )
	JTAG_Execute(STM | mask, NULL);	
		
	JTAG_Nop();
	
	//* Exit from debug mode
	JTAG_Shift_ir(RESTART, JTAG_NO_IDLE);	//* Shift RESTART instruction	
	
	Current_Scan_Chain = -1; //* necessary to execute the next select_scan_chain
		
	//* Polling of the bits DBGACK and nMREQ 
	if (JTAG_Test_Is_Breaked(WATCHDOG) != 1){
		at91_print(&COM0,"\n\rTHE CORE IS NOT STOPPED !!!\n\r");	
	}
    
    //* Select Debug Scan Chain
	JTAG_Select_Scan_Chain(DEBUG);
    
 	return;	
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Load_Multiple
//* Object              : Load the specified datas in registers
//* Input Parameters    : nb_data, *data
//* Output Parameters   : none
//* Functions called    : JTAG_Select_Scan_Chain, JTAG_Nop, JTAG_Execute 
//*----------------------------------------------------------------------------
void JTAG_Load_Multiple(u_int nb_data, u_int *data){

	int i;
	u_int mask = 0x1;
	
	//* Init of the mask to add to the LDM instruction 
	for (i=nb_data; i>0; i--){
		mask |= (1<<(nb_data-i)); 
	}
	
	//* Select Debug Scan Chain
	JTAG_Select_Scan_Chain(DEBUG);	
	
	//* Execute the LDM instruction ( ldmia LR, {R0-Ri} )
	JTAG_Execute(LDM | mask, NULL);	
	
	JTAG_Nop();
	JTAG_Nop();
	
	//* Send the data
	for (i=nb_data; i>0; i--){
		JTAG_Execute(*(data++), NULL);
	}
		
	JTAG_Nop();
	
	//* Test if PC is loaded
	if ((mask & PC_LOADED_MASK) == PC_LOADED_MASK){
		JTAG_Nop();	//* PC = addr
		JTAG_Nop(); //* PC = addr + 4
	}	
	
	//* PC = addr + 8
	
 	return;	
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Go
//* Object              : Restart to an address
//* Input Parameters    : address
//* Output Parameters   : none
//* Functions called    : 
//*----------------------------------------------------------------------------
void JTAG_Go(u_int address){
	
	//* Restore context
	context[PC] = address;
	
	JTAG_Read_Register(R0, NULL); //* avoid crashing
	
	JTAG_Load_Multiple(16, context);
	
	//* Put the system speed flag for the next instruction to execute  
	JTAG_Nop_System_Speed();	
	
	//* Execute  B [PC-5] at system speed (2 for ldm + 2 instructions)
	JTAG_Execute(BRANCH_PC_5, NULL);
	
	//* Exit from debug mode
	JTAG_Shift_ir(RESTART, JTAG_NO_IDLE);	//* Shift RESTART instruction	
	
	Current_Scan_Chain = -1; //* necessary to execute the next select_scan_chain
	
 	return;
}

//*----------------------------------------------------------------------------
//* Function Name       : JTAG_Save_Context
//* Object              : Save the context
//* Input Parameters    : *context_tab
//* Output Parameters   : none
//* Functions called    : 
//*----------------------------------------------------------------------------
void JTAG_Save_Context(u_int *context_tab){
	
	int i;
	u_int mask = 0x00003FFF; //* All registers except LR and PC 
	
	//* Save R0
	JTAG_Read_Register(LR, &context_tab[LR]); //* PC + 0x10 = 4 instructions
	
	//* MOV LR, PC = NOP|0xE00F 	
	JTAG_Execute(NOP|0xE00F, NULL);
	JTAG_Nop();
	JTAG_Nop(); //* 2 or 3 instructions ??	
	
	//* Get Back PC value
	JTAG_Read_Register(LR, &context_tab[PC]);
	
	//* Remove the offset on PC
	context[PC] -= 0x18;
	
	//* Execute the STM instruction ( stmia R14!, {Ri} )
	JTAG_Execute(STM | mask, NULL);	
	JTAG_Nop();
	JTAG_Nop();
	
	for (i=0;i<14;i++){
		JTAG_Execute(NOP, &context_tab[i]);
	}
	
 	return;	
}

//*----------------------------------------------------------------------------
//* Function Name       : Com_Channel_Write_Data
//* Object              : Write a data in the Com Channel
//* Input Parameters    : data
//* Output Parameters   : none
//*----------------------------------------------------------------------------
u_int Com_Channel_Write_Data(u_int value){

	u_int  ctrl_reg, watchdog=0;

	//* Read the Debug Comms Control register
	JTAG_Read_ICEBreaker(ICE_DBG_COM_CTRL, &ctrl_reg);
	
	while ( ((ctrl_reg & R_BIT) == R_BIT) && (watchdog++ < TIMEOUT) ){
		//* Read the Debug Comms Control register
		JTAG_Read_ICEBreaker(ICE_DBG_COM_CTRL, &ctrl_reg);
	}
	
	if (watchdog > TIMEOUT){
		return FALSE;
	}
	
	//* Send the address where to store the data in flash
	JTAG_Write_ICEBreaker(ICE_DBG_COM_DATA, value);

	return TRUE;
}

//*----------------------------------------------------------------------------
//* Function Name       : Com_Channel_Read_Data
//* Object              : Read a data in the Com Channel
//* Input Parameters    : data
//* Output Parameters   : none
//*---------------------------------------------------------------------------
u_int Com_Channel_Read_Data(u_int *value){

	u_int ctrl_reg, watchdog = 0;
	
	//* Read the Debug Comms Control register
	JTAG_Read_ICEBreaker(ICE_DBG_COM_CTRL, &ctrl_reg);
	
	while ( ((ctrl_reg & W_BIT) != W_BIT) && (watchdog++ < TIMEOUT) ){
		//* Read the Debug Comms Control register
		JTAG_Read_ICEBreaker(ICE_DBG_COM_CTRL, &ctrl_reg);
	}
	
	if (watchdog > TIMEOUT){
		return FALSE;
	}
		
	//* Send the address where to store the data in flash
	JTAG_Read_ICEBreaker(ICE_DBG_COM_DATA, value);

	return TRUE;
}

⌨️ 快捷键说明

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