Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usb_hid.set_interface_name() doesn't work #9847

Open
podpah opened this issue Dec 1, 2024 · 4 comments
Open

usb_hid.set_interface_name() doesn't work #9847

podpah opened this issue Dec 1, 2024 · 4 comments
Milestone

Comments

@podpah
Copy link

podpah commented Dec 1, 2024

CircuitPython version

Adafruit CircuitPython 9.2.1 on 2024-11-20; Raspberry Pi Pico with rp2040

Code/REPL

# in boot.py file
import usb_hid
import supervisor
supervisor.set_usb_identification(manufacturer='HyperX', product='Pulsefire Haste 2', vid=0x0951, pid=0x16e4)

    usb_hid.disable()
    usb_hid.enable((usb_hid.Device.MOUSE,), boot_device=2)
    usb_hid.set_interface_name("HyperX Pulsefire Haste 2")

(some of the above is indented as it's in an if statement but it runs just fine, I've just omitted the rest of the boot.py for brevity)

Behavior

# Powershell
> Get-PnpDevice -InstanceId 'USB*' -Status OK
OK         HIDClass        USB Input Device                                                                 USB\VID_0951...
:: Cmd
> wmic path Win32_PnPEntity where "DeviceID like 'USB%'" get Name, DeviceID
USB\VID_0951&PID_16E4\425030503137330F         USB Input Device

Description

I am trying to change the interface name with usb_hid.set_interface_name in my boot.py but it does not take effect. I had a look at #9130 (comment) and added the supervisor.set_usb_identification which changed the PID/VID as shown in the PS/Cmd output but it did not affect the device name.

There are no other mounted devices with the PID/VID as I disable storage, cdc and midi. I've tried to set the interface name before enabling the device but that does not work either.
There are no errors shown on boot_out.txt and my code.py runs as intended

Additional information

No response

@podpah podpah added the bug label Dec 1, 2024
@jepler
Copy link
Member

jepler commented Dec 1, 2024

I tried reproducing your report on a Feather RP2350 and the following boot.py (all lines shown):

# in boot.py file
import usb_hid
import supervisor
supervisor.set_usb_identification(manufacturer='HyperX', product='Pulsefire Haste 2', vid=0x0951, pid=0x16e4)
#usb_hid.disable()
usb_hid.enable((usb_hid.Device.MOUSE,)
        #, boot_device=2 # Specifying this causes safe-mode reset (why?)
        )
usb_hid.set_interface_name("HyperX Pulsefire Haste 2")
print("done")

I'm not on Windows so I get my USB device information differently, but the device seems to come up with the specified strings, both for the overall device and for the HID input. This one way to check it on Linux:

$ lsusb | grep 0951
Bus 001 Device 086: ID 0951:16e4 Kingston Technology HyperX Pulsefire Raid
$ grep -A1 Vendor=0951 /proc/bus/input/devices 
I: Bus=0003 Vendor=0951 Product=16e4 Version=0111
N: Name="HyperX Pulsefire Haste 2"

(full lsusb at https://gist.github.com/jepler/6ec133ad4d3929b97dc54217bb760ab9)

However, I found that the boot_device setting was causing my device to safe-mode reset:

Auto-reload is off.
Running in safe mode! Not running saved code.

You are in safe mode because:
Boot device must be first (interface #0).
Press reset to exit safe mode.

This is probably because I did not deactivate CDC and MSC (part of what is not shown in your reduced boot.py I guess?)

I do not know where the string "USB Input Device" is coming from. CircuitPython uses the following logic:

    if (custom_usb_hid_interface_name == NULL) {
        usb_hid_interface_name = USB_INTERFACE_NAME " HID";                         
    } else {
        usb_hid_interface_name = custom_usb_hid_interface_name;
    }

which defaults like so

supervisor/supervisor.mk:235:USB_INTERFACE_NAME ?= "CircuitPython"

so the expected string if you weren't changing it would be "CircuitPython HID", not "USB Input Device". I don't know wmic or Get-PnpDevice, but this makes me wonder whether your query is really fetching the USB HID interface name string or something else.

@dhalbert
Copy link
Collaborator

dhalbert commented Dec 2, 2024

@podpah

I believe https://stackoverflow.com/questions/39395751/how-can-a-hid-device-control-the-description-shown-for-it-in-windows-device-mana is noting that Windows does not list the supplied interface name, unfortunately. Other OS's do better.

I searched the Windows registry for "CircuitPython HID', and did not find it. So it's not recording the name. The name also does not show up in this tool: https://www.uwe-sieber.de/usbtreeview_e.html, which lists a lot of information. The name is read by Windows. https://github.com/todbot/win-hid-dump shows "CircuitPython HID". And it shows up in the long list of values you can look at in Device Manager:
image

Some more info here: https://learn.microsoft.com/en-us/answers/questions/953624/show-bus-reportet-device-description-as-device-nam. Apparently, one could write a device-specific driver to change the name, but when you use the regular Windows-supplied "class" driver the name is not changed. CircuitPython can't do anything about this. Your use of .usb_set_identification() does help.

EDIT: The name does show up in some places, but not in the easily-visible Device Manager list. For instance, in the game controller list: #8989

@dhalbert dhalbert added this to the Support milestone Dec 2, 2024
@tannewt tannewt added the usb label Dec 2, 2024
@podpah
Copy link
Author

podpah commented Dec 6, 2024

@dhalbert @jepler thank you both for your support with this. Since it's a Windows issue I guess it'll be fine for my use case (and now that I think about it my own mouse/keyboard aren't named either and they're from a somewhat large brand too.

Also a note on the boot_machine thing:

This is probably because I did not deactivate CDC and MSC (part of what is not shown in your reduced boot.py I guess?)

Yup. The HID boot device must usually be the first or only device presented by CircuitPython. The HID device will be USB interface number 0. To make sure it is the first device, disable other USB devices, including CDC and MSC (CIRCUITPY). If you specify a non-zero boot_device, and it is not the first device, CircuitPython will enter safe mode to report this error.

@podpah podpah closed this as completed Dec 6, 2024
@dhalbert
Copy link
Collaborator

dhalbert commented Dec 7, 2024

Thanks. I'm going to reopen this, because I think there may be an off-by-one error that doesn't allow names larger than a certain length. But there's any easy workaround, so it's not a blocker.

@dhalbert dhalbert reopened this Dec 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants