Skip to content

Commit

Permalink
[MERGE] usb polling rate script (24622)
Browse files Browse the repository at this point in the history
  • Loading branch information
drashna committed Nov 21, 2024
1 parent 09b7ba9 commit 2fa0aa0
Showing 1 changed file with 82 additions and 0 deletions.
82 changes: 82 additions & 0 deletions util/polling_rate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/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)}")

0 comments on commit 2fa0aa0

Please sign in to comment.