Move JTAG chain bit init to device_select()

This commit is contained in:
Alexey Starikovskiy 2023-09-04 15:40:51 +03:00 committed by Gwenhael Goavec-Merou
parent 4c39abf51c
commit 67159e8297
2 changed files with 55 additions and 65 deletions

View File

@ -51,9 +51,10 @@ using namespace std;
#endif
/*
* FT232 JTAG PINS MAPPING:
* AD0 -> TCK
* AD1 -> TDI
* AD2 -> TD0
* AD2 -> TDO
* AD3 -> TMS
*/
@ -170,7 +171,7 @@ int Jtag::detectChain(unsigned max_dev)
/* cleanup */
_devices_list.clear();
_irlength_list.clear();
_ir_bits_before = _ir_bits_after = _dr_bits_before = _dr_bits_after = 0;
go_test_logic_reset();
set_state(SHIFT_DR);
@ -259,11 +260,38 @@ bool Jtag::insert_first(uint32_t device_id, uint16_t irlength)
return true;
}
uint16_t Jtag::device_select(uint16_t index)
int Jtag::device_select(unsigned index)
{
if (index > (uint16_t) _devices_list.size())
if (index > _devices_list.size())
return -1;
device_index = index;
/* get number of devices, in the JTAG chain,
* before the selected one
*/
_dr_bits_before = _devices_list.size() - device_index - 1;
/* get number of devices in the JTAG chain
* after the selected one
*/
_dr_bits_after = device_index;
_dr_bits = vector<uint8_t>((std::max(_dr_bits_after, _dr_bits_before) + 7)/8, 0);
/* when the device is not alone and not
* the first a serie of bypass must be
* send to complete send ir sequence
*/
_ir_bits_after = 0;
for (int i = 0; i < device_index; ++i)
_ir_bits_after += _irlength_list[i];
/* send serie of bypass instructions
* final size depends on number of device
* before targeted and irlength of each one
*/
_ir_bits_before = 0;
for (unsigned i = device_index + 1; i < _devices_list.size(); ++i)
_ir_bits_before += _irlength_list[i];
_ir_bits = vector<uint8_t>((std::max(_ir_bits_before, _ir_bits_after) + 7) / 8, 0xff); // BYPASS command is all-ones
return device_index;
}
@ -332,11 +360,6 @@ void Jtag::toggleClk(int nb)
int Jtag::shiftDR(const uint8_t *tdi, unsigned char *tdo, int drlen, tapState_t end_state)
{
/* get number of devices in the JTAG chain
* after the selected one
*/
int bits_after = device_index;
/* if current state not shift DR
* move to this state
*/
@ -344,19 +367,8 @@ int Jtag::shiftDR(const uint8_t *tdi, unsigned char *tdo, int drlen, tapState_t
set_state(SHIFT_DR);
flushTMS(false); // force transmit tms state
/* get number of devices, in the JTAG chain,
* before the selected one
*/
int bits_before = _devices_list.size() - device_index - 1;
/* if not 0 send enough bits
*/
if (bits_before > 0) {
int n = (bits_before + 7) / 8;
uint8_t tx[n];
memset(tx, 0x00, n);
read_write(tx, NULL, bits_before, 0);
}
if (_dr_bits_before)
read_write(_dr_bits.data(), NULL, _dr_bits_before, false);
}
/* write tdi (and read tdo) to the selected device
@ -364,18 +376,15 @@ int Jtag::shiftDR(const uint8_t *tdi, unsigned char *tdo, int drlen, tapState_t
* is the last of the chain and a state change must
* be done
*/
read_write(tdi, tdo, drlen, bits_after == 0 && end_state != SHIFT_DR);
read_write(tdi, tdo, drlen, _dr_bits_after == 0 && end_state != SHIFT_DR);
/* if it's asked to move in FSM */
if (end_state != SHIFT_DR) {
/* if current device is not the last */
if (bits_after > 0) {
int n = (bits_after + 7) / 8;
uint8_t tx[n];
memset(tx, 0x00, n);
read_write(tx, NULL, bits_after, 1); // its the last force
// tms high with last bit
}
if (_dr_bits_after)
read_write(_dr_bits.data(), NULL, _dr_bits_after, true); // its the last force
// tms high with last bit
/* move to end_state */
set_state(end_state);
@ -395,37 +404,12 @@ int Jtag::shiftIR(unsigned char tdi, int irlen, tapState_t end_state)
int Jtag::shiftIR(unsigned char *tdi, unsigned char *tdo, int irlen, tapState_t end_state)
{
display("%s: avant shiftIR\n", __func__);
int bypass_after = 0;
if (end_state != SHIFT_IR) {
/* when the device is not alone and not
* the first a serie of bypass must be
* send to complete send ir sequence
*/
for (int i = 0; i < device_index; i++)
bypass_after += _irlength_list[i];
}
/* if not in SHIFT IR move to this state */
if (_state != SHIFT_IR) {
set_state(SHIFT_IR);
/* force flush */
flushTMS(false);
/* send serie of bypass instructions
* final size depends on number of device
* before targeted and irlength of each one
*/
int bypass_before = 0;
for (unsigned int i = device_index + 1; i < _devices_list.size(); i++)
bypass_before += _irlength_list[i];
/* if > 0 send bits */
if (bypass_before > 0) {
int n = (bypass_before + 7) / 8;
uint8_t tx[n];
memset(tx, 0xff, n);
read_write(tx, NULL, bypass_before, 0);
}
if (_ir_bits_before)
read_write(_ir_bits.data(), NULL, _ir_bits_before, false);
}
display("%s: envoi ircode\n", __func__);
@ -435,17 +419,13 @@ int Jtag::shiftIR(unsigned char *tdi, unsigned char *tdo, int irlen, tapState_t
* is the last of the chain and a state change must
* be done
*/
read_write(tdi, tdo, irlen, bypass_after == 0 && end_state != SHIFT_IR);
read_write(tdi, tdo, irlen, _ir_bits_after == 0 && end_state != SHIFT_IR);
/* it's asked to move out of SHIFT IR state */
if (end_state != SHIFT_IR) {
/* again if devices after fill '1' */
if (bypass_after > 0) {
int n = (bypass_after + 7) / 8;
uint8_t tx[n];
memset(tx, 0xff, n);
read_write(tx, NULL, bypass_after, 1);
}
if (_ir_bits_after > 0)
read_write(_ir_bits.data(), NULL, _ir_bits_after, true);
/* move to the requested state */
set_state(end_state);
}

View File

@ -53,7 +53,7 @@ class Jtag {
* \param[in] index: index in the chain
* \return -1 if index is out of bound, index otherwise
*/
uint16_t device_select(uint16_t index);
int device_select(unsigned index);
/*!
* \brief inject a device into list at the begin
* \param[in] device_id: idcode
@ -127,6 +127,16 @@ class Jtag {
std::string _board_name;
int device_index; /*!< index for targeted FPGA */
// Assume passive devices in JTAG chain are switched to BYPASS mode,
// thus each device requeres 1 bit during SHIFT-DR
unsigned _dr_bits_before, _dr_bits_after;
std::vector<uint8_t> _dr_bits;
// For the above we need for add BYPASS commands for each passive device
unsigned _ir_bits_before, _ir_bits_after;
std::vector<uint8_t> _ir_bits;
std::vector<int32_t> _devices_list; /*!< ordered list of devices idcode */
std::vector<int16_t> _irlength_list; /*!< ordered list of irlength */
};