I need to communicate with a home-made controller over USB. I'd like to use Python. The controller 'speaks' HID, and is working (detected by Linux when plugged in).
The problem is that linux helpfully attaches the hid driver when the controller is plugged in. When 'Opening' the devices, I get the error OSError: open failed
, which I suspect come from Linux's automatic attachment.
Libusb has functions to a) check if the system driver is attached, and b) to detach the driver. But, as mentioned before, the controller needs the HID
protocol, and revising the different Python HID
implementations, they do not seem to care about detaching the system driver.
I don't feel comfortable loading both a libusb
(just for detaching?) and an hid(api)
module. Isn't there a more elegant way to do this?
The code used to open is:
import hid
VID = 0x04d8
PID = 0xf83f
def init(VID, PID):
dev = hid.device(VID, PID)
handle = dev.open()
init(VID, PID)
which gives:
OSError: open failed
Edit:
Prevent claiming of novelty usb device by usbhid gives two answers with udev rules which try to detach the driver. The first gives an error message in dmesg
. The second, apparently, does nothing.
EDIT: Still no joy. Maybe a few cues to help:
On boot, the USB device shows up in lsusb -t
as (last line):
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
|__ Port 2: Dev 93, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 95, If 0, Class=Hub, Driver=hub/4p, 12M
|__ Port 2: Dev 96, If 0, Class=Printer, Driver=, 12M
|__ Port 3: Dev 94, If 0, Class=Human Interface Device, Driver=usbhid, 12M
It also shows up in dmesg
, with correct information. As shown, the OS connects the device to the usbhid
driver.
This code succesfully detaches it from the driver:
import libusb as usb
class Module():
def __init__(self, VID, PID):
self.usb = usb.init(None)
dev = usb.open_device_with_vid_pid(None, VID, PID)
if usb.kernel_driver_active(dev, 0):
print("Kernel has device, detaching...")
usb.detach_kernel_driver(dev, 0)
usb.close(dev)
Now it shows in lsusb -t
as unconnected:
Port 3: Dev 94, If 0, Class=Human Interface Device, Driver=, 12M
But still, the following code cannot open the device (and tried other methods too). Neither does it enumerate in the enumerate
call:
import hid
class Motor():
def __init__(self, vid, pid):
self.vid, self.vid = vid, vid
print(len(hid.enumerate()))
for rec in print(hid.enumerate()):
print(rec)
dev = hid.Device(vid, vid)
handle = dev.open()