8000 RawHID support · Issue #25 · adafruit/Adafruit_CircuitPython_HID · GitHub
[go: up one dir, main page]

Skip to content

RawHID support #25

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

Closed
timonsku opened this issue Jul 26, 2018 · 21 comments
Closed

RawHID support #25

timonsku opened this issue Jul 26, 2018 · 21 comments

Comments

@timonsku
Copy link
timonsku commented Jul 26, 2018

Something that would be very helpful in communicating with computer side frameworks as an alternative to VCP would be the possiblity to have a RawHID class.
My understanding of USB is not too in-depth but afaik this would just mean a new descriptor that allows for a report of the maximum possible size to send buffers back and forth.

Right now I can already do this with the existing classes, I'm just limited to very few bytes per transaction and can't receive something back.
F.e. with the consumer key device:

import usb_hid

value = 4024
code = bytearray(2)
bytes = value.to_bytes(2,'big')
for device in usb_hid.devices:
            if device.usage_page == 0x0C and device.usage == 0x01:
                print('found consumer device')
                myDevice = device
                break
device.send_report(bytes)

I found this in the mpy docs but apart from this lonely docs page not much more and the pyb module does not seem to exist in CPY.

@tannewt
Copy link
Member
tannewt commented Jul 30, 2018

I'd rather support a second cdc connection as tracked by: adafruit/circuitpython#231

Please reopen if you need HID specifically.

@tannewt tannewt closed this as completed Jul 30, 2018
@timonsku
Copy link
Author

Seems I can't reopen by myself but yes, HID specifically would be what I'm interested in. I want to avoid serial all together as it poses a lot of trouble in the use cases I have. HID has proven to be a very robust way of communication. I think the second CDC port wants to tackle a different issue.

@tannewt
Copy link
Member
tannewt commented Jul 30, 2018

Could you elaborate more on what you are doing then? Thanks!

@tannewt tannewt reopened this Jul 30, 2018
@timonsku
Copy link
Author
timonsku commented Jul 30, 2018

Sure thing!
The main use case is getting data transmitted and received from an application running on Windows or Linux. The obvious way for that is using Serial though that comes with more than a few caveats.

First comes the uncertainty of the serial port number enumeration, this behaviour is the same on Windows and Linux (and Mac), after every reboot, your device might enumerate under a different port number. There are ways to circumvent this by having a hwid to port number resolver but that requires certain access to the OS and aren't always easy to implement in every framework.

Next and probably the most annoying one are the bugs that are often happening with the Serial port management on both Windows and Linux. It is far to common that a com port lands in a sort of zombie mode if the application using it had an issue/crashed or sometimes nothing apparent happening. Then the port is inaccessible until a system restart. This never happens to HID devices as they can have multiple users, every program is allowed to listen to an HID device, this is not the case with Serial ports. This is another big plus for HID if you want several applications listen to the same device.

Next issue is the unreliability of a transaction with Serial. There is no way of knowing if you fully received a message so you always have to spin a protocol in order to have any meaningful conversation with the device. HID is much more robust in this regard and does all of this for you. If you just want to share a few values with your PC application you can do this right away without any complexity and with a very high data rate.

When I talk about "frameworks" I mean things like openFrameworks, VVVV and more generic things like node.js and Python . These frameworks typically have support for reading HID device reports because the industry behind them often has to interface with odd hardware that quite often uses HID. So the support on the PC side is usually quite good but on the Microcontroller side there really only is Teensy if you want more than Mouse and Keyboard support.

If CPY HID support correlates in anyway to the Arduino cores HID support I also gladly see this on the Arduino side in addition to CPY.

If sponsoring the development can help in any way to get this feature implemented let me know!

@tannewt
Copy link
Member
tannewt commented Jul 31, 2018

Thanks for the detailed explanation! Its not a high priority for us but may be easy to add.

I believe the place to start would be with the built in HID descriptors here: https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/tools/hid_report_descriptors.py They are then added to the full descriptor here: https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/tools/gen_usb_descriptor.py#L302

I think that once its added there it'll be available in usb_hid.devices.

@timonsku
Copy link
Author

Are OUT endpoints represented in the API yet? That seems like it would be the biggest chunk of work if that doesn't exist yet. Getting the descriptor going shouldn't be too hard, having a look at some Arduino implementation probably helps.
Teensy: https://github.com/PaulStoffregen/cores/blob/master/usb_rawhid/usb.c#L58-L90
AVR: https://github.com/NicoHood/HID/blob/master/src/SingleReport/RawHID.cpp#L26-L48

@tannewt
Copy link
Member
tannewt commented Aug 2, 2018

Ah, OUT for HID isn't at the moment. I bet we'll want to add it as a queue of incoming reports.

@timonsku
Copy link
Author
timonsku commented Aug 2, 2018

Queue sounds good!

@fgervais
Copy link

I'd also be interested in that feature

@luolou
Copy link
luolou commented Dec 18, 2019

Can Adafruit_CircuitPython_HID operate in Python?
An error appears when I run this in Python:
ModuleNotFoundError: No module named 'usb_hid'
Anyone knows the reason?

@timonsku
Copy link
Author

@luolou thats a totally different issue but to answer that quickly, no if you are trying to run this on an SBC/Desktop, this will not work

@timonsku
Copy link
Author

@tannewt could this get another shot? @hathach added raw hid support in TinyUSB a while back :)

@dhalbert
Copy link
Collaborator

I started working on raw HID for a special project but it's not at the top of my stack right now.

@tannewt
Copy link
Member
tannewt commented Dec 18, 2019

@deshipu started adding OUT support here: adafruit/circuitpython#2366

It is very basic for numlock only.

@luolou
Copy link
luolou commented Dec 18, 2019

@luolou thats a totally different issue but to answer that quickly, no if you are trying to run this on an SBC/Desktop, this will not work

@PTS93 I run this on laptop(windows10 OS). Does this only run on adafruit devices? Whether regular computers also need support?

@timonsku
Copy link
Author

@luolou this will only work on microcontrollers that have native USB device support and are supported by CircuitPython. No Laptop or Desktop computer will ever work with this library as they are not USB devices but USB hosts. This library only supports "emulating" HID devices which talk to a USB host like a laptop or desktop PC. E.g. a keyboard that plugs into your laptop. Your laptop is not capable of acting like a keyboard to another computer through a USB connection.
If you have further questions please post them in the Adafruit Forums: https://forums.adafruit.com/viewforum.php?f=60
Or on the Adafruit Discord.

@luolou
Copy link
luolou commented Dec 18, 2019

@PTS93 Thank you for your help.

@dhalbert
Copy link
Collaborator
dhalbert commented May 4, 2021

CircuitPython 7.0.0 will allow you to supply your own HID report descriptors, and so will support raw HID. See adafruit/circuitpython#4689, which is still in process. That PR only provides one HID device descriptor, which means you can only have raw, and no other HID devices, but could be extended in the future to support multiple HID devices (one raw, one conventional with multiple devices). Please open an issue in circuitpython if you will need multiple HID devices. I will close this for now.

@dhalbert dhalbert closed this as completed May 4, 2021
@timonsku
Copy link
Author
timonsku commented May 6, 2021

@dhalbert cool, will this also take care of being able to listen to both in and out endpoints? Afaik there was no API for the in endpoint.

@dhalbert
Copy link
Collaborator
dhalbert commented May 6, 2021

There is now a .last_received_report attribute which was added to read LED status on keyboards, but I think it would work for this

@dhalbert
Copy link
Collaborator

adafruit/circuitpython#7806 fixes a problem that gets in the way of raw HID, and should now allow this. There are some test programs there.

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

5 participants
0