Skip to content

Raspberry Pi Pico: Exposing USB device support #6811

Description

@mcassaniti

Is it possible or a reasonable to ask about exposing USB device support in MicroPython similar to the support for the PyBoard?

Beyond that, is it reasonable to expose even more support so that custom USB devices could be created? For example, a custom U2F token running from MicroPython or an OpenPGP card implementation. I'm sure someone can come up with examples that aren't security related.

Original issue: https://github.com/raspberrypi/micropython/issues/5

Activity

  1. safijari commented on Feb 1, 2021

    @safijari

    Unsure if this is the right place but anyone that lands here because they want to make a keyboard/macropad/whatever with the pico please note that you can install CircuitPython and the HID functions work fine under CircuitPython (as does the adafruit HID library). KMK is also likely to work but I haven't tested it.

  2. matemaciek commented on Feb 11, 2021

    @matemaciek

    I'd love to see USB host support in MicroPython for Pi Pico, I could help in implementation.

  3. AngainorDev commented on Feb 13, 2021

    @AngainorDev

    Also eagerly waiting for USB_HID to be available on micropython.
    Is there someone actively working on this?
    What would be needed?

    Since this works on circuit python, I guess mainly the core usb lib needs to be ported.
    I'm not familiar with differences between circuitpython and micropython, but this seems a reasonable task.
    How could I help?

  4. LennartPiro commented on Feb 13, 2021

    @LennartPiro

    @AngainorDev there is a USB implementation for the pyboard in MicroPython:

    // MicroPython bindings for USB
    /*
    Philosophy of USB driver and Python API: pyb.usb_mode(...) configures the USB
    on the board. The USB itself is not an entity, rather the interfaces are, and
    can be accessed by creating objects, such as pyb.USB_VCP() and pyb.USB_HID().
    We have:
    pyb.usb_mode() # return the current usb mode
    pyb.usb_mode(None) # disable USB
    pyb.usb_mode('VCP') # enable with VCP interface
    pyb.usb_mode('VCP+MSC') # enable with VCP and MSC interfaces
    pyb.usb_mode('VCP+HID') # enable with VCP and HID, defaulting to mouse protocol
    pyb.usb_mode('VCP+HID', vid=0xf055, pid=0x9800) # specify VID and PID
    pyb.usb_mode('VCP+HID', hid=pyb.hid_mouse)
    pyb.usb_mode('VCP+HID', hid=pyb.hid_keyboard)
    pyb.usb_mode('VCP+HID', pid=0x1234, hid=(subclass, protocol, max_packet_len, polling_interval, report_desc))
    vcp = pyb.USB_VCP() # get the VCP device for read/write
    hid = pyb.USB_HID() # get the HID device for write/poll
    Possible extensions:
    pyb.usb_mode('host', ...)
    pyb.usb_mode('OTG', ...)
    pyb.usb_mode(..., port=2) # for second USB port
    */

    Maybe this is a good starting point in porting it to the Pico? I'm not good enough at C programming to make much sense of it.

  5. AngainorDev commented on Feb 13, 2021

    @AngainorDev

    @LennartPiro
    I had a look at adafruit implementation as well, and it's quite different (shared lib, for all ports)
    I guess the way to go here would be to follow the existing pyboard implementation, since it's also tied to the existing, working VCP interface.
    I also saw some PR or Issues about using the default tinyusb lib instead of the pico sdk provided one, things lying there as well probably.

    Someone with background on that low level code and USB implementation would be needed I'm afraid.

  6. robin7331 commented on May 3, 2021

    @robin7331

    Is there any update on this?

  7. mrkprdo commented on May 3, 2021

    @mrkprdo

    Add me to the list here.

    I just wanted to point out that one of my struggles using Circuitpython for usb hid is that it has no _thread support, which makes it difficult to perfrom concurrent functions. While Micropython does have minimal support for _thread, it will be more benificial to have usb hid device as well.

  8. GregWoods commented on Aug 9, 2021

    @GregWoods

    MicroPython really is the neglected younger sibling to C/C++ in the Pico world.
    I struggle to see how a maker focused device could even be released without HID support. It is a huge part of the hobbyist microcontroller community. I really can't stomach going back to C, and hate switching between CircuitPython and MicroPython for every other product. Please can we have some traction on this.

  9. robin7331 commented on Aug 11, 2021

    @robin7331

    You might wanna look into my thread on the RPi forums
    Its not an official library but it seems to work fine for HID :)

  10. WernerFS commented on Jan 10, 2022

    @WernerFS

    I have been porting my MP code to CP just to findout that I need to create a new board in order to use it. CP is nice and all but I cant bear the fact that if you work on a custom board it need to be re-compiled. USB HID in MP is a must.

  11. tannewt commented on Jan 10, 2022

    @tannewt
    Sponsor

    I have been porting my MP code to CP just to findout that I need to create a new board in order to use it. CP is nice and all but I cant bear the fact that if you work on a custom board it need to be re-compiled. USB HID in MP is a must.

    Custom boards often use different flash chips. A generic build will have a slow but universal setup for the flash. Using a custom build allows for an optimal flash setup for a given board.

  12. theboyknowsclass commented on Jul 10, 2022

    @theboyknowsclass

    any word on this being added? (esp for pico w)

  13. ofirgaash1 commented on Jul 27, 2022

    @ofirgaash1

    please, please add HID to MP

  14. WarpRomo commented on Jul 31, 2022

    @WarpRomo

    for tha love of god, add it

  15. 4 remaining items

  16. jimmo commented on Aug 27, 2022

    @jimmo
    Member

    Hoping it can't be bricked so I don't need to buy an external programmer or something

    Yes, it is almost impossible to brick a device these days, and fortunately the Pico board has an easy "boot" button to get to the uf2 bootloader. The bootloader is in ROM so you can't overwrite it by accident.

    (I have never bricked a single microcontroller while working on MicroPython)

    You can also use a second Pico as an external (SWD) debugger for a Pico. Not sure if that supports uploading code though.

    Once I get my code working, I would of course like to make the usb module.

    There's a lot of scope here, and it impacts several ports (mimxrt, samd, rp2, esp32s*, nrf and potentially stm32). Also questions about how this works with host mode, and potentially whether we want to use the tinyusb device class implementations or something more Python-based.

    So, great to experiment, but I don't have any specific advice to give here yet. Anything you find out will be useful though to help figure out how to approach this.

  17. elpekenin commented on Aug 27, 2022

    @elpekenin

    Thanks for the detailed info, once again

    My next steps will be

    1. Of course, test the (allegdly) HID-enabled firmware i made the other day and get it working
    2. Try and build a usb module which unifies all the pieces of configuration, and provides a standarized API (mode method, keyboard/mouse/consumer classes, ...)

    Actually, there is no point on adding a global module, since it would just be using the underlying API. Having port-specific modules would be harmless to other ports and eaiser to maintain&test

    I'm by no means a software-engineer, I'm open to ideas but this feels like a decent way of approaching the problem.
    Will be sharing updates as soon as i get back working on this project in a couple of days. (perhaps spamming this issue page isn't the best place to do so, should I move the convo elsewhere?)

  18. mcassaniti commented on Aug 28, 2022

    @mcassaniti
    Author

    I'm by no means a software-engineer

    I can't say I agree with you @elpekenin. This is exactly what I would consider software engineering to be all about.

    perhaps spamming this issue page isn't the best place to do so, should I move the convo elsewhere?

    I'd say this issue is the right place. The subscribers to the issue are the ones who are getting "spammed" and really do wish to stay up to date on anything that you can share. You might even get a few beta testers this way. The only other location I could suggest is the discussions section, but I would wait for someone to complain first.

  19. elpekenin commented on Aug 28, 2022

    @elpekenin

    This is exactly what I would consider software engineering to be all about.

    Thanks for the encouraing words :) I meant it in a "maybe there are some design patterns I'm missing" kind-off way

    I've spent several hours trying (and failing), my findings so far:
    ⚠️ Maybe I got my head tangled during the several tests, so take this with a grain of salt)

    • Adding the modusb_hid.c to CMakeLists.txt, even when not trying to add the module to mpconfigport.h:
      • Linux has no problem connecting to it.
      • Apparently breaks the W10 driver, and can't even connect to it with Thonny anymore - maybe just a typo/error on my code.
        Image
    • The way in which modules are added in mpconfigport.h has changed since noobee made their code, and I'm unsure how should i add it, I'll double-check soon, but pretty sure none of this worked:
    /* TESTING HID */
    extern const struct _mp_obj_module_t mp_module_usb_hid;
    // #define MICROPY_PY_USB_HID                   (1)    //useless config flag so far, just added so i don't forget
    // #define MICROPY_PY_USB_HID_INCLUDEFILE       "ports/rp2/modusb_hid.c"
    // #define MICROPY_PY_USB_HID { MP_ROM_QSTR(MP_QSTR_USB_HID), MP_ROM_PTR(&mp_module_usb_hid) }, 
    // #define MICROPY_PORT_BUILTIN_MODULES { MP_ROM_QSTR(MP_QSTR_USB_HID), MP_ROM_PTR(&mp_module_usb_hid) }, //noobee's way
    // MP_REGISTER_MODULE(MP_QSTR_usb_hid, &mp_module_usb_hid); 
    #define MICROPY_PORT_BUILTIN_MODULES { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid), (mp_obj_t)&mp_module_usb_hid },
  20. theboyknowsclass commented on Aug 28, 2022

    @theboyknowsclass

    Is there anything to be gained from looking at the circuit python implementation?

  21. elpekenin commented on Aug 28, 2022

    @elpekenin

    Added the MP_REGISTER_MODULE line in the own modusb_hid.c file and it worked, im now trying to get drivers working on Windows :))

  22. elpekenin commented on Aug 29, 2022

    @elpekenin

    It is """working""" already, you can check my branch here

    I'm not sure how/why the drivers were acting weird nor how i fixed it 😅

    Changes made:

    • Moved several defines to enums (im not sure i understood their meaning correctly, have some '??'s over the code)
    • Added #if CFG_TUD_HID at all my pieces of code, so it can be disabled on compile. Also added checks for stuff related with CFG_TUD_MSC and didn't have it already
    • USBD_DESC_LEN is now dynamically computed (at compile) using a multiplication thanks to the CFG flags being 1/0 (should i add some extra code to avoid problems with other values? are they already forced to be 0/1?)

    TODO list:

    • Rename module to usb
    • Rename stuff to match pyb.USB_HID's API
    • Add some documentation
    • Would like to add the module from mpconfigport.h with something like
    #if CFG_TUD_HID
    #    define MICROPY_PY_USB_HID_INCLUDEFILE    "ports/rp2/modusb_hid.c"
    #endif

    But not sure how to


    If you have some time, please take a moment to check if you run into driver issues (as i did yesterday):

    1. Compile my code with cd ports/rp2 && make submodules && make clean && make
    2. Test on your board with this little program
    import time
    import usb_hid
    
    report = bytearray(8)
    
    report[2] = 0x04 # register 'a' keycode
    usb_hid.report(usb_hid.KEYBOARD, report) # send event
    
    time.sleep(2)
    
    report[2] = 0x00 # unregister 'a' keycode
    usb_hid.report(usb_hid.KEYBOARD, report) # send event

    And you should see a bunch fo as being printed in your screen

  23. CRImier commented on Oct 8, 2023

    @CRImier
    Contributor

    @elpekenin did you delete that repo? can't find it, could use some HID in a project of mine

  24. elpekenin commented on Oct 8, 2023

    @elpekenin

    @CRImier sorry, nuked the repo a couple months back to make GitHub see it as a fork of CircuitPython instead.

    I have just pushed that branch back up:https://github.com/elpekenin/circuitpython/tree/peke-devel

    However, i ended up using QMK for HID stuff, so don't expect any further work on it. Also, be aware i made very minimal testing(and it was a year ago), i have no idea how good the code is nor how easy will it merge into current repo.

  25. CRImier commented on Oct 19, 2023

    @CRImier
    Contributor

    @elpekenin thank you so much, tinkering with it right now, works wonders!

  26. fmohtadi99 commented on Jan 7, 2024

    @fmohtadi99

    Even after around 3 years of opening this issue, there's no official update....
    Actually no attention from any of 541 contributors :))

  27. pi-mst commented on Jan 7, 2024

    @pi-mst
    Contributor

    Even after around 3 years of opening this issue, there's no official update.... Actually no attention from any of 541 contributors :))

    There has been a lot of effort on this topic, see #9497.

    This ticket should probably be closed since 9497 is under active development.

  28. LennartPiro commented on Jun 5, 2024

    @LennartPiro

    USB device support was added in MicroPython v1.23.0
    Issue can be closed.

  29. robert-hh commented on Jun 5, 2024

    @robert-hh
    Contributor

    #9497 was merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions