3
votes

I have a USB HID device that can work in two different modes. The selection of modes is based on the sequence of USB enumeration/initialization packets sent to it.

I am using a Raspberry Pi 3 running Raspbian, however I also see the same issue if I compile my code for my desktop Ubuntu distro.

The issue I have is that linux is recognizing the USB device as a HID device and then sending the sequence of commands that it deems necessary to start the device, and this works correctly and starts the device in "Mode 1".

However I need to start the device in "Mode 2" and to do this I need to send a slightly different set of enumeration/initialization commands.

I am new to linux but very experienced with LibUSB and LibUSBDotNet under windows and can get the behavior I desire under windows.

Windows has similar behaviour to linux in that it will enumerate, recognise the device as a USB HID device and then initialise it as it deems fit resulting in the device going into "Mode 1". To prevent windows doing this I can create a LibUSB filter driver for the device, which then replaces the default driver, so windows will now do the initial enumeration, realise that the VID and PID of the device are managed by the LibUSB filter driver (rather than the windows HID driver) and then stop enumeration/initialization - this allows my code to take over and complete the initialization into "Mode 2".

How can I stop Linux from fully enumerating/initializing this device (as I do with windows). Perhaps I need to do something with udev rules or something, but I would have no idea what as I am new to linux.

Any help greatly appreciated

1
Is detaching from kernel and doing your own magic to late for a change to Mode 2?dryman

1 Answers

3
votes

you have right, you have to play with the udev rules.

First of all you have to identify your device. Find the idProduct and the idVendor of your device. You can use:

lsusb

Then in the rules.d folder (/etc/udev/rules.d) create a new file with the name:

10-my-usb.rules

In this file add this line

SUBSYSTEM=="usb",ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="XXXX", MODE="666", GROUP+="plugdev"

Replace the XXXX with the value you get before

Then restart your udev rules:

sudo udevadm trigger

Then unplug and replug normally you can use it