0

I have a specially designed board connected via USB to my Raspberry Pi 3. This board provides a keyboard interface. But it also provides additional USB "reports" that can be retrieved - for sensor data.

The board is recognized as a standard keyboard device (evdev):

[    3.007392] usb 1-1.4.4: new full-speed USB device number 9 using dwc_otg
[    3.119431] usb 1-1.4.4: New USB device found, idVendor=04d8, idProduct=f1cf
[    3.119459] usb 1-1.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    3.119474] usb 1-1.4.4: Product: My Interface
[    3.119486] usb 1-1.4.4: Manufacturer: My Company
[    3.125260] input: My Company My Interface as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4.4/1-1.4.4:1.0/0003:04D8:F1CF.0001/input/input0
[    3.177871] hid-generic 0003:04D8:F1CF.0001: input,hiddev0,hidraw0: USB HID v1.11 Keyboard [My Company My Interface] on usb-3f980000.usb-1.4.4/input0

I tried to implement the extra functionality using hidapi (http://www.signal11.us/oss/hidapi/) in parallel in the Qt application. I'm able to enumerate the usb hid devices with the hidapi. But as soon as I "open" the hid device with libhid, the input device gets disconnected, so the keyboard functionality is lost:

qt.qpa.input: Removing keyboard at "/dev/input/event0"
qt.qpa.input: Unload current keymap and restore built-in
evdevkeyboard: Failed to query led states
qt.qpa.input: switchLed 0 false
qt.qpa.input: switchLed 1 false
qt.qpa.input: switchLed 2 false

My code:

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>

struct hid_device_info *deviceList, *cur_dev;
deviceList = hid_enumerate(0x0, 0x0);
cur_dev = deviceList;

// Iterate through connected USB HIDs
while (cur_dev) {
    qDebug() << "USB: HIDevice:" << cur_dev->path << QString::fromWCharArray(cur_dev->product_string)
             << cur_dev->release_number << cur_dev->serial_number << QString::fromWCharArray(cur_dev->manufacturer_string);

    if (cur_dev->vendor_id == RPIBASE_VENDORID && cur_dev->product_id == RPIBASE_PRODUCTID) {
        m_deviceIsConnected = true;
        m_devicePath = QString(cur_dev->path);
        qDebug() << "Device Path:" << m_devicePath;
    }

    cur_dev = cur_dev->next;
}
hid_free_enumeration(deviceList);

if (false == m_deviceIsConnected)
    return;

// Open the device using the VID, PID.
// TODO: The keyboard is detached as soon as we open a handle using hidapi
hid_device *deviceHandle = hid_open(RPIBASE_VENDORID, RPIBASE_PRODUCTID, NULL);
if (deviceHandle != 0x0) {
    hid_close(deviceHandle);
    this->m_deviceIsWritable = true;
}

I added udev rules to have write access to the hidraw device. And this device provides both functionality under windows. Is there anyone with experience using hidapi within Qt accessing "the same" device? Any hint would be appreciated!

1

After having a conversation with Alan and Scott (hidapi contributors) I realized, that I used the hidapi-libusb implementation. After switching and linking to the hidapi-hidraw implementation it runs fine:

LIBS += -lhidapi-hidraw

The libusb implementation of hidapi boots off any other kernel driver on the device. When linking against the hidraw implementation (which is using /dev/hidrawX), the keyboard device stays attached.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.