jtag player: implement XWAITSTATE and XTRST

These new instructions are used by svf2xsvf OpenOCD tool.
This commit is contained in:
ole00 2024-04-12 22:39:05 +01:00
parent fb22c14e9f
commit 7d20d778c6

View File

@ -70,6 +70,8 @@ Arduino usage:
#define XSIR2 21 #define XSIR2 21
#define XCOMMENT 22 #define XCOMMENT 22
#define XWAIT 23 #define XWAIT 23
#define XWAITSTATE 24
#define XTRST 28
#define S_MAX_CHAIN_SIZE_BYTES 129 #define S_MAX_CHAIN_SIZE_BYTES 129
#define S_MAX_CHAIN_SIZE_BITS (S_MAX_CHAIN_SIZE_BYTES * 8) #define S_MAX_CHAIN_SIZE_BITS (S_MAX_CHAIN_SIZE_BYTES * 8)
@ -537,7 +539,7 @@ static void xsvf_jtagtap_state_goto(jtag_port_t* port, uint8_t state) {
} }
} }
static void xsvf_jtagtap_wait_time(jtag_port_t* port, uint32_t microseconds) { static void xsvf_jtagtap_wait_time(jtag_port_t* port, uint32_t microseconds, uint8_t wait_clock) {
uint32_t until; uint32_t until;
if (xsvf->error) { if (xsvf->error) {
@ -545,12 +547,14 @@ static void xsvf_jtagtap_wait_time(jtag_port_t* port, uint32_t microseconds) {
} }
until = micros() + microseconds; until = micros() + microseconds;
while (microseconds--) { if (wait_clock) {
jtag_port_pulse_clock(port); while (microseconds--) {
} jtag_port_pulse_clock(port);
while (micros() < until) { }
}
while (micros() < until) {
jtag_port_pulse_clock(port); jtag_port_pulse_clock(port);
} }
} }
static void xsvf_jtag_sir(jtag_port_t* port) { static void xsvf_jtag_sir(jtag_port_t* port) {
@ -563,7 +567,7 @@ static void xsvf_jtag_sir(jtag_port_t* port) {
xsvf_jtagtap_state_goto(port, xsvf->endir_state); xsvf_jtagtap_state_goto(port, xsvf->endir_state);
} else { } else {
xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE); xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE);
xsvf_jtagtap_wait_time(port, xsvf->runtest); xsvf_jtagtap_wait_time(port, xsvf->runtest, 1);
} }
} }
@ -625,7 +629,7 @@ static uint8_t xsvf_jtag_sdr(jtag_port_t* port, uint8_t flags)
xsvf_jtagtap_state_goto(port, XSTATE_PAUSE_DR); xsvf_jtagtap_state_goto(port, XSTATE_PAUSE_DR);
xsvf_jtagtap_state_goto(port, XSTATE_SHIFT_DR); xsvf_jtagtap_state_goto(port, XSTATE_SHIFT_DR);
xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE); xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE);
xsvf_jtagtap_wait_time(port, xsvf->runtest); xsvf_jtagtap_wait_time(port, xsvf->runtest, 1);
// //
xsvf_jtagtap_state_goto(port, XSTATE_SHIFT_DR); xsvf_jtagtap_state_goto(port, XSTATE_SHIFT_DR);
#if XSVF_DEBUG #if XSVF_DEBUG
@ -645,7 +649,7 @@ static uint8_t xsvf_jtag_sdr(jtag_port_t* port, uint8_t flags)
xsvf_jtagtap_state_goto(port, xsvf->enddr_state); xsvf_jtagtap_state_goto(port, xsvf->enddr_state);
} else { } else {
xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE); xsvf_jtagtap_state_goto(port, XSTATE_RUN_TEST_IDLE);
xsvf_jtagtap_wait_time(port, xsvf->runtest); xsvf_jtagtap_wait_time(port, xsvf->runtest, 1);
} }
} }
@ -833,7 +837,7 @@ static uint8_t xsvf_player_handle_next_instruction(jtag_port_t* port) {
uint8_t c; uint8_t c;
#if XSVF_DEBUG #if XSVF_DEBUG
Serial.println(F("XCOMMENT")); Serial.println(F("XCOMMENT"));
#endif #endif
Serial.print(F("D"));//debug message preamble Serial.print(F("D"));//debug message preamble
//read the comment bytes //read the comment bytes
do { do {
@ -863,26 +867,53 @@ static uint8_t xsvf_player_handle_next_instruction(jtag_port_t* port) {
} else } else
// ---[WAIT ] -------------------------------------------- // ---[WAIT ] --------------------------------------------
if (instruction == XWAIT) { if (instruction == XWAIT || instruction == XWAITSTATE) {
uint32_t clock_cnt = 0;
uint8_t wait_clock = 1;
#if XSVF_DEBUG #if XSVF_DEBUG
Serial.println(F("XWAIT")); Serial.println(instruction == XWAIT ? F("XWAIT") : F("XWAITSTATE"));
#endif #endif
//TOOD - do we need these states to be global? //TOOD - do we need these states to be global?
xsvf->wait_start_state = xsvf_player_get_next_byte(); xsvf->wait_start_state = xsvf_player_get_next_byte();
xsvf->wait_end_state = xsvf_player_get_next_byte(); xsvf->wait_end_state = xsvf_player_get_next_byte();
xsvf->wait_time_usecs = xsvf_player_get_next_long(); if (instruction == XWAITSTATE) {
clock_cnt = xsvf_player_get_next_long();
wait_clock = clock_cnt > 0 ? 1 : 0;
}
#if XSVF_DEBUG
Serial.print(F("Dclock:"));
Serial.println(clock_cnt, DEC);
#endif
xsvf->wait_time_usecs = xsvf_player_get_next_long();
#if XSVF_DEBUG
Serial.print(F("Dmicros:"));
Serial.println( xsvf->wait_time_usecs, DEC);
#endif
xsvf_jtagtap_state_goto(port, xsvf->wait_start_state); xsvf_jtagtap_state_goto(port, xsvf->wait_start_state);
xsvf_jtagtap_wait_time(port, xsvf->wait_time_usecs); // happens only during XWAITSTATE
while (clock_cnt) {
jtag_port_pulse_clock(port);
clock_cnt--;
}
xsvf_jtagtap_wait_time(port, xsvf->wait_time_usecs, wait_clock);
xsvf_jtagtap_state_goto(port, xsvf->wait_end_state); xsvf_jtagtap_state_goto(port, xsvf->wait_end_state);
} else } else
// ---[TRST - test line reset] --------------------------------------------
if (instruction == XTRST) {
#if XSVF_DEBUG
Serial.println(F("XTRST"));
#endif
//read test reset mode (0-on, 1-off, 2-Z, 3-Absent)
xsvf_player_get_next_byte();
} else
// ---[UNKNOWN ] -------------------------------------------- // ---[UNKNOWN ] --------------------------------------------
{ {
#if XSVF_DEBUG #if XSVF_DEBUG
Serial.print(F("XUNKNOWN:")); Serial.print(F("XUNKNOWN:"));
Serial.println(instruction, DEC); Serial.println(instruction, DEC);
#endif #endif
//unimplemented instruction //unimplemented instruction
return ERR_INSTR_NOT_IMPLEMENTED; return ERR_INSTR_NOT_IMPLEMENTED;
} }