polling_rate.py (2833B)
- #!/usr/bin/env python3
- import usb
- USB_INTERFACE_CLASS_HID = 0x03
- def usb_device_spec(spec):
- major = spec >> 8
- minor = (spec >> 4) & 0xF
- return f"{major}.{minor}"
- def usb_device_speed(speed):
- if speed == 1:
- return "Low-speed"
- elif speed == 2:
- return "Full-speed"
- elif speed == 3:
- return "High-speed"
- elif speed == 4:
- return "SuperSpeed"
- elif speed == 5:
- return "SuperSpeed+"
- return "Speed unknown"
- def usb_hid_interface_subclass(subclass):
- if subclass == 0x00:
- return "None"
- elif subclass == 0x01:
- return "Boot"
- else:
- return f"Unknown (0x{subclass:02X})"
- def usb_hid_interface_protocol(subclass, protocol):
- if subclass == 0x00 and protocol == 0x00:
- return "None"
- elif subclass == 0x01:
- if protocol == 0x00:
- return "None"
- elif protocol == 0x01:
- return "Keyboard"
- elif protocol == 0x02:
- return "Mouse"
- return f"Unknown (0x{protocol:02X})"
- def usb_interface_polling_rate(speed, interval):
- if speed >= 3:
- return f"{interval * 125} μs ({8000 // interval} Hz)"
- else:
- return f"{interval} ms ({1000 // interval} Hz)"
- if __name__ == '__main__':
- devices = usb.core.find(find_all=True)
- for device in devices:
- try:
- configuration = device.get_active_configuration()
- except NotImplementedError:
- continue
- hid_interfaces = []
- for interface in configuration.interfaces():
- if interface.bInterfaceClass == USB_INTERFACE_CLASS_HID:
- hid_interfaces.append(interface)
- if len(hid_interfaces) > 0:
- print(f"{device.manufacturer} {device.product} ({device.idVendor:04X}:{device.idProduct:04X}:{device.bcdDevice:04X}), {usb_device_spec(device.bcdUSB)} {usb_device_speed(device.speed)}")
- for interface in hid_interfaces:
- print(f"└─ HID Interface {interface.bInterfaceNumber}")
- subclass = interface.bInterfaceSubClass
- protocol = interface.bInterfaceProtocol
- print(f" ├─ Subclass: {usb_hid_interface_subclass(subclass)}")
- print(f" ├─ Protocol: {usb_hid_interface_protocol(subclass, protocol)}")
- for endpoint in interface.endpoints():
- endpoint_address = endpoint.bEndpointAddress & 0xF
- endpoint_direction = "IN" if endpoint.bEndpointAddress & 0x80 else "OUT"
- print(f" └─ Endpoint {endpoint_address} {endpoint_direction}")
- print(f" ├─ Endpoint Size: {endpoint.wMaxPacketSize} bytes")
- print(f" └─ Polling Rate: {usb_interface_polling_rate(device.speed, endpoint.bInterval)}")