Move JTAG chain bit init to device_select()
This commit is contained in:
parent
4c39abf51c
commit
67159e8297
108
src/jtag.cpp
108
src/jtag.cpp
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
12
src/jtag.hpp
12
src/jtag.hpp
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue