You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dynamic USB descriptors: enable/disable, change HID descriptors, etc. #1015
A couple of forum posts recently have asked if HID or MSC could be disabled for security or device interference reasons. We need some kind of dynamic USB descriptors to do this.
Other uses for dynamic USB descriptors include adding new HID devices, disabling selected HID devices, and varying an HID device (e.g., changing the joystick coordinate ranges).
This would be helpful in some of our projects as well. One way I could see this working is to check for the presence (or absence) of a file or config option in the BOOT filesystem. So, when CP's UF2 is loaded, it checks for that file (maybe a config file?) and checked which USB descriptors to present.
This would make it possible to enter the bootloader mode, tell it to not share the mass storage device or the HID (or the Serial port?) and restart. If you ever wanted to change that, just double click to get into the boot loader.
CIRCUITPY just like code.py. You can edit it the same way but it won't be rerun automatically. Instead, one needs to eject the drive and then reset the board (using the button or unplugging).
I understand how that would be helpful for the HID descriptors, etc. But shouldn't the Mass Storage descriptor be controllable by something not on that drive?
I think its ok. You can change files through the REPL or use the REPL to reboot to safe mode which skips all user code.
A common technique for the similar problem of flipping read-only for the file system is to read an external line connected to a switch to determine whether to do it or not on boot.
changed the title [-]Dynamic USB device enabling/disabling[/-][+]Dynamic USB descriptors: enable/disable, change HID descriptors, etc.[/+]on Apr 28, 2019
Just an observer here, but is this bootloader command what might be needed here? pyb.usb_mode
It seems that it'd make sense to control this behavior in boot.py, which is accessible by double-clicking the reset button to mount the bootloader's partition. Presumably, if boot.py changes this mode, it could intercept the CircuitPy partition / MSC device from being presented?
@RichardFoo Yes, that's the part of the kind of capability we have in mind, but we'd also like for user-supplied descriptors both for the different USB devices, and for different HID devices in the HID desccriptor. The actual API would be different. It would be invoked from boot.py, which runs before the USB enumeration happens.
How would one accomplish the three following tasks very specifically?
1)disable REPL (like going into a given ports main.c in MP)
2)disable USB (for instances where you want both a REPL and USB no access)
3)have full serial input and output available
The potential use case will NOT be default or standard it would be an option for advanced uses in the event CP were to be used in more advanced IoT devices where security is of primary concern. This can create significant potential for CP however would not change CP just add options.
As you've seen, CircuitPython unifies main.c outside of ports. It is the equivalent of MicroPython's port/*/main.c but applies to all ports.
Take a look in supervisor for the serial APIs. It should be possible to disable USB and interface with a UART there.
Please continue to ask about this on Discord or a separate issue. This issue isn't a great place because it's specifically about changing the USB descriptor, not disabling it.
Just adding my +1 to this. @dhalbert - Since you've already suggested the likely solution similar to the pyb.usb_mode API, I'm really excited to get my hands on the feature. Dynamically (via an I/O pin) allowing the storage to be turned off, but continue to operate the USB as a HID device is my goal.
Same here. I would love to be able to re-enable the CIRCUITPY drive in my keyboards when, for example, a certain key is pressed while connecting it. That would make it much easier to tweak the layouts and other settings.
@npendlington@deshipu Yes, this will be possible. MSC, REPL CDC and data CDC, and MIDI will all be togglable individually from boot.py. You will also be able to specify a list of included HID devices, and include your own descriptors if needed, or drop HID entirely. It might also be possible initially to have extra non-composite HID devices so that a boot keyboard is possible, though I may not do that for the first pass.
Reacted by Radomir Dopieralski, Reppad, npendlington, Scott Shawcroft and Evelyn
Hello! I am currently working with Arduino. Can you please tell me if it is possible to implement a Dynamic USB HID descriptor? The most convenient would be, for example, changing the USB HID descriptor when a certain pin is shorted to ground. I saw the following code on the Internet – and I understand that this is possible.
—————code———————-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
#ifdef ABSOLUTE_MOUSE_MODE
0x15, 0x01, // LOGICAL_MINIMUM (1) <<<< This allows us to talk to any display resolution
0x25, 0x64, // LOGICAL_MAXIMUM (100) <<<< as though it was 100×100 pixels
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs) <<<< This allows us to moveTo absolute positions
#else
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
#endif
————-end code —————–
However, I'm not entirely sure that in the .cpp code (not in the sketch), where USB HID DISCRIPTOR located, it is possible to read the level of the pin and, depending on the result, and then change the descriptor with a new boot of device. Thanks!
Activity
ATMakersBill commentedon Sep 11, 2018
This would be helpful in some of our projects as well. One way I could see this working is to check for the presence (or absence) of a file or config option in the BOOT filesystem. So, when CP's UF2 is loaded, it checks for that file (maybe a config file?) and checked which USB descriptors to present.
This would make it possible to enter the bootloader mode, tell it to not share the mass storage device or the HID (or the Serial port?) and restart. If you ever wanted to change that, just double click to get into the boot loader.
Just a thought
tannewt commentedon Sep 11, 2018
The idea I had was to control the descriptors from
boot.pywhich runs before usb enumeration.ATMakersBill commentedon Sep 11, 2018
Where does that live? On the BOOT drive or on the CIRCUITPY drive? How does a user edit it?
tannewt commentedon Sep 12, 2018
CIRCUITPY just like code.py. You can edit it the same way but it won't be rerun automatically. Instead, one needs to eject the drive and then reset the board (using the button or unplugging).
ATMakersBill commentedon Sep 12, 2018
I understand how that would be helpful for the HID descriptors, etc. But shouldn't the Mass Storage descriptor be controllable by something not on that drive?
tannewt commentedon Sep 13, 2018
I think its ok. You can change files through the REPL or use the REPL to reboot to safe mode which skips all user code.
A common technique for the similar problem of flipping read-only for the file system is to read an external line connected to a switch to determine whether to do it or not on boot.
[-]Dynamic USB device enabling/disabling[/-][+]Dynamic USB descriptors: enable/disable, change HID descriptors, etc.[/+]RichardFoo commentedon May 9, 2020
Just an observer here, but is this bootloader command what might be needed here?
pyb.usb_mode
It seems that it'd make sense to control this behavior in boot.py, which is accessible by double-clicking the reset button to mount the bootloader's partition. Presumably, if boot.py changes this mode, it could intercept the CircuitPy partition / MSC device from being presented?
dhalbert commentedon May 9, 2020
@RichardFoo Yes, that's the part of the kind of capability we have in mind, but we'd also like for user-supplied descriptors both for the different USB devices, and for different HID devices in the HID desccriptor. The actual API would be different. It would be invoked from
boot.py, which runs before the USB enumeration happens.mytechnotalent commentedon Sep 24, 2020
How would one accomplish the three following tasks very specifically?
1)disable REPL (like going into a given ports main.c in MP)
2)disable USB (for instances where you want both a REPL and USB no access)
3)have full serial input and output available
The potential use case will NOT be default or standard it would be an option for advanced uses in the event CP were to be used in more advanced IoT devices where security is of primary concern. This can create significant potential for CP however would not change CP just add options.
mytechnotalent commentedon Sep 24, 2020
It looks like https://github.com/adafruit/circuitpython/blob/main/main.c#L436 has a run_repl function that might be what I am looking for.
tannewt commentedon Sep 24, 2020
As you've seen, CircuitPython unifies main.c outside of ports. It is the equivalent of MicroPython's port/*/main.c but applies to all ports.
Take a look in
supervisorfor the serial APIs. It should be possible to disable USB and interface with a UART there.Please continue to ask about this on Discord or a separate issue. This issue isn't a great place because it's specifically about changing the USB descriptor, not disabling it.
npendlington commentedon Apr 15, 2021
Just adding my +1 to this. @dhalbert - Since you've already suggested the likely solution similar to the pyb.usb_mode API, I'm really excited to get my hands on the feature. Dynamically (via an I/O pin) allowing the storage to be turned off, but continue to operate the USB as a HID device is my goal.
deshipu commentedon Apr 15, 2021
Same here. I would love to be able to re-enable the CIRCUITPY drive in my keyboards when, for example, a certain key is pressed while connecting it. That would make it much easier to tweak the layouts and other settings.
dhalbert commentedon Apr 15, 2021
@npendlington @deshipu Yes, this will be possible. MSC, REPL CDC and data CDC, and MIDI will all be togglable individually from boot.py. You will also be able to specify a list of included HID devices, and include your own descriptors if needed, or drop HID entirely. It might also be possible initially to have extra non-composite HID devices so that a boot keyboard is possible, though I may not do that for the first pass.
unicorn79 commentedon Mar 9, 2022
Hello! I am currently working with Arduino. Can you please tell me if it is possible to implement a Dynamic USB HID descriptor? The most convenient would be, for example, changing the USB HID descriptor when a certain pin is shorted to ground. I saw the following code on the Internet – and I understand that this is possible.
—————code———————-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
#ifdef ABSOLUTE_MOUSE_MODE
0x15, 0x01, // LOGICAL_MINIMUM (1) <<<< This allows us to talk to any display resolution
0x25, 0x64, // LOGICAL_MAXIMUM (100) <<<< as though it was 100×100 pixels
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs) <<<< This allows us to moveTo absolute positions
#else
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
#endif
————-end code —————–
However, I'm not entirely sure that in the .cpp code (not in the sketch), where USB HID DISCRIPTOR located, it is possible to read the level of the pin and, depending on the result, and then change the descriptor with a new boot of device. Thanks!
bitboy85 commentedon Mar 9, 2022
Are you trying to switch between a normal and an absolute mouse?