Skip to content

Conversation

@Ivan-Johnson
Copy link
Contributor

@Ivan-Johnson Ivan-Johnson commented Dec 29, 2025

I've started working on USB support for the Arduino Micro (#40). There's still a lot of work left to do, but I'd like to get your feedback on the big-picture design stuff before I get too far into the implementation @Rahix.

I've got a bunch of TODOs with design questions in the PR itself, but there are a couple of other things that I wanted to ask about as well:

  • I've created a new usb-support feature in both arduino-hal and mcu/atmega-hal; since I'm only testing arduino-micro, I'm thinking that it's better to have the new USB functionality disabled by default everywhere else. Is this the right call? Or is it better to remove the feature flag(s) and have the functionality always enabled in atmega-hal?

  • When I make changes to this PR would you like me to squash the new changes with the previous version, or is it easier for you if I keep the commits separate until we're almost ready to merge?

Fixes Rahix#40.

The purpose of this PR is to add USB support for the `atmega32u4`. This
is done using rust-embedded-community/usb-device GitHub repo, since that
appears to be the most popular crate this sort of thing.

When using `usb-device`, there are three main components to be aware of:

* For `avr-hal`, the main thing we care about is `UsbBus`. This trait is
  a hardware abstraction layer for the actual USB hardware. We implement
  this trait in `mcu/atmega-hal/src/usb.rs`.

* The `UsbClass` trait is used to implement support for each different
  type of USB device (e.g. speaker, keyboard, or serial port). These
  implementations are portable, so we can just use existing
  implementations from other crates. For `micro-usb-serial.rs`, we
  create a serial port using `usbd-serial`'s implementation of
  `UsbClass`.

  `usbd-serial` was chosen simply because it is the only serial class
  implementation that is mentioned in `usb-device`'s readme file.

* `UsbDevice` is used by our users (and our example code) to actually
  configure the USB device. Basically, to create `UsbDevice` the user just
  needs to combine our `UsbBus` implementation with the list of
  `UsbClass`es that they want to use.
@Ivan-Johnson
Copy link
Contributor Author

Ivan-Johnson commented Jan 5, 2026

Over the last week I've spent quite a few hours reading through the atmega datasheet and working on implementing this PR. In the process, I've made a few design changes; in brief:

  • Given all the time I'm putting into this I've decided that I might as well support all atmega32u4 platforms, rather than just the Arduino Micro. I haven't yet purchased an Arduino Leonardo or Sparkfun Promicro, but I'll do so eventually and verify that they work before we merge this PR

  • I propose that for this PR, we disallow the hardware timer from using PLL while the USB bus is active. We can add support for that in a future PR. In order to make it easier to implement that feature without breaking backwards compatibility, I've made the UsbdBus struct private.

    There are docs with more details in the PR: mcu/atmega-hal/src/lib.rs

@Ivan-Johnson
Copy link
Contributor Author

Y'know what. I think I published this PR prematurely; I'll mark it as a draft.

At work I'm so used to the design being the hard part; when I work on something difficult, I'm now in the habit of asking for feedback early in order to avoid having to rewrite the whole thing from scratch multiple times. It turns out that doesn't really apply here because the design isn't the hard part; the vast majority of the difficulty is grokking how everything works 😅

@Ivan-Johnson Ivan-Johnson marked this pull request as draft January 15, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant