libusb подключается к устройству нормально, результаты передачи прерываний в LIBUSB_ERROR_IO - PullRequest
0 голосов
/ 18 декабря 2018

Я создал USB-устройство на основе STM32, которое отлично работает с Python во время прототипирования.В настоящее время я пытаюсь перенести его на C ++ / Qt для производства.Я интегрировал libusb с Qt и могу успешно открывать и закрывать устройство и читать строки и дескрипторы устройства.Однако, когда я пытаюсь отправить какую-либо передачу OUT прерывания на устройство или получаю передачу IN прерывания, я ничего не получаю на устройстве и ERROR_IO (-1) в моем приложении.

#define HIL_USB_VID     0x0483
#define HIL_USB_PID     0x572b
#define HIL_USB_OUT_EP  0x01
#define HIL_USB_IN_EP   0x81
#define HIL_PKT_LENGTH  64
#define HIL_PKT_TIMEOUT 100
#define USB_CONFIG_NUM  1
#define USB_IFACE_NUM   0

HILInterface::HILInterface()
{
    this->handle = NULL;
    this->worker = NULL;
}

HILInterface::~HILInterface()
{
    this->disconnect();
}

bool HILInterface::connectMjolnir() {
    if (libusb_init(NULL) < 0)
    {
        qDebug() << "Failed to initialize libusb";
        return false;
    }
    this->handle = libusb_open_device_with_vid_pid(NULL, HIL_USB_VID, HIL_USB_PID);
    if (NULL == this->handle) {
        qDebug() << "Failed to open HIL interface";
        return false;
    }
    int needToDetach = libusb_kernel_driver_active(this->handle, USB_IFACE_NUM);
    if (LIBUSB_SUCCESS == needToDetach || LIBUSB_ERROR_NOT_SUPPORTED == needToDetach) {
        qDebug() << "No need to detach HIL interface from OS";
    } else {
        if (LIBUSB_SUCCESS != libusb_detach_kernel_driver(this->handle, USB_IFACE_NUM)) {
            qDebug() << "Failed to detach HIL interface from OS";
            this->disconnect();
            return false;
        }
    }
    if (LIBUSB_SUCCESS != libusb_set_configuration(this->handle, USB_CONFIG_NUM)) {
        qDebug() << "Failed to set-configuration on HIL interface";
        this->disconnect();
        return false;
    }
    if (LIBUSB_SUCCESS != libusb_claim_interface(this->handle, USB_IFACE_NUM))
    {
        qDebug() << "Failed to claim HIL interface";
        this->disconnect();
        return false;
    }
    qDebug() << "HIL interface connected successfully";
    unsigned char strDesc[256];
    struct libusb_device_descriptor desc;
    struct libusb_config_descriptor ** conDesc = NULL;
    libusb_get_device_descriptor(libusb_get_device(this->handle), &desc);
    libusb_get_string_descriptor_ascii(this->handle, desc.iManufacturer, strDesc, 256);
    qDebug() << "HIL Manufacturer:" << (char*)strDesc;
    libusb_get_string_descriptor_ascii(this->handle, desc.iProduct, strDesc, 256);
    qDebug() << "HIL Product:" << (char*)strDesc;
    libusb_get_string_descriptor_ascii(this->handle, desc.iSerialNumber, strDesc, 256);
    qDebug() << "HIL Serial Number:" << (char*)strDesc;
    this->worker = new HILInterfaceThread();
    this->worker->moveToThread(&workerThread);
    connect(&workerThread, &QThread::finished, this->worker, &QObject::deleteLater);
    connect(this, &HILInterface::startReceiveThread, this->worker, &HILInterfaceThread::run);
    this->worker->handle = this->handle;
    workerThread.start();
    emit startReceiveThread();
    return true;
}

bool HILInterface::disconnectMjolnir() {
    if (NULL == this->handle) {
        return false;
    }
    workerThread.terminate();
    workerThread.wait();
    libusb_release_interface(this->handle, USB_IFACE_NUM);
    libusb_attach_kernel_driver(this->handle, USB_IFACE_NUM);
    libusb_close(this->handle);
    this->handle = NULL;
    libusb_exit(NULL);
    return true;
}

bool HILInterface::sendCommand(uint8_t * msgBuffer, uint16_t msgLen) {
    if (NULL == this->handle) {
        return false;
    }
    int xferCount = 0;
    int errorCode = libusb_interrupt_transfer(this->handle, HIL_USB_OUT_EP, msgBuffer, msgLen, &xferCount, HIL_PKT_TIMEOUT);
    if (LIBUSB_SUCCESS == errorCode) {
        if (HIL_PKT_LENGTH == xferCount) {
            return true;
        }
    }
    return false;
}

1 Ответ

0 голосов
/ 21 декабря 2018

В результате возникла проблема с дескриптором HID на стороне устройства, а не с кодом libusb.Вот дескриптор HID, который в итоге работал с кодом выше:

__ALIGN_BEGIN static uint8_t USBD_HID_ReportDesc[HID_REPORT_DESC_SIZE]  __ALIGN_END =
{
        0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
        0x09, 0x01,        // Usage (0x01)
        0xA1, 0x01,        // Collection (Application)
        0x19, 0x01,        //   Usage Minimum (0x01)
        0x29, 0x40,        //   Usage Maximum (0x40)
        0x15, 0x00,        //   Logical Minimum (0)
        0x26, 0xFF, 0x00,  //   Logical Maximum (255)
        0x75, 0x08,        //   Report Size (8)
        0x95, 0x40,        //   Report Count (64)
        0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
        0x19, 0x01,        //   Usage Minimum (0x01)
        0x29, 0x40,        //   Usage Maximum (0x40)
        0x91, 0x00,        //   Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
        0xC0,              // End Collection

        // 29 bytes
};
...