-
-
Notifications
You must be signed in to change notification settings - Fork 59
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
Add support for programming over USB #208
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work getting this working! I've made a few suggestions.
4f36857
to
77ebf82
Compare
8486b47
to
72d3412
Compare
909644d
to
24871fa
Compare
This is able to receive a program. Still cleaning up changes to pybricks/pybricksdev#69, but that should be available in a day or two. This is currently not sending the hub kind or variant. I'm not sure this is needed, but I could encode that in the BOS descriptor using the PnP ID UUID, like in BLE. What do you think, @dlech? |
Amazing! I've been wanting to take this for a test drive but haven't had time yet.
This is not needed since it can be inferred from the USB VID/PID. |
I'm pretty happy with how it came together. My main concern now is that it will only work on a SPIKE Prime because I don't have any of the other bricks to test it with. How do you think we should handle that?
In pybricksdev, should I set the |
You can find all of the numbers here (both USB PID/VID and hub kind/variant): https://github.com/pybricks/technical-info/blob/master/assigned-numbers.md
I can test the other hubs. We will need to add some code that reads the variant in the case of SPIKE Prime and Robot Inventor that will select the correct PID at runtime. The SPIKE Essential hub can just have the PID as a compile option. |
ebcb76d
to
a519633
Compare
I finally had a chance to try this out. I've made a few changes I would like to incorporate and pushed them to https://github.com/pybricks/pybricks-micropython/tree/dlech-usb. I didn't want to push to your branch since you are still working on this. Very cool that it "just works" on Windows. Also tested on Linux. |
((USBD_Pybricks_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hPybricks->RxBuffer, &hPybricks->RxLength); | ||
|
||
return (uint8_t)USBD_OK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
((USBD_Pybricks_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hPybricks->RxBuffer, &hPybricks->RxLength); | |
return (uint8_t)USBD_OK; | |
return ((USBD_Pybricks_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hPybricks->RxBuffer, &hPybricks->RxLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also check other function calls like this to make sure we aren't ignoring return values. (If there is a good reason for ignoring a return value, we should add a comment explaining why.)
I was also wondering if you gave much thought to using bulk transfers vs interrupt transfers? |
Great! What is your strategy for this branch? Do you want me to work those changes into my patches or keep those separate?
What are you using for your backend? I can't remember exactly but I think I downloaded https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26-binaries.7z and copied
I intended to go with an interrupt transfer because it seemed like the amount of data needing to be transmitted was so small that any performance increase from using a bulk transfer would be negligible. Looking at the capture in Wireshark though it looks like it is using a bulk transfer? PyUSB supposedly infers the correct method, which I thought would have been an interrupt transfer because the endpoints are created using |
The
I didn't get that far yet on Windows. I just plugged it in to make sure that the driver matching works. If I can find the time, I would eventually like to make a Python Windows USB library using PyWinRT so that we don't have to worry about libusb there and everything is async.
Using interrupt transfers seems like the right choice for this application to me too. It looks like "Bulk" is specified currently in |
Yeah, no problem!
Are you planning on that for a future improvement or as part of this?
Yes, you're right! I'll change that and see how it works. |
Depends on if I have time and motivation 😄 So, I guess consider it a future improvement for now. |
I would expect that it could. It's just a matter of figuring out how to setup all of the config/descriptors/etc. to be the same. |
You're welcome :) My understanding is that LEGO has discontinued the EV3. What's the purpose in continuing to support that platform? I imagine there are plenty of EV3 users out there still, but didn't know if there was more to it than that. |
That's precisely it. There are numerous EV3s out there, and it is still the platform of choice for many competition teams. By making it a bit more like SPIKE (possibly but not necessarily without Linux) it could work with the web IDE just like the others. Once the initial chunk of development is done, it could mostly just be taken along for the ride as we add features to all platforms at once. LEGO Education recently discontinued the Android and iOS apps (but reneged on this for a few more months after very strong public outcry). Most schools can't just switch to the desktop version. So it's also from a sustainability point of view, avoiding hundreds of thousands of EV3 bricks becoming e-waste overnight. Or put differently - you can still build with regular bricks from 1960, so why give up on elements sold as recently as 2018? 😄 |
5cca9dc
to
5a78c75
Compare
Uses a single-byte message ID instead of 16-byte UUID. Still on the TODO list are:
|
That makes sense, and it's great that existing teams wouldn't have to purchase new kits when their existing stuff works just fine. I don't have an EV3 and so wouldn't be able to help with that. |
Updated TODO list:
|
The commit "Add function to read VBUS status" should no longer be needed, so I think we can drop that one. Then to break this down in to smaller parts for testing and final review, it would be nice if we could get all of the BOS stuff working and tested and merge that first, then look at the Pybricks profile stuff. |
Adds a new Pybricks device class and provides the correct descriptors so that Windows will use the WinUSB driver. Signed-off-by: Nate Karstens <[email protected]> Co-authored-by: David Lechner <[email protected]>
Adds function to copy UUIDs in little endian format. USB is a little endian protocol, so this will be used to encode UUIDs properly on this medium. Signed-off-by: Nate Karstens <[email protected]>
Adds additional information to the BOS Descriptor by appending dynamically-generated platform descriptors that use the same UUIDs that are used with BLE and contain the following values: * Device Name * Firmware version * Software (protocol) version * Hub capabilities Signed-off-by: Nate Karstens <[email protected]>
Configures the USB device and processes pybricks commands. Signed-off-by: Nate Karstens <[email protected]>
Transmit the response to a command. This is used to communicate any errors in handling the command back to the user. Signed-off-by: Nate Karstens <[email protected]>
Periodically sends status flags over the USB connection. Signed-off-by: Nate Karstens <[email protected]>
Adds support for transmitting stdout messages over USB. Signed-off-by: Nate Karstens <[email protected]>
Adds a WebUSB platform descriptor to the BOS descriptor and a landing page pointing to https://code.pybricks.com. Signed-off-by: Nate Karstens <[email protected]>
Sounds good, I dropped the VBUS status change. WebUSB is still a work-in-progress but support for that is optional. I think we could go ahead and start working on merging changes in. |
Thanks again for your contribution. Could you perhaps add a status summary to the first post in this thread? It would be great to have an overview of:
I'd also love to know what the currently intended user experience is, perhaps in tandem with #195. Is USB currently disabled when the user is connected via Bluetooth or not, for example? What if users try both at the same time? Is Bluetooth still the default even when USB is plugged in (because it might just be charging)? I'd be happy to start helping review this and work towards getting it merged. Separately, I've previously mentioned EV3 compatibility. This is probably a bit too far off. However, the NXT is starting to look a bit more realistic at this point. Other than a lacking implementation of connectivity for download and run, it is now running "standard" Pybricks (i.e. "like SPIKE Prime") as of this writing. Now that we've gotten this far, I think I'll go ahead and start implementing motors and sensors, which shouldn't be the biggest hurdle. Its USB driver (obtained from another project) is here. Do you think this contain enough handles to implement something similar as in this PR? Even if we don't go ahead and do this for now, it would be great to have the big picture. Thanks! |
I'm still just looking at this with a bird's-eye view as I am catching up with the changes. USB and Bluetooth are not my key expertise, so please forgive me if I'm getting a few things wrong 🙂 Following up on the above, I suppose that USB is intended an alternative to Bluetooth. Supposing that is the case, do we need to handle both USB, BLE (and soon BT) separately at the highest levels? For example, currently Then So basically what is currently Such a BLE/USB/BT mode might also be one way to address the notes above:
|
If you mean in the firmware, no. If you mean in Pybricks Code, yes.
Yes. I would expect this to be like upstream MicroPython's dupterm feature.
There is no "active" mode from the firmware point of view. I.e. all events would be sent to all active connections.
If users try to use both at the exact same time, like downloading a program, it could be problematic. But we can protect against this in Pybricks Code. |
Thanks for getting back!
So am I understanding correctly that what's currently in And continuing on that, getting BT-RFCOMM-NXT working will be a matter of implementing a driver backend for "pbsys/protocol" to call into, inspired by the |
Hello, thank you for all the work done! 😄 I am trying to send data via USB to my SPIKE Prime. But when I want to send some demo via USB, through the command
Have I skipped any step? Since I would like to integrate this in the pybricks code builder, to be able to send data to the SPIKE Prime via USB. Thanks in advance! |
Any updates? Do you plan to push usb programming feature to master branch? |
I'm afraid it probably won't be in the near future. There would be a long way to go to finish this both in the firmware and the editor. We have limited time and resources, and other aspects currently have priority. Thanks for your understanding. |
Gets Windows to use the WinUSB driver for device. No other functionality is provided at this time.
See pybricks/pybricksdev#69 for changes to pybricksdev.