qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

polling_rate.py (2833B)


      1 #!/usr/bin/env python3
      2 
      3 import usb
      4 
      5 USB_INTERFACE_CLASS_HID = 0x03
      6 
      7 def usb_device_spec(spec):
      8     major = spec >> 8
      9     minor = (spec >> 4) & 0xF
     10     return f"{major}.{minor}"
     11 
     12 def usb_device_speed(speed):
     13     if speed == 1:
     14         return "Low-speed"
     15     elif speed == 2:
     16         return "Full-speed"
     17     elif speed == 3:
     18         return "High-speed"
     19     elif speed == 4:
     20         return "SuperSpeed"
     21     elif speed == 5:
     22         return "SuperSpeed+"
     23 
     24     return "Speed unknown"
     25 
     26 def usb_hid_interface_subclass(subclass):
     27     if subclass == 0x00:
     28         return "None"
     29     elif subclass == 0x01:
     30         return "Boot"
     31     else:
     32         return f"Unknown (0x{subclass:02X})"
     33 
     34 def usb_hid_interface_protocol(subclass, protocol):
     35     if subclass == 0x00 and protocol == 0x00:
     36         return "None"
     37     elif subclass == 0x01:
     38         if protocol == 0x00:
     39             return "None"
     40         elif protocol == 0x01:
     41             return "Keyboard"
     42         elif protocol == 0x02:
     43             return "Mouse"
     44 
     45     return f"Unknown (0x{protocol:02X})"
     46 
     47 def usb_interface_polling_rate(speed, interval):
     48     if speed >= 3:
     49         return f"{interval * 125} μs ({8000 // interval} Hz)"
     50     else:
     51         return f"{interval} ms ({1000 // interval} Hz)"
     52 
     53 if __name__ == '__main__':
     54     devices = usb.core.find(find_all=True)
     55 
     56     for device in devices:
     57         try:
     58             configuration = device.get_active_configuration()
     59         except NotImplementedError:
     60             continue
     61 
     62         hid_interfaces = []
     63         for interface in configuration.interfaces():
     64             if interface.bInterfaceClass == USB_INTERFACE_CLASS_HID:
     65                 hid_interfaces.append(interface)
     66 
     67         if len(hid_interfaces) > 0:
     68             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)}")
     69 
     70             for interface in hid_interfaces:
     71                 print(f"└─ HID Interface {interface.bInterfaceNumber}")
     72                 subclass = interface.bInterfaceSubClass
     73                 protocol = interface.bInterfaceProtocol
     74                 print(f"   ├─ Subclass: {usb_hid_interface_subclass(subclass)}")
     75                 print(f"   ├─ Protocol: {usb_hid_interface_protocol(subclass, protocol)}")
     76 
     77                 for endpoint in interface.endpoints():
     78                     endpoint_address = endpoint.bEndpointAddress & 0xF
     79                     endpoint_direction = "IN" if endpoint.bEndpointAddress & 0x80 else "OUT"
     80                     print(f"   └─ Endpoint {endpoint_address} {endpoint_direction}")
     81                     print(f"      ├─ Endpoint Size: {endpoint.wMaxPacketSize} bytes")
     82                     print(f"      └─ Polling Rate: {usb_interface_polling_rate(device.speed, endpoint.bInterval)}")