all jtag cable: no more hardcoding tdi bit with writeTMS

This commit is contained in:
Gwenhael Goavec-Merou 2023-10-29 06:41:39 +01:00
parent 43ae0d8fdd
commit 59b56bcc95
29 changed files with 54 additions and 37 deletions

View File

@ -136,7 +136,8 @@ int AnlogicCable::setClkFreq(uint32_t clkHZ)
return clkHZ; return clkHZ;
} }
int AnlogicCable::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int AnlogicCable::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute((unused)) const uint8_t tdi)
{ {
(void) flush_buffer; (void) flush_buffer;

View File

@ -25,7 +25,7 @@ class AnlogicCable : public JtagInterface {
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHZ) override;
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */ /* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
/* clk */ /* clk */

View File

@ -268,7 +268,8 @@ int CH347Jtag::_setClkFreq(uint32_t clkHZ)
return _clkHZ; return _clkHZ;
} }
int CH347Jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int CH347Jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
if (get_obuf_length() < (int)(len * 2 + 4)) { // check if there is enough room left if (get_obuf_length() < (int)(len * 2 + 4)) { // check if there is enough room left
flush(); flush();

View File

@ -18,7 +18,7 @@ class CH347Jtag : public JtagInterface {
int setClkFreq(uint32_t clkHZ) override { return _setClkFreq(clkHZ); }; int setClkFreq(uint32_t clkHZ) override { return _setClkFreq(clkHZ); };
int _setClkFreq(uint32_t clkHZ); int _setClkFreq(uint32_t clkHZ);
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */ /* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
/* clk */ /* clk */

View File

@ -88,7 +88,8 @@ int CH552_jtag::setClkFreq(uint32_t clkHZ) {
return ret; return ret;
} }
int CH552_jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int CH552_jtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
(void) flush_buffer; (void) flush_buffer;
display("%s %d %d\n", __func__, len, (len/8)+1); display("%s %d %d\n", __func__, len, (len/8)+1);

View File

@ -32,7 +32,7 @@ class CH552_jtag : public JtagInterface, private FTDIpp_MPSSE {
uint32_t getClkFreq() override {return FTDIpp_MPSSE::getClkFreq();} uint32_t getClkFreq() override {return FTDIpp_MPSSE::getClkFreq();}
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* clock */ /* clock */
int toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) override; int toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) override;
/* TDI */ /* TDI */

View File

@ -313,7 +313,8 @@ int CmsisDAP::setClkFreq(uint32_t clkHZ)
* flush the buffer * flush the buffer
* tms states are written only if max or if flush_buffer set * tms states are written only if max or if flush_buffer set
*/ */
int CmsisDAP::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int CmsisDAP::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
/* nothing to send /* nothing to send
* check if the buffer must be flushed * check if the buffer must be flushed

View File

@ -44,7 +44,7 @@ class CmsisDAP: public JtagInterface {
* \param[in] flush_buffer: force buffer to be send or not * \param[in] flush_buffer: force buffer to be send or not
* \return <= 0 if something wrong, len otherwise * \return <= 0 if something wrong, len otherwise
*/ */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/*! /*!
* \brief write and read len bits with optional tms set to 1 if end * \brief write and read len bits with optional tms set to 1 if end

View File

@ -171,9 +171,10 @@ int DirtyJtag::setClkFreq(uint32_t clkHZ)
return clkHZ; return clkHZ;
} }
int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len,
__attribute__((unused)) bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
(void) flush_buffer;
int actual_length; int actual_length;
if (len == 0) if (len == 0)

View File

@ -25,7 +25,7 @@ class DirtyJtag : public JtagInterface {
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHZ) override;
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */ /* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
/* clk */ /* clk */

View File

@ -116,7 +116,8 @@ int FtdiJtagBitBang::setBitmode(uint8_t mode)
return ret; return ret;
} }
int FtdiJtagBitBang::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int FtdiJtagBitBang::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
int ret; int ret;

View File

@ -31,7 +31,7 @@ class FtdiJtagBitBang : public JtagInterface, private FTDIpp_MPSSE {
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHZ) override;
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */ /* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;

View File

@ -107,10 +107,11 @@ void FtdiJtagMPSSE::config_edge()
} }
} }
int FtdiJtagMPSSE::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int FtdiJtagMPSSE::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi)
{ {
(void) flush_buffer; (void) flush_buffer;
display("%s %d %d\n", __func__, len, (len/8)+1); display("%s %d %d\n", __func__, len, (len/8)+1);
uint8_t curr_tdi = (tdi << 7);
if (len == 0) if (len == 0)
return 0; return 0;
@ -123,14 +124,17 @@ int FtdiJtagMPSSE::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer)
MPSSE_BITMODE | _write_mode), MPSSE_BITMODE | _write_mode),
0, 0}; 0, 0};
while (xfer > 0) { while (xfer > 0) {
uint8_t curr_tms = 0;
int bit_to_send = (xfer > 6) ? 6 : xfer; int bit_to_send = (xfer > 6) ? 6 : xfer;
buf[1] = bit_to_send-1; buf[1] = bit_to_send-1;
buf[2] = 0x80; buf[2] = curr_tdi;
for (int i = 0; i < bit_to_send; i++, offset++) { for (int i = 0; i < bit_to_send; i++, offset++) {
buf[2] |= curr_tms = ((tms[offset >> 3] & (1 << (offset & 0x07))) ? 1 : 0);
(((tms[offset >> 3] & (1 << (offset & 0x07))) ? 1 : 0) << i);
buf[2] |= (curr_tms << i);
} }
buf[2] |= (curr_tms << bit_to_send);
pos+=3; pos+=3;
mpsse_store(buf, 3); mpsse_store(buf, 3);
@ -230,8 +234,8 @@ int FtdiJtagMPSSE::writeTDI(const uint8_t *tdi, uint8_t *tdo, uint32_t len, bool
static_cast<unsigned char>((xfer - 1) & 0xff), // low static_cast<unsigned char>((xfer - 1) & 0xff), // low
static_cast<unsigned char>((((xfer - 1) >> 8) & 0xff))}; // high static_cast<unsigned char>((((xfer - 1) >> 8) & 0xff))}; // high
display("%s len : %d %d %d %d\n", __func__, len, real_len, nb_byte, display("%s len : %d %d %d %d last: %d\n", __func__, len, real_len, nb_byte,
nb_bit); nb_bit, last);
if ((nb_byte + _num + 3) > _buffer_size) if ((nb_byte + _num + 3) > _buffer_size)
mpsse_write(); mpsse_write();

View File

@ -58,7 +58,7 @@ class FtdiJtagMPSSE : public JtagInterface, public FTDIpp_MPSSE {
} }
/* TMS */ /* TMS */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* clock */ /* clock */
int toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) override; int toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) override;
/* TDI */ /* TDI */

View File

@ -209,7 +209,8 @@ int JetsonNanoJtagBitbang::setClkFreq(__attribute__((unused)) uint32_t clkHZ)
} }
int JetsonNanoJtagBitbang::writeTMS(uint8_t *tms_buf, uint32_t len, int JetsonNanoJtagBitbang::writeTMS(uint8_t *tms_buf, uint32_t len,
__attribute__((unused)) bool flush_buffer) __attribute__((unused)) bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
int tms; int tms;

View File

@ -53,7 +53,7 @@ class JetsonNanoJtagBitbang : public JtagInterface {
virtual ~JetsonNanoJtagBitbang(); virtual ~JetsonNanoJtagBitbang();
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHZ) override;
int writeTMS(uint8_t *tms_buf, uint32_t len, bool flush_buffer) override; int writeTMS(uint8_t *tms_buf, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
int writeTDI(uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override; int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override;

View File

@ -89,7 +89,8 @@ Jlink::~Jlink()
libusb_exit(jlink_ctx); libusb_exit(jlink_ctx);
} }
int Jlink::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int Jlink::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
// empty buffer // empty buffer
// if asked flush // if asked flush

View File

@ -44,7 +44,7 @@ class Jlink: public JtagInterface {
* \param[in] flush_buffer: force buffer to be send or not * \param[in] flush_buffer: force buffer to be send or not
* \return <= 0 if something wrong, len otherwise * \return <= 0 if something wrong, len otherwise
*/ */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/*! /*!
* \brief write and read len bits with optional tms set to 1 if end * \brief write and read len bits with optional tms set to 1 if end

View File

@ -81,7 +81,7 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
_verbose(verbose > 1), _verbose(verbose > 1),
_state(RUN_TEST_IDLE), _state(RUN_TEST_IDLE),
_tms_buffer_size(128), _num_tms(0), _tms_buffer_size(128), _num_tms(0),
_board_name("nope"), device_index(0) _board_name("nope"), device_index(0), _curr_tdi(1)
{ {
switch (cable.type) { switch (cable.type) {
case MODE_ANLOGICCABLE: case MODE_ANLOGICCABLE:
@ -319,7 +319,7 @@ int Jtag::flushTMS(bool flush_buffer)
if (_num_tms != 0) { if (_num_tms != 0) {
display("%s: %d %x\n", __func__, _num_tms, _tms_buffer[0]); display("%s: %d %x\n", __func__, _num_tms, _tms_buffer[0]);
ret = _jtag->writeTMS(_tms_buffer, _num_tms, flush_buffer); ret = _jtag->writeTMS(_tms_buffer, _num_tms, flush_buffer, _curr_tdi);
/* reset buffer and number of bits */ /* reset buffer and number of bits */
memset(_tms_buffer, 0, _tms_buffer_size); memset(_tms_buffer, 0, _tms_buffer_size);
@ -433,8 +433,9 @@ int Jtag::shiftIR(unsigned char *tdi, unsigned char *tdo, int irlen, tapState_t
return 0; return 0;
} }
void Jtag::set_state(tapState_t newState) void Jtag::set_state(tapState_t newState, const uint8_t tdi)
{ {
_curr_tdi = tdi;
unsigned char tms = 0; unsigned char tms = 0;
while (newState != _state) { while (newState != _state) {
display("_state : %16s(%02d) -> %s(%02d) ", display("_state : %16s(%02d) -> %s(%02d) ",

View File

@ -119,7 +119,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, const uint8_t tdi = 1);
int flushTMS(bool flush_buffer = false); int flushTMS(bool flush_buffer = false);
void flush() {flushTMS(); _jtag->flush();} void flush() {flushTMS(); _jtag->flush();}
void setTMS(unsigned char tms); void setTMS(unsigned char tms);
@ -160,5 +160,6 @@ 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 */
uint8_t _curr_tdi;
}; };
#endif #endif

View File

@ -53,7 +53,7 @@ class JtagInterface {
* \param len: number of bit to send * \param len: number of bit to send
* \return number of bit send/received * \return number of bit send/received
*/ */
virtual int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) = 0; virtual int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) = 0;
/*! /*!
* \brief send TDI bits (mainly in shift DR/IR state) * \brief send TDI bits (mainly in shift DR/IR state)

View File

@ -292,7 +292,8 @@ int LibgpiodJtagBitbang::setClkFreq(__attribute__((unused)) uint32_t clkHZ)
} }
int LibgpiodJtagBitbang::writeTMS(const uint8_t *tms_buf, uint32_t len, int LibgpiodJtagBitbang::writeTMS(const uint8_t *tms_buf, uint32_t len,
__attribute__((unused)) bool flush_buffer) __attribute__((unused)) bool flush_buffer,
__attribute__((unused)) uint8_t tdi)
{ {
int tms; int tms;

View File

@ -33,7 +33,7 @@ class LibgpiodJtagBitbang : public JtagInterface {
virtual ~LibgpiodJtagBitbang(); virtual ~LibgpiodJtagBitbang();
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHZ) override;
int writeTMS(const uint8_t *tms_buf, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms_buf, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;
int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override; int toggleClk(uint8_t tms, uint8_t tdo, uint32_t clk_len) override;

View File

@ -77,7 +77,7 @@ RemoteBitbang_client::~RemoteBitbang_client()
} }
int RemoteBitbang_client::writeTMS(const uint8_t *tms, uint32_t len, int RemoteBitbang_client::writeTMS(const uint8_t *tms, uint32_t len,
bool flush_buffer) bool flush_buffer, __attribute__((unused)) const uint8_t tdi)
{ {
// empty buffer // empty buffer
// if asked flush // if asked flush

View File

@ -43,7 +43,7 @@ class RemoteBitbang_client: public JtagInterface {
* \param[in] flush_buffer: force buffer to be send or not * \param[in] flush_buffer: force buffer to be send or not
* \return <= 0 if something wrong, len otherwise * \return <= 0 if something wrong, len otherwise
*/ */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/*! /*!
* \brief write and read len bits with optional tms set to 1 if end * \brief write and read len bits with optional tms set to 1 if end

View File

@ -89,7 +89,8 @@ uint32_t UsbBlaster::getClkFreq()
return ll_driver->getClkFreq(); return ll_driver->getClkFreq();
} }
int UsbBlaster::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int UsbBlaster::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
int ret; int ret;

View File

@ -54,7 +54,7 @@ class UsbBlaster : public JtagInterface {
* \param flush_buffer force flushing the buffer * \param flush_buffer force flushing the buffer
* \return number of state written * \return number of state written
* */ * */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */ /* TDI */
int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override; int writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end) override;

View File

@ -87,7 +87,8 @@ XVC_client::~XVC_client()
close(_sock); close(_sock);
} }
int XVC_client::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) int XVC_client::writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer,
__attribute__((unused)) const uint8_t tdi)
{ {
// empty buffer // empty buffer
// if asked flush // if asked flush

View File

@ -43,7 +43,7 @@ class XVC_client: public JtagInterface {
* \param[in] flush_buffer: force buffer to be send or not * \param[in] flush_buffer: force buffer to be send or not
* \return <= 0 if something wrong, len otherwise * \return <= 0 if something wrong, len otherwise
*/ */
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/*! /*!
* \brief write and read len bits with optional tms set to 1 if end * \brief write and read len bits with optional tms set to 1 if end