dirtyJtag: doc + nitpick

This commit is contained in:
Gwenhael Goavec-Merou 2026-03-12 18:25:19 +01:00
parent 85be4fa02b
commit 54595299d5
2 changed files with 54 additions and 35 deletions

View File

@ -52,7 +52,6 @@ struct version_specific
static version_specific v_options[4] ={{0, 240}, {0, 240}, {NO_READ, 496}, static version_specific v_options[4] ={{0, 240}, {0, 240}, {NO_READ, 496},
{NO_READ, 4000}}; {NO_READ, 4000}};
enum dirtyJtagSig { enum dirtyJtagSig {
SIG_TCK = (1 << 1), SIG_TCK = (1 << 1),
SIG_TDI = (1 << 2), SIG_TDI = (1 << 2),
@ -62,7 +61,7 @@ enum dirtyJtagSig {
SIG_SRST = (1 << 6) SIG_SRST = (1 << 6)
}; };
DirtyJtag::DirtyJtag(uint32_t clkHZ, int8_t verbose, uint16_t vid, uint16_t pid): DirtyJtag::DirtyJtag(uint32_t clkHz, int8_t verbose, uint16_t vid, uint16_t pid):
_verbose(verbose), _verbose(verbose),
dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0), _version(0) dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0), _version(0)
{ {
@ -91,7 +90,7 @@ DirtyJtag::DirtyJtag(uint32_t clkHZ, int8_t verbose, uint16_t vid, uint16_t pid)
if (!getVersion()) if (!getVersion())
throw std::runtime_error("Fail to get version"); throw std::runtime_error("Fail to get version");
if (setClkFreq(clkHZ) < 0) { if (setClkFreq(clkHz) < 0) {
cerr << "Fail to set frequency" << endl; cerr << "Fail to set frequency" << endl;
throw std::exception(); throw std::exception();
} }
@ -140,24 +139,24 @@ bool DirtyJtag::getVersion()
return true; return true;
} }
int DirtyJtag::setClkFreq(uint32_t clkHZ) int DirtyJtag::setClkFreq(uint32_t clkHz)
{ {
int actual_length; int actual_length;
int ret, req_freq = clkHZ; int ret, req_freq = clkHz;
if (clkHZ > 16000000) { if (clkHz > 16000000) {
printWarn("DirtyJTAG probe limited to 16000 kHz"); printWarn("DirtyJTAG probe limited to 16000 kHz");
clkHZ = 16000000; clkHz = 16000000;
} }
_clkHZ = clkHZ; _clkHZ = clkHz;
printInfo("Jtag frequency : requested " + std::to_string(req_freq) + printInfo("Jtag frequency : requested " + std::to_string(req_freq) +
"Hz -> real " + std::to_string(clkHZ) + "Hz"); " Hz -> real " + std::to_string(clkHz) + " Hz");
uint8_t buf[] = {CMD_FREQ, uint8_t buf[] = {CMD_FREQ,
static_cast<uint8_t>(0xff & ((clkHZ / 1000) >> 8)), static_cast<uint8_t>(0xff & ((clkHz / 1000) >> 8)),
static_cast<uint8_t>(0xff & ((clkHZ / 1000) )), static_cast<uint8_t>(0xff & ((clkHz / 1000) )),
CMD_STOP}; CMD_STOP};
ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP, ret = libusb_bulk_transfer(dev_handle, DIRTYJTAG_WRITE_EP,
buf, 4, &actual_length, DIRTYJTAG_TIMEOUT); buf, 4, &actual_length, DIRTYJTAG_TIMEOUT);
@ -166,7 +165,7 @@ int DirtyJtag::setClkFreq(uint32_t clkHZ)
return -EXIT_FAILURE; return -EXIT_FAILURE;
} }
return clkHZ; return clkHz;
} }
int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len, int DirtyJtag::writeTMS(const uint8_t *tms, uint32_t len,
@ -320,7 +319,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
} }
/* Last xfer: /* Last xfer:
* if bit_to_send is not a multiple of 8bits a shift must * if bit_to_send is not a multiple of 8bits a shift must
* be applied to align rigth the last Byte * be applied to align right the last Byte
*/ */
if (bit_to_send < max_bit_transfer_length) { if (bit_to_send < max_bit_transfer_length) {
const uint32_t b = (bit_to_send >> 3) << 3; // floor const uint32_t b = (bit_to_send >> 3) << 3; // floor
@ -336,7 +335,7 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
tx_ptr += byte_to_send; tx_ptr += byte_to_send;
} }
/* this step exist only with [D|I]R_SHIFT */ /* Final single-bit step used only for DR/IR SHIFT end transitions. */
if (end) { if (end) {
int pos = len-1; int pos = len-1;
uint8_t sig; uint8_t sig;
@ -395,8 +394,8 @@ int DirtyJtag::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len, bool end)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* GPIOs */ /* GPIO helpers */
/* Read GPIOs */ /* Read GPIO signal state */
uint8_t DirtyJtag::gpio_get() uint8_t DirtyJtag::gpio_get()
{ {
int actual_length; int actual_length;
@ -437,12 +436,13 @@ bool DirtyJtag::_set_gpio_level(uint8_t gpio, uint8_t val)
return true; return true;
} }
/* update selected gpio */ /* Set selected GPIO bits */
bool DirtyJtag::gpio_set(uint8_t gpio) bool DirtyJtag::gpio_set(uint8_t gpio)
{ {
return _set_gpio_level(gpio, gpio); return _set_gpio_level(gpio, gpio);
} }
/* Clear selected GPIO bits */
bool DirtyJtag::gpio_clear(uint8_t gpio) bool DirtyJtag::gpio_clear(uint8_t gpio)
{ {
return _set_gpio_level(gpio, 0); return _set_gpio_level(gpio, 0);

View File

@ -11,24 +11,45 @@
#include "jtagInterface.hpp" #include "jtagInterface.hpp"
/*! /*!
* \file DirtyJtag.hpp * \file dirtyJtag.hpp
* \class DirtyJtag * \class DirtyJtag
* \brief concrete class between jtag implementation and FTDI capable bitbang mode * \brief concrete class between jtag implementation and DirtyJTAG probe
* \author Gwenhael Goavec-Merou * \author Gwenhael Goavec-Merou
*/ */
class DirtyJtag : public JtagInterface { class DirtyJtag : public JtagInterface {
public: public:
DirtyJtag(uint32_t clkHZ, int8_t verbose, uint16_t vid = 0x1209, uint16_t pid = 0xC0CA); DirtyJtag(uint32_t clkHz, int8_t verbose, uint16_t vid = 0x1209, uint16_t pid = 0xC0CA);
virtual ~DirtyJtag(); virtual ~DirtyJtag();
int setClkFreq(uint32_t clkHZ) override; int setClkFreq(uint32_t clkHz) override;
/* TMS */ /*!
* \brief drive TMS to move in JTAG state machine
* \param tms serie of TMS state
* \param len number of TMS state
* \param flush_buffer force flushing the buffer
* \param tdi TDI constant value
* \return number of state written
*/
int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override; int writeTMS(const uint8_t *tms, uint32_t len, bool flush_buffer, const uint8_t tdi = 1) override;
/* TDI */
/*!
* \brief send TDI bits (mainly in shift DR/IR state)
* \param tx array of TDI values (used to write)
* \param rx array of TDO values (used when read)
* \param len number of bit to send/receive
* \param end in JTAG state machine last bit and tms are set in same time
* \return number of bit written and/or read
*/
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 */
/*!
* \brief toggle clock with static tms and tdi
* \param tms state of tms signal
* \param tdo state of tdo signal
* \param clk_len number of clock cycle
* \return number of clock cycle send
*/
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;
/*! /*!
@ -42,7 +63,6 @@ class DirtyJtag : public JtagInterface {
int flush() override; int flush() override;
/* access gpio */
/* read gpio */ /* read gpio */
uint8_t gpio_get(); uint8_t gpio_get();
/* update selected gpio */ /* update selected gpio */
@ -54,7 +74,6 @@ class DirtyJtag : public JtagInterface {
int sendBitBang(uint8_t mask, uint8_t val, uint8_t *read, bool last); int sendBitBang(uint8_t mask, uint8_t val, uint8_t *read, bool last);
bool getVersion(); bool getVersion();
bool _set_gpio_level(uint8_t gpio, uint8_t val); bool _set_gpio_level(uint8_t gpio, uint8_t val);
libusb_device_handle *dev_handle; libusb_device_handle *dev_handle;