rust-embedded / wg

Coordination repository of the embedded devices Working Group
1.87k stars 95 forks source link

USB stack #40

Closed japaric closed 1 month ago

japaric commented 6 years ago

This issue is for gathering resources on writing USB firmware in Rust and for tracking progress on building a generic USB stack in Rust.

This is basically a place where people working on USB firmware can post about the progress they have made, exchange notes, etc.

People that have been doing USB stuff (that I know of):

alevy commented 6 years ago

@japaric RE: Tock, it can enumerate as well as send/receive data via control endpoints. Bulk and interrupt endpoints isn't much different but hasn't been implemented yet. Also looking at implementing the interfaces for the new NRF52 (which has USB stack) and a Synergy-IP-base one (which I believe is the same as the STM32 series). Those span very different levels of abstraction from the hardware, which we're hoping will help either validate or suggest changes to the interface.

Related note, I think the really hard part, in general, for this is going to be abstracting enumeration since lots of hardware seems to want the descriptors to be laid out in particular ways in memory that are often quite different. So my 2 cents is that's gonna be the interesting place to focus on interface (Tock hasn't really done that yet, aside from taking a guess)

jcsoo commented 6 years ago

I've been working on USB stacks for a couple of different MCUs (STM32F4 / F7 and K64, hoping to get to STM32F0, STM32L4 and SAMD21 soon) and device classes (HID, CDC-ACM, CDC-EEM, and hopefully CDC-ECM soon). I feel like I have a reasonable grasp of potential traits for basic lower-level USB drivers that could work across all of these - you set up descriptors and buffers owned by the driver and simply copy into them. I think it should also be possible to come up with lower level traits to support zero-copy buffer passing, but implementation would be quite a bit more complicated and I don't currently have any boards with USB HS that would justify the effort.

I haven't run across any issues in sending descriptors themselves - as far as I know, they are just data. There may be some issues in constructing the descriptors themselves. I've mostly pre-generated device descriptors as const data and then copied them onto the stack, updating fields as necessary before sending them.

It would be really nice to have a Rust crate to construct and parse descriptors, particularly HID reports descriptors.

LunNova commented 6 years ago

I've been trying to get USB working here on the blue pill: https://github.com/nallar/BluePillKeyboard/blob/master/src/usb/mod.rs

Doesn't work yet and uses types from stm32f103xx so couldn't be used with anything else.

kinnison commented 6 years ago

I got very stuck when trying to work out how to update svd2rust to deal with registers which contained write-to-toggle bits (the stm32f103 and similar devices have, in their USB peripherals, registers which contain read/write bits where you write zero to leave alone and 1 to toggle).

japaric commented 6 years ago

@kinnison Could you open an issue in the svd2rust repo describing the issue you are running into? I'd be happy to look into it.

@nallar

uses types from stm32f103xx so couldn't be used with anything else.

I think that's fine to start with. We should have at least, ideally independent, two implementations of USB for different devices then we can think about what, or what level, things can / should be abstracted into traits / common types.

lylecheatham commented 6 years ago

I'm interested in potentially using rust to write firmware for a 3D printer, but it would most definitely require a USB stack as the bandwidth difference between using real USB vs something like an FTDI is several orders of magnitude.

wez commented 6 years ago

I'm interested in contributing time on this for the ATSAMD21 boards that adafruit produces (https://github.com/rust-lang-nursery/embedded-wg/issues/61)

ah- commented 6 years ago

I've now got simple USB with enumeration and HID input working on an STM32L1: https://github.com/ah-/anne-key/tree/master/src/usb

It's still pretty rough, but it works. Will clean it up over the next few days.

zklapow commented 6 years ago

@wez have you made any progress on your USB work for the SAMD21? I am also starting to work on a USB stack for the SAMD21G18A but I know next to nothing about USB so it has been slow going so far

wez commented 6 years ago

@zklapow https://github.com/wez/atsamd21-rs/tree/master/hal/src/usb is where I've started to pull some things together. It's a very thin veneer over the peripherals at this stage. I've also been studying a couple of other implementations (tock and the anne-key mentioned above) and reading specs.

zklapow commented 6 years ago

@wez awesome I saw that and have been building off it a bit, you may see some PRs from me soon!

mvirkkunen commented 5 years ago

Just to let everybody know, I've been working on a generic USB stack crate plus a sample hardware implementation crate for STM32F103 chips for the past few weeks. I've gotten it to a point where I'm mostly happy with the API for both implementing USB classes and using them as an end-user. It's currently functional enough to be able to implement a simple CDC ACM serial port and talk back and forth to a computer.

There's still a lot of standard USB functionality missing and/or hand-waved currently though, so it's nowhere near done yet, but it's quickly getting to the point that I could publish it for everybody to play around with. I have to work out some issues with getting the stm32f103xx-hal crate to play along first.

kinnison commented 5 years ago

@mvirkkunen That sounds awesome. Once you have something you feel works nicely with current nightly and perhaps on the Blue Pill (stm32f103cbt6 IIRC) then I'd be pleased to give it a go and comment.

kellerkindt commented 5 years ago

@mvirkkunen That sounds awesome. Once you have something you feel works nicely with current nightly and perhaps on the Blue Pill (stm32f103cbt6 IIRC) then I'd be pleased to give it a go and comment.

Same here, great work

TeXitoi commented 5 years ago

@mvirkkunen is using a (PA12 resistor tuned) blue pill board.

cc @kinnison @kellerkindt

mvirkkunen commented 5 years ago

