📄 tapctrl.c
字号:
/*
* tapctrl.c :
1). Implement TAP controller state transitions.
2). Implement required JTAG public instructions.
*
* Copyright (C) 2004, OPEN-JTAG, All rights reserved.
*/
#include <windows.h>
#include "jtag.h"
#include "xjerr.h"
#include "tapctrl.h"
/* Used to record the current TAP state */
static int tap_state = TAPSTAT_UNDEFINED;
/*
* TAP state transition array -
* This array descripes the TAP state machine. It is used
* to instruct the TAP state transition.
*/
static const tap_state_t state_trans[NUM_OF_STATES] =
{ {TAPSTAT_SHIFT_DR, TAPSTAT_UPDATE_DR}, //TAPSTAT_EXIT2_DR
{TAPSTAT_PAUSE_DR, TAPSTAT_UPDATE_DR}, //TAPSTAT_EXIT1_DR
{TAPSTAT_SHIFT_DR, TAPSTAT_EXIT1_DR}, //TAPSTAT_SHIFT_DR
{TAPSTAT_PAUSE_DR, TAPSTAT_EXIT2_DR}, //TAPSTAT_PAUSE_DR
{TAPSTAT_CAPTURE_IR, TAPSTAT_TSTLOG_RST}, //TAPSTAT_SELECT_IR_SCAN
{TAPSTAT_RUNTEST_IDLE, TAPSTAT_SELECT_DR_SCAN}, //TAPSTAT_UPDATE_DR
{TAPSTAT_SHIFT_DR, TAPSTAT_EXIT1_DR}, //TAPSTAT_CAPTURE_DR
{TAPSTAT_CAPTURE_DR, TAPSTAT_SELECT_IR_SCAN}, //TAPSTAT_SELECT_DR_SCAN
{TAPSTAT_SHIFT_IR, TAPSTAT_UPDATE_IR}, //TAPSTAT_EXIT2_IR
{TAPSTAT_PAUSE_IR, TAPSTAT_UPDATE_IR}, //TAPSTAT_EXIT1_IR
{TAPSTAT_SHIFT_IR, TAPSTAT_EXIT1_IR}, //TAPSTAT_SHIFT_IR
{TAPSTAT_PAUSE_IR, TAPSTAT_EXIT2_IR}, //TAPSTAT_PAUSE_IR
{TAPSTAT_RUNTEST_IDLE, TAPSTAT_SELECT_DR_SCAN}, //TAPSTAT_RUNTST_IDLE
{TAPSTAT_RUNTEST_IDLE, TAPSTAT_SELECT_DR_SCAN}, //TAPSTAT_UPDATE_IR
{TAPSTAT_SHIFT_IR, TAPSTAT_EXIT1_IR}, //TAPSTAT_CAPTURE_IR
{TAPSTAT_RUNTEST_IDLE, TAPSTAT_TSTLOG_RST}, //TAPSTAT_TSTLOG_RST
};
/*
* tapctrl_next_state() -
* Make TAP controller go to the next adjacent state
* according to the value of tms. Before exit from this
* route, the current state of TAP controller will be
* updated.
*
* @tms: the new logic value for TMS signal, it must be 0 or 1.
*/
static int tapctrl_next_state(u8 tms)
{
if(tap_state < 0x0 || tap_state > 0xF)
return XJERR_TAPSTATE_INVALID;
jtag_wri_tms(tms);
jtag_wri_tck();
if(tms)
tap_state = state_trans[tap_state].next_state[1];
else
tap_state = state_trans[tap_state].next_state[0];
return XJ_OK;
}
/*
* tapctrl_acs_reg() -
* This route is used to access selected test data registers or
* instruction regisger depending on the current TAP controller's
* state. If the TAP controller's state is Shift-DR, selected
* test data register will be accessed. If the TAP controller's
* state is Shift-IR, the instruction register will be accessed.
* When calling this route, please make sure that the current TAP's
* state is Shift-DR or Shift-IR. When return from this route, the
* TAP controller will enter the Exit1-DR/Exit1-IR state.
*
* @bit_len: the length in terms of bit to be shifted into the selected register.
* @shift_in: data to be shifted into the selected register.
* @shift_out: buffer to receive the data shifted out from selected register.
*
* shift_in and shift_out can't both be NULL at the same time.
*/
static int tapctrl_acs_reg(int bit_len, const u32 *shift_in, u32 *shift_out)
{
int bit_idx, word_idx;
u32 wri_data, rd_data;
//Check the current TAP controller's state and the paramaters
if( (tap_state != TAPSTAT_SHIFT_DR) && (tap_state != TAPSTAT_SHIFT_IR) )
return XJ_ERROR;
if(bit_len <= 0)
return XJ_ERROR;
if( (shift_in == NULL) && (shift_out == NULL) )
return XJ_ERROR;
//Access the cells of selected scan chain
for(bit_idx = 0; bit_idx < bit_len; bit_idx++){
//update wri_data and rd_data
if(bit_idx%32 == 0){
word_idx = bit_idx/32;
if(shift_in != NULL)
wri_data = shift_in[word_idx];
else
wri_data = 0;
rd_data = 0;
}
//Write 1 bit
jtag_wri_tdi((u8) (wri_data & 0x1) );
wri_data >>= 1;
/*
* If this is the last bit, enter the next TAP state (Exit1-DR/Exit1-IR).
* Otherwise, stay at current TPA state (Shift-DR/Shift-IR) for further access
*/
if(bit_idx == bit_len - 1)
tapctrl_next_state(1);
else
tapctrl_next_state(0);
//Read 1 bit
if( jtag_rd_rdo() )
rd_data |= (1 << (bit_idx%32));
/* update rd_buf when necessary
* 1). when read 32 bits
* 2). last bit
*/
if( (bit_idx%32 == 31 || bit_idx == bit_len - 1) && shift_out != NULL )
shift_out[word_idx] = rd_data;
}
return XJ_OK;
}
/*
* tapctrl_acs_ireg() -
* This route is used to access JTAG instruction register.
* Please make sure that TAP controller is in the Run-Test/Idle or
* Select-DR-Scan state when calling this route. If the JTAG instruction
* is RESTART, the TAP Controller will enter Run-Test/Idle state b4 returning;
* else, the TAP Controller will enter Select-DR-Scan state b4 returning.
*
* @instruction: public JTAG instruction to be shifted into the instruction
* register.
*/
int tapctrl_acs_ireg(u32 instruction)
{
int status;
int val = 0;
u32 shift_in;
u32 shift_out;
shift_out = 0;
shift_in = instruction;
if(tap_state == TAPSTAT_RUNTEST_IDLE)
tapctrl_next_state(1); //Run-Test/Idle -> Select-DR-Scan
else if(tap_state == TAPSTAT_SELECT_DR_SCAN)
; //Select-DR-Scan -> Select-DR-Scan
else
return XJ_ERROR;
tapctrl_next_state(1); //Select-DR-Scan -> Select-IR-Scan
tapctrl_next_state(0); //Select-IR-Scan -> Capture-IR
tapctrl_next_state(0); //Capture-IR -> Shift-IR
status = tapctrl_acs_reg(4, &shift_in, &shift_out);
tapctrl_next_state(1); //Exit1-IR -> Update-IR
if(instruction == JTAG_RESTART)
tapctrl_next_state(0); //Update-IR -> Run-Test/Idle
else //if(instruction == JTAG_SCAN_N) //添加此行和下一行
//tapctrl_next_state(0); //Update-IR -> Run-Test/Idle
tapctrl_next_state(1); //Update-IR -> Select-DR-Scan
if(status != XJ_OK)
return XJERR_ACSIREG_FAIL;
if(shift_out != 0x1) //访问指令寄存器,TDO必须返回ox1 ??
return XJERR_ACSIREG_FAIL;
return XJ_OK;
}
/*
* tapctrl_acs_dreg() -
* This route is used to access selected data register.
* Please make sure that TAP controller is in the Run-Test/Idle or
* Select-DR-Scan state when calling this route. On returning
* from this route, the TAP Controller will return to Run-Test/Idle
* state.
*
* @bit_len: the length in terms of bit to be shifted into the data register.
* @shift_in: data to be shifted into the data register.
* @shift_out: buffer to receive the data shifted out from data register.
* @run_test: flag used to control enter which state b4 returning.
*/
int tapctrl_acs_dreg(int bit_len, const u32 *shift_in, u32 *shift_out)
{
int status;
int val = 0;
if(tap_state == TAPSTAT_RUNTEST_IDLE)
tapctrl_next_state(1); //Run-Test/Idle -> Select-DR-Scan
else if(tap_state == TAPSTAT_SELECT_DR_SCAN)
; //Select-DR-Scan -> Select-DR-Scan
else
return XJ_ERROR;
tapctrl_next_state(0); //Select-DR-Scan -> Capture-DR
tapctrl_next_state(0); //Capture-DR -> Shift-DR
status = tapctrl_acs_reg(bit_len, shift_in, shift_out);
tapctrl_next_state(1); //Exit1-DR -> Update-DR
tapctrl_next_state(0); //Update-DR -> Run-Test/Idle
if(status != XJ_OK)
return XJERR_ACSIREG_FAIL;
else
return XJ_OK;
}
/*
* tapctrl_reset() -
* This route is used to reset the TAP controller.
* This route will put the TAP controller into the
* Run-Test/Idle state. Please note that this route
* should be called to initialize the TAP controller before
* any operations can be applied to the TAP controller.
*
* There are two methods to reset the TAP controller.
* 1). The optional TRST* input provides for asynchronous initialization of
* the TAP controller. To force the TAP controller into the correct state
* after power-up, nTRST must be driven LOW and then HIGH again. It is
* recommended that TMS should be held at 1 while the signal applied at
* nTRST changes from 0 to 1.
* 2). No matter what the original state of the controller, it will enter Test-
* Logic-Reset when TMS is held high for at least five rising edges of TCK.
* The controller remains in this state while TMS is high.
*/
int tapctrl_reset(void)
{
int i;
//Reset the TAP controller through nTRST
jtag_wri_tms(1);
jtag_wri_ntrst(1); //Drive Low first
Sleep(50);
jtag_wri_ntrst(0); //Drive High
Sleep(50);
//Reset the TAP controller through TMS
for (i = 1; i <= 10; i++){
jtag_wri_tms(1);
jtag_wri_tck();
}
//Update the state of TAP controller
tap_state = TAPSTAT_TSTLOG_RST;
/* Now enter Run-Test/Idle state and stay here */
tapctrl_next_state(0); //Test-Logic Reset -> Run-Test/Idle
tapctrl_next_state(0); //Run-Test/Idle -> Run-Test/Idle
return XJ_OK;
}
/*
* tapctrl_init() -
* This route is used to initialize the TAP Controller by
* calling tapctrl_reset().
*/
int tapctrl_init(void)
{
return tapctrl_reset();
}
/*
* tapctrl_runtest() -
* Produce an TAP state trnasition from the Run-Test/Idle state
* to Run-Test/Idle state.
*/
int tapctrl_runtest(void)
{
if(tap_state != TAPSTAT_RUNTEST_IDLE)
return XJ_ERROR;
else
return tapctrl_next_state(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -