cmsisDAP: v1: uses INFO_ID_MAX_PKT_SZ to fix xfer length

This commit is contained in:
Gwenhael Goavec-Merou 2026-05-24 09:16:30 +02:00
parent 468f787fdf
commit bba86d8be3
2 changed files with 30 additions and 12 deletions

View File

@ -107,7 +107,7 @@ CmsisDAP::CmsisDAP(const cable_t &cable, int index, uint32_t clkHZ, int8_t verbo
#ifdef ENABLE_CMSISDAP_V2 #ifdef ENABLE_CMSISDAP_V2
_usb_dev(NULL), _ctx(NULL), _usb_dev(NULL), _ctx(NULL),
#endif #endif
_packet_size(0), _pkt_sz(0),
_ep_in(0), _ep_out(0), _num_tms(0), _is_connect(false), _backend(BACKEND_NONE) _ep_in(0), _ep_out(0), _num_tms(0), _is_connect(false), _backend(BACKEND_NONE)
{ {
_ll_buffer = (unsigned char *)malloc(sizeof(unsigned char) * 1024); _ll_buffer = (unsigned char *)malloc(sizeof(unsigned char) * 1024);
@ -129,6 +129,7 @@ CmsisDAP::CmsisDAP(const cable_t &cable, int index, uint32_t clkHZ, int8_t verbo
#endif #endif
#ifdef ENABLE_CMSISDAP_V1 #ifdef ENABLE_CMSISDAP_V1
if (_backend == BACKEND_NONE) { if (_backend == BACKEND_NONE) {
_pkt_sz = 64;
_backend = BACKEND_HID; _backend = BACKEND_HID;
if (!initWithHID(cable, index, verbose)) { if (!initWithHID(cable, index, verbose)) {
printInfo("cmsisDAP v1: try HID init but failed"); printInfo("cmsisDAP v1: try HID init but failed");
@ -328,6 +329,23 @@ bool CmsisDAP::initWithHID(const cable_t &cable, int index, int8_t verbose){
/* cleanup enumeration */ /* cleanup enumeration */
hid_free_enumeration(devs); hid_free_enumeration(devs);
/* query actual HID packet size and grow buffer if needed */
uint8_t buf[65];
memset(buf, 0, 65);
if (read_info(INFO_ID_MAX_PKT_SZ, buf, 64) == 2) {
const uint16_t sz = (static_cast<uint16_t>(buf[3]) << 8) | buf[2];
if (sz > 64) {
_pkt_sz = sz;
if (sz > 1024) {
unsigned char *tmp = (unsigned char *)realloc(_ll_buffer, _pkt_sz + 1);
if (!tmp)
throw std::runtime_error("internal buffer reallocation failed");
_ll_buffer = tmp;
_buffer = _ll_buffer + 2;
}
}
}
return true; return true;
} }
#endif #endif
@ -404,11 +422,11 @@ bool CmsisDAP::initWithBulk(const cable_t &cable, int8_t verbose, bool err_as_in
return false; return false;
} }
_packet_size = dev.packet_size; _pkt_sz = dev.packet_size;
_ep_out = dev.ep_out; _ep_out = dev.ep_out;
_ep_in = dev.ep_in; _ep_in = dev.ep_in;
if (!libusb_dev_mem_alloc(_usb_dev, _packet_size)) { if (!libusb_dev_mem_alloc(_usb_dev, _pkt_sz)) {
libusb_close(_usb_dev); libusb_close(_usb_dev);
libusb_exit(_ctx); libusb_exit(_ctx);
disp_error_info("cmsisDAP: failed to alloc DMA memory for device", err_as_info); disp_error_info("cmsisDAP: failed to alloc DMA memory for device", err_as_info);
@ -697,8 +715,8 @@ int CmsisDAP::writeJtagSequence(uint8_t tms, const uint8_t *tx, uint8_t *rx,
* => one sequence == 9Bytes and 9*7 == 63 * => one sequence == 9Bytes and 9*7 == 63
* then we have 6 * 8 fully filled sequence + one up to 56bits * then we have 6 * 8 fully filled sequence + one up to 56bits
*/ */
if (xfer_byte_len + 1 + pos > 63) { if (xfer_byte_len + 1 + pos > _pkt_sz - 1) {
xfer_byte_len = 63 - pos - 1; // number of free bytes xfer_byte_len = _pkt_sz - pos - 2; // number of free bytes
xfer_bit_len = xfer_byte_len * 8; xfer_bit_len = xfer_byte_len * 8;
} }
@ -819,12 +837,12 @@ int CmsisDAP::xfer(uint8_t instruction, int tx_len,
switch(_backend){ switch(_backend){
#ifdef ENABLE_CMSISDAP_V1 #ifdef ENABLE_CMSISDAP_V1
case BACKEND_HID: case BACKEND_HID:
ret = hid_write(_hid_dev, _ll_buffer, 65); ret = hid_write(_hid_dev, _ll_buffer, _pkt_sz + 1);
if (ret == -1) { if (ret == -1) {
printError("Error: HID write failed\n"); printError("Error: HID write failed\n");
return ret; return ret;
} }
ret = hid_read_timeout(_hid_dev, _ll_buffer, 65, 1000); ret = hid_read_timeout(_hid_dev, _ll_buffer, _pkt_sz + 1, 1000);
if (ret <= 0) { if (ret <= 0) {
if (ret == 0) if (ret == 0)
printError("Error: HID read timeout\n"); printError("Error: HID read timeout\n");
@ -843,7 +861,7 @@ int CmsisDAP::xfer(uint8_t instruction, int tx_len,
return ret; return ret;
} }
memset(&_ll_buffer[0], 0, 1024); memset(&_ll_buffer[0], 0, 1024);
ret = libusb_bulk_transfer(_usb_dev, _ep_in, &_ll_buffer[0], _packet_size, &bulk_len, 1000); ret = libusb_bulk_transfer(_usb_dev, _ep_in, &_ll_buffer[0], _pkt_sz, &bulk_len, 1000);
// sleep for 1ms to ensure that polling behavior aligns with HID backend // sleep for 1ms to ensure that polling behavior aligns with HID backend
usleep(1000); usleep(1000);
if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) { if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) {
@ -891,12 +909,12 @@ int CmsisDAP::xfer(int tx_len, uint8_t *rx_buff, int rx_len)
switch(_backend){ switch(_backend){
#ifdef ENABLE_CMSISDAP_V1 #ifdef ENABLE_CMSISDAP_V1
case BACKEND_HID: case BACKEND_HID:
ret = hid_write(_hid_dev, _ll_buffer, 65); ret = hid_write(_hid_dev, _ll_buffer, _pkt_sz + 1);
if (ret == -1) { if (ret == -1) {
printError("Error: HID write failed\n"); printError("Error: HID write failed\n");
return ret; return ret;
} }
ret = hid_read_timeout(_hid_dev, _ll_buffer, 65, 1000); ret = hid_read_timeout(_hid_dev, _ll_buffer, _pkt_sz + 1, 1000);
if (ret <= 0) { if (ret <= 0) {
if (ret == 0) if (ret == 0)
printError("Error: HID read timeout\n"); printError("Error: HID read timeout\n");
@ -915,7 +933,7 @@ int CmsisDAP::xfer(int tx_len, uint8_t *rx_buff, int rx_len)
return ret; return ret;
} }
memset(&_ll_buffer[0], 0, 1024); memset(&_ll_buffer[0], 0, 1024);
ret = libusb_bulk_transfer(_usb_dev, _ep_in, &_ll_buffer[0], _packet_size, &bulk_len, 1000); ret = libusb_bulk_transfer(_usb_dev, _ep_in, &_ll_buffer[0], _pkt_sz, &bulk_len, 1000);
// sleep for 1ms to ensure that polling behavior aligns with HID backend // sleep for 1ms to ensure that polling behavior aligns with HID backend
usleep(1000); usleep(1000);
if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) { if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) {

View File

@ -143,7 +143,7 @@ class CmsisDAP: public JtagInterface {
unsigned char *_ll_buffer; /**< message buffer */ unsigned char *_ll_buffer; /**< message buffer */
unsigned char *_buffer; /**< subset of _ll_buffer */ unsigned char *_buffer; /**< subset of _ll_buffer */
#ifdef ENABLE_CMSISDAP_V2 #ifdef ENABLE_CMSISDAP_V2
int _packet_size; /**< USB bulk packet size */ int _pkt_sz; /**< USB bulk packet size */
int _ep_in; /**< USB bulk in endpoint */ int _ep_in; /**< USB bulk in endpoint */
int _ep_out; /**< USB bulk out endpoint */ int _ep_out; /**< USB bulk out endpoint */
#endif #endif