I've published a work-in-progress version of my USB stack. The only device implementation is currently for STM32F103 chips, and it comes with a couple of runnable examples. The "serial" example should be detected as a USB serial port (tested on Linux and Windows 10) and loop back any input converted to uppercase as an example.

There's still a lot of work to do here to implement the rest of the standard, and also implement device class crates which would make this much easier to use in practice (I'm planning to do a better serial port crate as well as a simple HID device crate), but it's a start.

https://github.com/mvirkkunen/usb-device https://github.com/mvirkkunen/stm32f103xx-usb

ah- commented 5 years ago

Oh this is amazing! Can't wait for it to be somewhat stable.

RandomInsano commented 5 years ago

@mvirkkunen What would you want help with here? I still need to bootstrap myself into Rust embedded development (I've been running on a Pi mostly which doesn't count :D).

I'm most interested in HID support, which does need to be its own crate. Maybe making use of macros to build the HID report.

mvirkkunen commented 5 years ago

@RandomInsano What I think I need the most is feedback on the API, once it's at least somewhat stable (not quite yet). My idea is to design a USB stack that will be usable on many platforms and with many USB classes, and reasonably easy to use for end-users and it would be great to get feedback from people who have worked with USB before and people who are more familiar with various device families.

I think it only makes sense to start making other dependent crates once the API is at least somewhat stable. I haven't even versioned it so far.

wez commented 5 years ago

I've managed to successfully implement the device specific portions of @mvirkkunen's usb_device crate for atsamd21; I'm pretty stoked because it was a hard slog. https://github.com/wez/atsamd21-rs/issues/11 is tracking some outstanding issues before we can call this "done". I'm excited to see this moving forwards!

kevinmehall commented 5 years ago

I have the usb crate name from a pre-Rust-1.0 attempt to write a libusb wrapper that has since been deprecated in favor of libusb-rs. I was thinking that it should be repurposed into something like the http crate, with things like descriptors that could be shared across host and device implementations.

https://github.com/kevinmehall/rust-usb/issues/19

azasypkin commented 5 years ago

In case it's useful to anyone, here is yet another narrowly specialized USB HID implementation for STM32F0 inspired by anne-key and stm32plus. It's very rough, but works nevertheless.

There is also a test hidapi/libusb-based CLI tool to interact with this USB device.

therealprof commented 5 years ago

@azasypkin Wow, this is awesome! On a first glance this might be a nice project for the showcase, would you like to submit it?

azasypkin commented 5 years ago

On a first glance this might be a nice project for the showcase, would you like to submit it?

Yes, definitely, thanks! I'll clean it up a bit and submit.

timonsku commented 4 years ago

Not sure how useful it is at this point but there is TinyUSB which is being adopted in a lot of places now. Maybe something a rust stack can profit from? https://github.com/hathach/tinyusb

twitchyliquid64 commented 4 years ago

Just dropping by to mention atsamd contributors have finished implementing working USB drivers for the samd21 & samd51 crates, entirely interrupt driven. This was built on wez@'s existing implementation.

As far as I'm aware, this makes it the third implementation of the usb-device HAL.

I'm also working on a HID class crate (implementation of functionality is decoupled from the underlying device thanks to mvirkkunen's excellent HAL), and hoping to have an alpha API / crate soon. (descriptor generation WIP, class WIP)

nickray commented 4 years ago

Congrats :) We also have USB support in https://github.com/nickray/lpc55-hal/, and a custom HID class in https://github.com/nickray/usbd-ctaphid. Happy to move to usbd-hid once it's done!

TeXitoi commented 4 years ago

@twitchyliquid64 for HID, I use https://github.com/TeXitoi/keyberon/blob/master/src/hid.rs and there is demands on a published crate on https://github.com/TeXitoi/keyberon/issues/14#issuecomment-569563329

I didn't wrote the code, just add a few thing for my needs. Working great, but I'm sure it's possible to do much better. Will try to have a look at your WiP.

twitchyliquid64 commented 4 years ago

I've pushed an alpha version of usbd-hid here: any feedback? is it understandable?

Still need to implement reading host -> device reports, but that should only be 10 lines or so.

thejpster commented 4 years ago

Has anyone done any work on a USB Host HAL? I guess it would look like OHCI, or UHCI (or EHCI or XHCI?).

olback commented 2 years ago

@thejpster @bjc has made something that looks interesting. USB Host Driver traits: https://github.com/bjc/usb-host ATSAMD Host HAL Driver: https://github.com/bjc/atsamd-usb-host/tree/next Keyboard driver: https://github.com/bjc/bootkbd

Not tested any of them though.

paulyoung commented 7 months ago

I found this thread because I have an STM32F723 Discovery kit which has host functionality.

To summarize my findings so far:

If anyone knows of any other updates, or has advice for how I might go about working on this, please let me know!

paulyoung commented 7 months ago

https://github.com/nviennot/turbo-resin/blob/6cd8f7567e81c6159c356ea18b5942237f86e47d/src/drivers/usb/usb_host.rs appears to refer to STMicroelectronics/stm32f1xx_hal_driver

For my board the equivalent would be STMicroelectronics/stm32f7xx_hal_driver

jamesmunns commented 1 month ago

Closing this as part of 2024 triage.

As of now, the charter of the WG is to focus on foundational crates and functionality, rather than develop solutions for all use cases. However, as of today there are the following existing solutions, and folks finding this issue are suggested to contribute to one of the following projects:

If you think this was closed incorrectly, please leave a comment and we can revisit this decision in the next weekly WG meeting on Matrix.