work around WinUSB limitation of only one open device handle
This commit is contained in:
parent
4deaddf5d3
commit
6f717de0f1
@ -80,6 +80,7 @@ void USBInBuffer::Callback(libusb_transfer *transfer)
|
||||
case LIBUSB_TRANSFER_STALL:
|
||||
qCritical() << "LIBUSB_ERROR" << transfer->status;
|
||||
libusb_free_transfer(transfer);
|
||||
this->transfer = nullptr;
|
||||
emit TransferError();
|
||||
return;
|
||||
break;
|
||||
@ -146,6 +147,9 @@ Device::Device(QString serial)
|
||||
m_handle = nullptr;
|
||||
lastInfoValid = false;
|
||||
libusb_init(&m_context);
|
||||
#if LIBUSB_API_VERSION >= 0x01000106
|
||||
libusb_set_option(m_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
||||
#endif
|
||||
|
||||
SearchDevices([=](libusb_device_handle *handle, QString found_serial) -> bool {
|
||||
if(serial.isEmpty() || serial == found_serial) {
|
||||
@ -158,7 +162,7 @@ Device::Device(QString serial)
|
||||
// not the requested device, continue search
|
||||
return true;
|
||||
}
|
||||
}, m_context);
|
||||
}, m_context, false);
|
||||
|
||||
if(!m_handle) {
|
||||
QString message = "No device found";
|
||||
@ -170,21 +174,19 @@ Device::Device(QString serial)
|
||||
}
|
||||
|
||||
// Found the correct device, now connect
|
||||
/* claim the interfaces */
|
||||
for (int if_num = 0; if_num < 1; if_num++) {
|
||||
int ret = libusb_claim_interface(m_handle, if_num);
|
||||
if (ret < 0) {
|
||||
libusb_close(m_handle);
|
||||
/* Failed to open */
|
||||
QString message = "Failed to claim interface: \"";
|
||||
message.append(libusb_strerror((libusb_error) ret));
|
||||
message.append("\" Maybe you are already connected to this device?");
|
||||
qWarning() << message;
|
||||
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
|
||||
msg->exec();
|
||||
libusb_exit(m_context);
|
||||
throw std::runtime_error(message.toStdString());
|
||||
}
|
||||
/* claim the interface */
|
||||
int ret = libusb_claim_interface(m_handle, 0);
|
||||
if (ret < 0) {
|
||||
libusb_close(m_handle);
|
||||
/* Failed to open */
|
||||
QString message = "Failed to claim interface: \"";
|
||||
message.append(libusb_strerror((libusb_error) ret));
|
||||
message.append("\" Maybe you are already connected to this device?");
|
||||
qWarning() << message;
|
||||
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
|
||||
msg->exec();
|
||||
libusb_exit(m_context);
|
||||
throw std::runtime_error(message.toStdString());
|
||||
}
|
||||
qInfo() << "USB connection established" << flush;
|
||||
m_connected = true;
|
||||
@ -215,6 +217,7 @@ Device::~Device()
|
||||
qCritical() << "Error releasing interface" << libusb_error_name(ret);
|
||||
}
|
||||
}
|
||||
libusb_release_interface(m_handle, 0);
|
||||
libusb_close(m_handle);
|
||||
m_receiveThread->join();
|
||||
libusb_exit(m_context);
|
||||
@ -287,11 +290,14 @@ std::set<QString> Device::GetDevices()
|
||||
|
||||
libusb_context *ctx;
|
||||
libusb_init(&ctx);
|
||||
#if LIBUSB_API_VERSION >= 0x01000106
|
||||
libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
||||
#endif
|
||||
|
||||
SearchDevices([&serials](libusb_device_handle *, QString serial) -> bool {
|
||||
serials.insert(serial);
|
||||
return true;
|
||||
}, ctx);
|
||||
}, ctx, true);
|
||||
|
||||
libusb_exit(ctx);
|
||||
|
||||
@ -307,7 +313,7 @@ void Device::USBHandleThread()
|
||||
qDebug() << "Disconnected, receive thread exiting";
|
||||
}
|
||||
|
||||
void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)> foundCallback, libusb_context *context)
|
||||
void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)> foundCallback, libusb_context *context, bool ignoreOpenError)
|
||||
{
|
||||
libusb_device **devList;
|
||||
auto ndevices = libusb_get_device_list(context, &devList);
|
||||
@ -341,13 +347,19 @@ void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)>
|
||||
libusb_device_handle *handle = nullptr;
|
||||
ret = libusb_open(device, &handle);
|
||||
if (ret) {
|
||||
qDebug() << libusb_strerror((enum libusb_error) ret);
|
||||
/* Failed to open */
|
||||
QString message = "Found potential device but failed to open usb connection: \"";
|
||||
message.append(libusb_strerror((libusb_error) ret));
|
||||
message.append("\" On Linux this is most likely caused by a missing udev rule. On Windows it could be a missing driver. Try installing the WinUSB driver using Zadig (https://zadig.akeo.ie/)");
|
||||
qWarning() << message;
|
||||
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
|
||||
msg->exec();
|
||||
if(!ignoreOpenError) {
|
||||
QString message = "Found potential device but failed to open usb connection: \"";
|
||||
message.append(libusb_strerror((libusb_error) ret));
|
||||
message.append("\" On Linux this is most likely caused by a missing udev rule. "
|
||||
"On Windows this most likely means that you are already connected to "
|
||||
"this device (is another instance of the application already runnning? "
|
||||
"If that is not the case, you can try installing the WinUSB driver using Zadig (https://zadig.akeo.ie/)");
|
||||
qWarning() << message;
|
||||
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
|
||||
msg->exec();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -408,6 +420,7 @@ void Device::ReceivedData()
|
||||
{
|
||||
Protocol::PacketInfo packet;
|
||||
uint16_t handled_len;
|
||||
// qDebug() << "Received data";
|
||||
do {
|
||||
handled_len = Protocol::DecodeBuffer(dataBuffer->getBuffer(), dataBuffer->getReceived(), &packet);
|
||||
dataBuffer->removeBytes(handled_len);
|
||||
|
@ -98,7 +98,7 @@ private:
|
||||
void USBHandleThread();
|
||||
// foundCallback is called for every device that is found. If it returns true the search continues, otherwise it is aborted.
|
||||
// When the search is aborted the last found device is still opened
|
||||
static void SearchDevices(std::function<bool(libusb_device_handle *handle, QString serial)> foundCallback, libusb_context *context);
|
||||
static void SearchDevices(std::function<bool(libusb_device_handle *handle, QString serial)> foundCallback, libusb_context *context, bool ignoreOpenError);
|
||||
|
||||
libusb_device_handle *m_handle;
|
||||
libusb_context *m_context;
|
||||
|
@ -263,6 +263,9 @@ int AppWindow::UpdateDeviceList()
|
||||
deviceActionGroup->setExclusive(true);
|
||||
ui->menuConnect_to->clear();
|
||||
auto devices = Device::GetDevices();
|
||||
if(device) {
|
||||
devices.insert(device->serial());
|
||||
}
|
||||
if(devices.size()) {
|
||||
for(auto d : devices) {
|
||||
auto connectAction = ui->menuConnect_to->addAction(d);
|
||||
|
@ -110,7 +110,7 @@ __ALIGN_BEGIN uint8_t USBD_CfgFSDesc[USB_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
|
||||
// See https://github.com/pbatard/libwdi/wiki/WCID-Devices for descriptor data
|
||||
// This requests to load the WinUSB driver for this device
|
||||
__ALIGN_BEGIN const uint8_t USBD_MicrosoftCompatibleID[40] __ALIGN_END =
|
||||
__ALIGN_BEGIN const char USBD_MicrosoftCompatibleID[40] __ALIGN_END =
|
||||
{
|
||||
0x28, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
@ -119,7 +119,7 @@ __ALIGN_BEGIN const uint8_t USBD_MicrosoftCompatibleID[40] __ALIGN_END =
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00,
|
||||
'W','I','N','U','S','B','\0','\0',
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
36
Software/VNA_embedded/VNA_embedded Debug.cfg
Normal file
36
Software/VNA_embedded/VNA_embedded Debug.cfg
Normal file
@ -0,0 +1,36 @@
|
||||
# This is an VNA_embedded board with a single STM32G431CBUx chip
|
||||
#
|
||||
# Generated by System Workbench for STM32
|
||||
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
|
||||
set WORKAREASIZE 0x5800
|
||||
|
||||
transport select "hla_swd"
|
||||
|
||||
set CHIPNAME STM32G431CBUx
|
||||
set BOARDNAME VNA_embedded
|
||||
|
||||
# CHIPNAMES state
|
||||
set CHIPNAME_CPU0_ACTIVATED 1
|
||||
|
||||
# Enable debug when in low power modes
|
||||
set ENABLE_LOW_POWER 1
|
||||
|
||||
# Stop Watchdog counters when halt
|
||||
set STOP_WATCHDOG 1
|
||||
|
||||
# STlink Debug clock frequency
|
||||
set CLOCK_FREQ 8000
|
||||
|
||||
# use hardware reset, connect under reset
|
||||
# connect_assert_srst needed if low power mode application running (WFI...)
|
||||
reset_config srst_only srst_nogate connect_assert_srst
|
||||
set CONNECT_UNDER_RESET 1
|
||||
|
||||
# BCTM CPU variables
|
||||
|
||||
|
||||
|
||||
source [find target/stm32g4x.cfg]
|
Loading…
Reference in New Issue
Block a user