remoteBitbang_client: fix toggleClk behavior, uses flush instead of ll_write(NULL), fix potential overflows, simplify code

This commit is contained in:
Gwenhael Goavec-Merou 2026-05-19 11:41:37 +02:00
parent 956375efbc
commit b3f418c977
1 changed files with 19 additions and 22 deletions

View File

@ -76,25 +76,27 @@ 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, __attribute__((unused)) const uint8_t tdi) bool flush_buffer, const uint8_t tdi)
{ {
// empty buffer // empty buffer
// if asked flush // if asked flush
if (len == 0) if (len == 0)
return ((flush_buffer) ? flush() : 0); return ((flush_buffer) ? flush() : 0);
_last_tdi = (tdi) ? TDI_BIT : 0;
uint8_t base_v = '0' + _last_tdi; uint8_t base_v = '0' + _last_tdi;
for (uint32_t pos = 0; pos < len; pos++) { for (uint32_t pos = 0; pos < len; pos++) {
// buffer full -> write // buffer full -> write
if (_num_bytes == _buffer_size) if ((_num_bytes + 2) >= _buffer_size)
ll_write(NULL); flush();
_last_tms = (tms[pos >> 3] & (1 << (pos & 0x07))) ? TMS_BIT : 0; _last_tms = (tms[pos >> 3] & (1 << (pos & 0x07))) ? TMS_BIT : 0;
_xfer_buf[_num_bytes++] = base_v + _last_tms; _xfer_buf[_num_bytes++] = base_v + _last_tms;
_xfer_buf[_num_bytes++] = base_v + _last_tms + TCK_BIT; _xfer_buf[_num_bytes++] = base_v + _last_tms + TCK_BIT;
} }
// flush where it's asked or if the buffer is full // flush where it's asked or if the buffer is full
if (flush_buffer || _num_bytes == _buffer_size * 8) if (flush_buffer || _num_bytes == _buffer_size)
return flush(); return flush();
return len; return len;
} }
@ -107,9 +109,11 @@ int RemoteBitbang_client::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len,
uint8_t base_v = '0' + _last_tms; uint8_t base_v = '0' + _last_tms;
for (uint32_t pos = 0; pos < len; pos++) { for (uint32_t pos = 0; pos < len; pos++) {
if (_num_bytes == _buffer_size) const uint32_t pos_byte = (pos >> 3);
ll_write(NULL); // NULL because _num_bytes is always 0 when read const uint32_t pos_bit = (1 << (pos & 0x07));
_last_tdi = (tx[pos >> 3] & (1 << (pos & 0x07))) ? TDI_BIT : 0; if ((_num_bytes + 2) >= _buffer_size)
flush();
_last_tdi = (tx[pos_byte] & pos_bit) ? TDI_BIT : 0;
if (end && pos == len - 1) { if (end && pos == len - 1) {
_last_tms = TMS_BIT; _last_tms = TMS_BIT;
base_v = '0' + _last_tms; base_v = '0' + _last_tms;
@ -120,9 +124,9 @@ int RemoteBitbang_client::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len,
uint8_t tdo; uint8_t tdo;
ll_write(&tdo); ll_write(&tdo);
if (tdo == '1') if (tdo == '1')
rx[pos >> 3] |= (1 << (pos & 0x07)); rx[pos_byte] |= pos_bit;
else else
rx[pos >> 3] &= ~(1 << (pos & 0x07)); rx[pos_byte] &= ~pos_bit;
} }
} }
@ -130,30 +134,23 @@ int RemoteBitbang_client::writeTDI(const uint8_t *tx, uint8_t *rx, uint32_t len,
} }
// toggle clk with constant TDI and TMS. // toggle clk with constant TDI and TMS.
int RemoteBitbang_client::toggleClk(uint8_t tms, uint8_t tdi, uint32_t clk_len) int RemoteBitbang_client::toggleClk([[maybe_unused]] uint8_t tms,
[[maybe_unused]] uint8_t tdi, uint32_t clk_len)
{ {
// nothing to do // nothing to do
if (clk_len == 0) if (clk_len == 0)
return 0; return 0;
if (_num_bytes != 0)
flush();
_last_tms = tms; const uint8_t val = (_last_tms | _last_tdi);
_last_tdi = tdi;
uint8_t val = (_last_tms | _last_tdi);
// flush buffer before starting
if (_num_bytes != 0)
flush();
for (uint32_t len = 0; len < clk_len; len++) { for (uint32_t len = 0; len < clk_len; len++) {
if (len == _num_bytes) if ((_num_bytes + 2) >= _buffer_size)
ll_write(NULL); flush();
_xfer_buf[_num_bytes++] = '0' + val; _xfer_buf[_num_bytes++] = '0' + val;
_xfer_buf[_num_bytes++] = '0' + (val | TCK_BIT); _xfer_buf[_num_bytes++] = '0' + (val | TCK_BIT);
} }
ll_write(NULL); flush();
return clk_len; return clk_len;
} }