Update JTAG chain detect
This commit is contained in:
parent
fc6f3fb8e1
commit
d3410e0e30
71
src/jtag.cpp
71
src/jtag.cpp
|
|
@ -151,7 +151,7 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
|
||||||
throw std::runtime_error("Error: memory allocation failed");
|
throw std::runtime_error("Error: memory allocation failed");
|
||||||
memset(_tms_buffer, 0, _tms_buffer_size);
|
memset(_tms_buffer, 0, _tms_buffer_size);
|
||||||
|
|
||||||
detectChain(5);
|
detectChain(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Jtag::~Jtag()
|
Jtag::~Jtag()
|
||||||
|
|
@ -159,13 +159,13 @@ Jtag::~Jtag()
|
||||||
free(_tms_buffer);
|
free(_tms_buffer);
|
||||||
delete _jtag;
|
delete _jtag;
|
||||||
}
|
}
|
||||||
int Jtag::detectChain(int max_dev)
|
int Jtag::detectChain(unsigned max_dev)
|
||||||
{
|
{
|
||||||
char message[256];
|
char message[256];
|
||||||
unsigned char rx_buff[4];
|
uint8_t rx_buff[4];
|
||||||
/* WA for CH552/tangNano: write is always mandatory */
|
/* WA for CH552/tangNano: write is always mandatory */
|
||||||
unsigned char tx_buff[4] = {0xff, 0xff, 0xff, 0xff};
|
uint8_t tx_buff[4] = {0xff, 0xff, 0xff, 0xff};
|
||||||
unsigned int tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
_devices_list.clear();
|
_devices_list.clear();
|
||||||
|
|
@ -177,47 +177,56 @@ int Jtag::detectChain(int max_dev)
|
||||||
if (_verbose)
|
if (_verbose)
|
||||||
printInfo("Raw IDCODE:");
|
printInfo("Raw IDCODE:");
|
||||||
|
|
||||||
for (int i = 0; i < max_dev; i++) {
|
for (unsigned i = 0; i < max_dev; ++i) {
|
||||||
read_write(tx_buff, rx_buff, 32, (i == max_dev-1)?1:0);
|
read_write(tx_buff, rx_buff, 32, (i == max_dev-1)?1:0);
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
for (int ii=0; ii < 4; ii++)
|
for (int ii = 0; ii < 4; ++ii)
|
||||||
tmp |= (rx_buff[ii] << (8*ii));
|
tmp |= (rx_buff[ii] << (8 * ii));
|
||||||
|
|
||||||
if (_verbose) {
|
if (_verbose) {
|
||||||
snprintf(message, sizeof(message), "- %d -> 0x%08x", i, tmp);
|
snprintf(message, sizeof(message), "- %d -> 0x%08x", i, tmp);
|
||||||
printInfo(message);
|
printInfo(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tmp == 0) {
|
||||||
|
throw std::runtime_error("TDO is stuck at 0");
|
||||||
|
}
|
||||||
|
if (tmp == 0xffffffff) {
|
||||||
|
if (_verbose) {
|
||||||
|
snprintf(message, sizeof(message), "Fetched TDI, end-of-chain");
|
||||||
|
printInfo(message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* search IDCODE in fpga_list and misc_dev_list
|
/* search IDCODE in fpga_list and misc_dev_list
|
||||||
* since most device have idcode with high nibble masked
|
* since most device have idcode with high nibble masked
|
||||||
* we start to search sub IDCODE
|
* we start to search sub IDCODE
|
||||||
* if IDCODE has no match: try the same with version unmasked
|
* if IDCODE has no match: try the same with version unmasked
|
||||||
*/
|
*/
|
||||||
if (tmp != 0 && tmp != 0xffffffff) {
|
bool found = false;
|
||||||
bool found = false;
|
/* ckeck highest nibble to prevent confusion between Cologne Chip
|
||||||
/* ckeck highest nibble to prevent confusion between Cologne Chip
|
* GateMate and Efinix Trion T4/T8 devices
|
||||||
* GateMate and Efinix Trion T4/T8 devices
|
*/
|
||||||
*/
|
if (tmp == 0x20000001)
|
||||||
if (tmp == 0x20000001)
|
found = search_and_insert_device_with_idcode(tmp);
|
||||||
found = search_and_insert_device_with_idcode(tmp);
|
if (!found) /* not specific case -> search for full */
|
||||||
if (!found) /* not specific case -> search for full */
|
found = search_and_insert_device_with_idcode(tmp);
|
||||||
found = search_and_insert_device_with_idcode(tmp);
|
if (!found) /* if full idcode not found -> search for masked */
|
||||||
if (!found) /* if full idcode not found -> search for masked */
|
found = search_and_insert_device_with_idcode(tmp & 0x0fffffff);
|
||||||
found = search_and_insert_device_with_idcode(tmp & 0x0fffffff);
|
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
uint16_t mfg = IDCODE2MANUFACTURERID(tmp);
|
uint16_t mfg = IDCODE2MANUFACTURERID(tmp);
|
||||||
uint8_t part = IDCODE2PART(tmp);
|
uint8_t part = IDCODE2PART(tmp);
|
||||||
uint8_t vers = IDCODE2VERS(tmp);
|
uint8_t vers = IDCODE2VERS(tmp);
|
||||||
|
|
||||||
char error[1024];
|
char error[1024];
|
||||||
snprintf(error, sizeof(error),
|
snprintf(error, sizeof(error),
|
||||||
"Unknown device with IDCODE: 0x%08x"
|
"Unknown device with IDCODE: 0x%08x"
|
||||||
" (manufacturer: 0x%03x (%s),"
|
" (manufacturer: 0x%03x (%s),"
|
||||||
" part: 0x%02x vers: 0x%x", tmp,
|
" part: 0x%02x vers: 0x%x", tmp,
|
||||||
mfg, list_manufacturer[mfg].c_str(), part, vers);
|
mfg, list_manufacturer[mfg].c_str(), part, vers);
|
||||||
throw std::runtime_error(error);
|
throw std::runtime_error(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
go_test_logic_reset();
|
go_test_logic_reset();
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class Jtag {
|
||||||
* vector with irlength
|
* vector with irlength
|
||||||
* \return number of devices found
|
* \return number of devices found
|
||||||
*/
|
*/
|
||||||
int detectChain(int max_dev);
|
int detectChain(unsigned int max_dev);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief return list of devices in the chain
|
* \brief return list of devices in the chain
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue