📄 jtag.c
字号:
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, ®0);
JTAG_Read_Register(1, ®1);
//* 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 + -