precompute TMS sequencies
This commit is contained in:
parent
0bbf817c92
commit
cceac16fc5
376
src/jtag.cpp
376
src/jtag.cpp
|
|
@ -79,8 +79,7 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
|
||||||
const string &ip_adr, int port,
|
const string &ip_adr, int port,
|
||||||
const bool invert_read_edge, const string &firmware_path):
|
const bool invert_read_edge, const string &firmware_path):
|
||||||
_verbose(verbose > 1),
|
_verbose(verbose > 1),
|
||||||
_state(RUN_TEST_IDLE),
|
_state(UNKNOWN),
|
||||||
_tms_buffer_size(128), _num_tms(0),
|
|
||||||
_board_name("nope"), device_index(0)
|
_board_name("nope"), device_index(0)
|
||||||
{
|
{
|
||||||
switch (cable.type) {
|
switch (cable.type) {
|
||||||
|
|
@ -146,20 +145,111 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
|
||||||
std::cerr << "Jtag: unknown cable type" << std::endl;
|
std::cerr << "Jtag: unknown cable type" << std::endl;
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
_tms_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _tms_buffer_size);
|
create_paths();
|
||||||
if (_tms_buffer == nullptr)
|
|
||||||
throw std::runtime_error("Error: memory allocation failed");
|
|
||||||
memset(_tms_buffer, 0, _tms_buffer_size);
|
|
||||||
|
|
||||||
detectChain(32);
|
detectChain(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Jtag::~Jtag()
|
Jtag::~Jtag()
|
||||||
{
|
{
|
||||||
free(_tms_buffer);
|
|
||||||
delete _jtag;
|
delete _jtag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr static Jtag::tapState_t edges[16][2] = {
|
||||||
|
{Jtag::RUN_TEST_IDLE, Jtag::TEST_LOGIC_RESET}, // TEST_LOGIC_RESET
|
||||||
|
{Jtag::RUN_TEST_IDLE, Jtag::SELECT_DR_SCAN}, // RUN_TEST_IDLE
|
||||||
|
|
||||||
|
{Jtag::CAPTURE_DR, Jtag::SELECT_IR_SCAN}, // SELECT_DR_SCAN
|
||||||
|
{Jtag::SHIFT_DR, Jtag::EXIT1_DR}, // CAPTURE_DR
|
||||||
|
{Jtag::SHIFT_DR, Jtag::EXIT1_DR}, // SHIFT_DR
|
||||||
|
{Jtag::PAUSE_DR, Jtag::UPDATE_DR}, // EXIT1_DR
|
||||||
|
{Jtag::PAUSE_DR, Jtag::EXIT2_DR}, // PAUSE_DR
|
||||||
|
{Jtag::SHIFT_DR, Jtag::UPDATE_DR}, // EXIT2_DR
|
||||||
|
{Jtag::RUN_TEST_IDLE, Jtag::SELECT_DR_SCAN}, // UPDATE_DR
|
||||||
|
|
||||||
|
{Jtag::CAPTURE_IR, Jtag::TEST_LOGIC_RESET}, // SELECT_IR_SCAN
|
||||||
|
{Jtag::SHIFT_IR, Jtag::EXIT1_IR}, // CAPTURE_IR
|
||||||
|
{Jtag::SHIFT_IR, Jtag::EXIT1_IR}, // SHIFT_IR
|
||||||
|
{Jtag::PAUSE_IR, Jtag::UPDATE_IR}, // EXIT1_IR
|
||||||
|
{Jtag::PAUSE_IR, Jtag::EXIT2_IR}, // PAUSE_IR
|
||||||
|
{Jtag::SHIFT_IR, Jtag::UPDATE_IR}, // EXIT2_IR
|
||||||
|
{Jtag::RUN_TEST_IDLE, Jtag::SELECT_DR_SCAN}, // UPDATE_IR, same as UPDATE_DR
|
||||||
|
};
|
||||||
|
|
||||||
|
void Jtag::dive(unsigned origin, unsigned prev, const Path &p) {
|
||||||
|
for (unsigned i = 0; i < 2; ++i) {
|
||||||
|
unsigned x = edges[prev][i];
|
||||||
|
if (paths[origin][x].len <= p.len) continue;
|
||||||
|
Path pn;
|
||||||
|
pn.len = p.len + 1;
|
||||||
|
pn.tms_bits = p.tms_bits | i << p.len;
|
||||||
|
|
||||||
|
paths[origin][x] = pn;
|
||||||
|
dive(origin, x, pn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static const char *getStateName[16] = {
|
||||||
|
"TEST_LOGIC_RESET",
|
||||||
|
"RUN_TEST_IDLE",
|
||||||
|
"SELECT_DR_SCAN",
|
||||||
|
"CAPTURE_DR",
|
||||||
|
"SHIFT_DR",
|
||||||
|
"EXIT1_DR",
|
||||||
|
"PAUSE_DR",
|
||||||
|
"EXIT2_DR",
|
||||||
|
"UPDATE_DR",
|
||||||
|
"SELECT_IR_SCAN",
|
||||||
|
"CAPTURE_IR",
|
||||||
|
"SHIFT_IR",
|
||||||
|
"EXIT1_IR",
|
||||||
|
"PAUSE_IR",
|
||||||
|
"EXIT2_IR",
|
||||||
|
"UPDATE_IR",
|
||||||
|
};
|
||||||
|
|
||||||
|
void Jtag::print_path(tapState_t from, tapState_t to) {
|
||||||
|
uint8_t path = paths[from][to].tms_bits;
|
||||||
|
printf ("Start: %s[%d]\n", getStateName[from], from);
|
||||||
|
tapState_t x = from;
|
||||||
|
for (unsigned i = 0; i < paths[from][to].len; ++i) {
|
||||||
|
unsigned step = path & 1;
|
||||||
|
path >>= 1;
|
||||||
|
x = edges[x][step];
|
||||||
|
printf("\t%d:TMS=%d: -> %s[%d]\n", i + 1, step, getStateName[x], x);
|
||||||
|
}
|
||||||
|
printf("Should arrive at %s[%d]\n", getStateName[x], x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jtag::create_paths() {
|
||||||
|
uint8_t max_len = 0;
|
||||||
|
for (unsigned i = 0; i < 16; ++i) {
|
||||||
|
for (unsigned j = 0; j < 16; ++j) {
|
||||||
|
paths[i][j].len = 0xff;
|
||||||
|
paths[i][j].tms_bits = 0;
|
||||||
|
}
|
||||||
|
Path p = {0, 0};
|
||||||
|
paths[i][i] = p;
|
||||||
|
dive(i, i, p);
|
||||||
|
for (unsigned j = 0; j < 16; ++j) {
|
||||||
|
max_len = std::max(max_len, paths[i][j].len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
printf("max tms sequence is %d\n", max_len);
|
||||||
|
print_path(TEST_LOGIC_RESET, RUN_TEST_IDLE);
|
||||||
|
print_path(RUN_TEST_IDLE, SHIFT_IR);
|
||||||
|
print_path(RUN_TEST_IDLE, SHIFT_DR);
|
||||||
|
print_path(SHIFT_IR, RUN_TEST_IDLE);
|
||||||
|
print_path(SHIFT_DR, PAUSE_DR);
|
||||||
|
print_path(PAUSE_DR, SHIFT_DR);
|
||||||
|
print_path(SHIFT_IR, PAUSE_IR);
|
||||||
|
print_path(PAUSE_IR, SHIFT_DR);
|
||||||
|
print_path(PAUSE_IR, RUN_TEST_IDLE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int Jtag::detectChain(unsigned max_dev)
|
int Jtag::detectChain(unsigned max_dev)
|
||||||
{
|
{
|
||||||
char message[256];
|
char message[256];
|
||||||
|
|
@ -231,7 +321,6 @@ int Jtag::detectChain(unsigned max_dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_state(TEST_LOGIC_RESET);
|
set_state(TEST_LOGIC_RESET);
|
||||||
flushTMS(true);
|
|
||||||
return _devices_list.size();
|
return _devices_list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,53 +384,17 @@ int Jtag::device_select(unsigned index)
|
||||||
return device_index;
|
return device_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jtag::setTMS(unsigned char tms)
|
|
||||||
{
|
|
||||||
display("%s %x %d %d\n", __func__, tms, _num_tms, (_num_tms >> 3));
|
|
||||||
if (_num_tms+1 == _tms_buffer_size * 8)
|
|
||||||
flushTMS(false);
|
|
||||||
if (tms != 0)
|
|
||||||
_tms_buffer[_num_tms>>3] |= (0x1) << (_num_tms & 0x7);
|
|
||||||
_num_tms++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reconstruct byte sent to TMS pins
|
|
||||||
* - use up to 6 bits
|
|
||||||
* -since next bit after length is use to
|
|
||||||
* fix TMS state after sent we copy last bit
|
|
||||||
* to bit after next
|
|
||||||
* -bit 7 is TDI state for each clk cycles
|
|
||||||
*/
|
|
||||||
|
|
||||||
int Jtag::flushTMS(bool flush_buffer)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
if (_num_tms != 0) {
|
|
||||||
display("%s: %d %x\n", __func__, _num_tms, _tms_buffer[0]);
|
|
||||||
|
|
||||||
ret = _jtag->writeTMS(_tms_buffer, _num_tms, flush_buffer);
|
|
||||||
|
|
||||||
/* reset buffer and number of bits */
|
|
||||||
memset(_tms_buffer, 0, _tms_buffer_size);
|
|
||||||
_num_tms = 0;
|
|
||||||
} else if (flush_buffer) {
|
|
||||||
_jtag->flush();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jtag::go_test_logic_reset()
|
void Jtag::go_test_logic_reset()
|
||||||
{
|
{
|
||||||
/* independently to current state 5 clk with TMS high is enough */
|
/* independently to current state 5 clk with TMS high is enough */
|
||||||
for (int i = 0; i < 6; i++)
|
uint8_t bits = 0xff;
|
||||||
setTMS(0x01);
|
_jtag->writeTMS(&bits, 5, false);
|
||||||
flushTMS(false);
|
|
||||||
_state = TEST_LOGIC_RESET;
|
_state = TEST_LOGIC_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Jtag::read_write(const uint8_t *tdi, unsigned char *tdo, int len, char last)
|
int Jtag::read_write(const uint8_t *tdi, unsigned char *tdo, int len, char last)
|
||||||
{
|
{
|
||||||
flushTMS(false);
|
|
||||||
_jtag->writeTDI(tdi, tdo, len, last);
|
_jtag->writeTDI(tdi, tdo, len, last);
|
||||||
if (last == 1)
|
if (last == 1)
|
||||||
_state = (_state == SHIFT_DR) ? EXIT1_DR : EXIT1_IR;
|
_state = (_state == SHIFT_DR) ? EXIT1_DR : EXIT1_IR;
|
||||||
|
|
@ -350,8 +403,7 @@ int Jtag::read_write(const uint8_t *tdi, unsigned char *tdo, int len, char last)
|
||||||
|
|
||||||
void Jtag::toggleClk(int nb)
|
void Jtag::toggleClk(int nb)
|
||||||
{
|
{
|
||||||
unsigned char c = (TEST_LOGIC_RESET == _state) ? 1 : 0;
|
uint8_t c = (TEST_LOGIC_RESET == _state) ? 1 : 0;
|
||||||
flushTMS(false);
|
|
||||||
if (_jtag->toggleClk(c, 0, nb) >= 0)
|
if (_jtag->toggleClk(c, 0, nb) >= 0)
|
||||||
return;
|
return;
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
|
|
@ -365,7 +417,6 @@ int Jtag::shiftDR(const uint8_t *tdi, unsigned char *tdo, int drlen, tapState_t
|
||||||
*/
|
*/
|
||||||
if (_state != SHIFT_DR) {
|
if (_state != SHIFT_DR) {
|
||||||
set_state(SHIFT_DR);
|
set_state(SHIFT_DR);
|
||||||
flushTMS(false); // force transmit tms state
|
|
||||||
|
|
||||||
if (_dr_bits_before)
|
if (_dr_bits_before)
|
||||||
read_write(_dr_bits.data(), NULL, _dr_bits_before, false);
|
read_write(_dr_bits.data(), NULL, _dr_bits_before, false);
|
||||||
|
|
@ -435,226 +486,9 @@ int Jtag::shiftIR(unsigned char *tdi, unsigned char *tdo, int irlen, tapState_t
|
||||||
|
|
||||||
void Jtag::set_state(tapState_t newState)
|
void Jtag::set_state(tapState_t newState)
|
||||||
{
|
{
|
||||||
unsigned char tms = 0;
|
if (_state >= UNKNOWN || newState >= UNKNOWN) {
|
||||||
while (newState != _state) {
|
throw std::exception();
|
||||||
display("_state : %16s(%02d) -> %s(%02d) ",
|
|
||||||
getStateName((tapState_t)_state),
|
|
||||||
_state,
|
|
||||||
getStateName((tapState_t)newState), newState);
|
|
||||||
switch (_state) {
|
|
||||||
case TEST_LOGIC_RESET:
|
|
||||||
if (newState == TEST_LOGIC_RESET) {
|
|
||||||
tms = 1;
|
|
||||||
} else {
|
|
||||||
tms = 0;
|
|
||||||
_state = RUN_TEST_IDLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RUN_TEST_IDLE:
|
|
||||||
if (newState == RUN_TEST_IDLE) {
|
|
||||||
tms = 0;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = SELECT_DR_SCAN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SELECT_DR_SCAN:
|
|
||||||
switch (newState) {
|
|
||||||
case CAPTURE_DR:
|
|
||||||
case SHIFT_DR:
|
|
||||||
case EXIT1_DR:
|
|
||||||
case PAUSE_DR:
|
|
||||||
case EXIT2_DR:
|
|
||||||
case UPDATE_DR:
|
|
||||||
tms = 0;
|
|
||||||
_state = CAPTURE_DR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = SELECT_IR_SCAN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SELECT_IR_SCAN:
|
|
||||||
switch (newState) {
|
|
||||||
case CAPTURE_IR:
|
|
||||||
case SHIFT_IR:
|
|
||||||
case EXIT1_IR:
|
|
||||||
case PAUSE_IR:
|
|
||||||
case EXIT2_IR:
|
|
||||||
case UPDATE_IR:
|
|
||||||
tms = 0;
|
|
||||||
_state = CAPTURE_IR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = TEST_LOGIC_RESET;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* DR column */
|
|
||||||
case CAPTURE_DR:
|
|
||||||
if (newState == SHIFT_DR) {
|
|
||||||
tms = 0;
|
|
||||||
_state = SHIFT_DR;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT1_DR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHIFT_DR:
|
|
||||||
if (newState == SHIFT_DR) {
|
|
||||||
tms = 0;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT1_DR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXIT1_DR:
|
|
||||||
switch (newState) {
|
|
||||||
case PAUSE_DR:
|
|
||||||
case EXIT2_DR:
|
|
||||||
case SHIFT_DR:
|
|
||||||
case EXIT1_DR:
|
|
||||||
tms = 0;
|
|
||||||
_state = PAUSE_DR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = UPDATE_DR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PAUSE_DR:
|
|
||||||
if (newState == PAUSE_DR) {
|
|
||||||
tms = 0;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT2_DR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXIT2_DR:
|
|
||||||
switch (newState) {
|
|
||||||
case SHIFT_DR:
|
|
||||||
case EXIT1_DR:
|
|
||||||
case PAUSE_DR:
|
|
||||||
tms = 0;
|
|
||||||
_state = SHIFT_DR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = UPDATE_DR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UPDATE_DR:
|
|
||||||
case UPDATE_IR:
|
|
||||||
if (newState == RUN_TEST_IDLE) {
|
|
||||||
tms = 0;
|
|
||||||
_state = RUN_TEST_IDLE;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = SELECT_DR_SCAN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* IR column */
|
|
||||||
case CAPTURE_IR:
|
|
||||||
if (newState == SHIFT_IR) {
|
|
||||||
tms = 0;
|
|
||||||
_state = SHIFT_IR;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT1_IR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHIFT_IR:
|
|
||||||
if (newState == SHIFT_IR) {
|
|
||||||
tms = 0;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT1_IR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXIT1_IR:
|
|
||||||
switch (newState) {
|
|
||||||
case PAUSE_IR:
|
|
||||||
case EXIT2_IR:
|
|
||||||
case SHIFT_IR:
|
|
||||||
case EXIT1_IR:
|
|
||||||
tms = 0;
|
|
||||||
_state = PAUSE_IR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = UPDATE_IR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PAUSE_IR:
|
|
||||||
if (newState == PAUSE_IR) {
|
|
||||||
tms = 0;
|
|
||||||
} else {
|
|
||||||
tms = 1;
|
|
||||||
_state = EXIT2_IR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXIT2_IR:
|
|
||||||
switch (newState) {
|
|
||||||
case SHIFT_IR:
|
|
||||||
case EXIT1_IR:
|
|
||||||
case PAUSE_IR:
|
|
||||||
tms = 0;
|
|
||||||
_state = SHIFT_IR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tms = 1;
|
|
||||||
_state = UPDATE_IR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UNKNOWN:;
|
|
||||||
// UNKNOWN should not be valid...
|
|
||||||
throw std::exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
setTMS(tms);
|
|
||||||
display("%d %d %d %x\n", tms, _num_tms-1, _state,
|
|
||||||
_tms_buffer[(_num_tms-1) / 8]);
|
|
||||||
}
|
|
||||||
/* force write buffer */
|
|
||||||
flushTMS(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Jtag::getStateName(tapState_t s)
|
|
||||||
{
|
|
||||||
switch (s) {
|
|
||||||
case TEST_LOGIC_RESET:
|
|
||||||
return "TEST_LOGIC_RESET";
|
|
||||||
case RUN_TEST_IDLE:
|
|
||||||
return "RUN_TEST_IDLE";
|
|
||||||
case SELECT_DR_SCAN:
|
|
||||||
return "SELECT_DR_SCAN";
|
|
||||||
case CAPTURE_DR:
|
|
||||||
return "CAPTURE_DR";
|
|
||||||
case SHIFT_DR:
|
|
||||||
return "SHIFT_DR";
|
|
||||||
case EXIT1_DR:
|
|
||||||
return "EXIT1_DR";
|
|
||||||
case PAUSE_DR:
|
|
||||||
return "PAUSE_DR";
|
|
||||||
case EXIT2_DR:
|
|
||||||
return "EXIT2_DR";
|
|
||||||
case UPDATE_DR:
|
|
||||||
return "UPDATE_DR";
|
|
||||||
case SELECT_IR_SCAN:
|
|
||||||
return "SELECT_IR_SCAN";
|
|
||||||
case CAPTURE_IR:
|
|
||||||
return "CAPTURE_IR";
|
|
||||||
case SHIFT_IR:
|
|
||||||
return "SHIFT_IR";
|
|
||||||
case EXIT1_IR:
|
|
||||||
return "EXIT1_IR";
|
|
||||||
case PAUSE_IR:
|
|
||||||
return "PAUSE_IR";
|
|
||||||
case EXIT2_IR:
|
|
||||||
return "EXIT2_IR";
|
|
||||||
case UPDATE_IR:
|
|
||||||
return "UPDATE_IR";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
}
|
||||||
|
_jtag->writeTMS(&paths[_state][newState].tms_bits, paths[_state][newState].len, false);
|
||||||
|
_state = newState;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/jtag.hpp
18
src/jtag.hpp
|
|
@ -99,11 +99,7 @@ class Jtag {
|
||||||
void toggleClk(int nb);
|
void toggleClk(int nb);
|
||||||
void go_test_logic_reset();
|
void go_test_logic_reset();
|
||||||
void set_state(tapState_t newState);
|
void set_state(tapState_t newState);
|
||||||
int flushTMS(bool flush_buffer = false);
|
void flush() {_jtag->flush();}
|
||||||
void flush() {flushTMS(); _jtag->flush();}
|
|
||||||
void setTMS(unsigned char tms);
|
|
||||||
|
|
||||||
const char *getStateName(tapState_t s);
|
|
||||||
|
|
||||||
/* utilities */
|
/* utilities */
|
||||||
void setVerbose(int8_t verbose){_verbose = verbose;}
|
void setVerbose(int8_t verbose){_verbose = verbose;}
|
||||||
|
|
@ -121,9 +117,6 @@ class Jtag {
|
||||||
bool search_and_insert_device_with_idcode(uint32_t idcode);
|
bool search_and_insert_device_with_idcode(uint32_t idcode);
|
||||||
bool _verbose;
|
bool _verbose;
|
||||||
tapState_t _state;
|
tapState_t _state;
|
||||||
int _tms_buffer_size;
|
|
||||||
int _num_tms;
|
|
||||||
unsigned char *_tms_buffer;
|
|
||||||
std::string _board_name;
|
std::string _board_name;
|
||||||
|
|
||||||
int device_index; /*!< index for targeted FPGA */
|
int device_index; /*!< index for targeted FPGA */
|
||||||
|
|
@ -139,5 +132,14 @@ class Jtag {
|
||||||
|
|
||||||
std::vector<int32_t> _devices_list; /*!< ordered list of devices idcode */
|
std::vector<int32_t> _devices_list; /*!< ordered list of devices idcode */
|
||||||
std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */
|
std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */
|
||||||
|
|
||||||
|
struct Path {
|
||||||
|
uint8_t tms_bits;
|
||||||
|
uint8_t len;
|
||||||
|
} paths[16][16];
|
||||||
|
|
||||||
|
void dive(unsigned origin, unsigned prev, const Path &p);
|
||||||
|
void print_path(tapState_t from, tapState_t to);
|
||||||
|
void create_paths();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue