Skip to content

Conversation

piotrfila
Copy link
Contributor

This PR is my shot at a better USB driver implementation.

Key changes:

  • Multi-function (composite) devices now possible
  • Descriptors are automatically constructed at compile time by drivers
  • More type safety around descriptors
  • Fixed a bug where tx data was lost if inconsistent buffer sizes were used
  • Limited use of dynamic dispatch

I'm open to suggestions for changes

Copy link
Contributor

@arkadiuszwojcik arkadiuszwojcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great rework! The USB drive code is much cleaner now. Here are my initial comments. I'll try to more detailed review later.

if (this.rx_buf) |rx| {
const len = @min(rx.len, dst.len);
// TODO: please fixme: https://github.com/ZigEmbeddedGroup/microzig/issues/452
std.mem.copyForwards(u8, dst, rx[0..len]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding those "TODO #452" memcpy should be part of DeviceInterface I guess as it is in TinyUSB and CherryUSB projects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, the @memcpy builtin is meant to provide a good implementation regardless of the target.
After checking on actual hardware, it seems like the issue is gone, maybe because of the recent rom changes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is issue description in:

Don't know what to think about it. At least I would extract it to some inline usb_memcpy function and use std.mem.copyForwards or @memcpy inside for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usb DPRAM behaves like regular memory unlike most peripheral memory.

image

As per zig documentation on @memcpy both source and destination can have any alignment.

I can't comment on how good the memcpy implementation is, but judging from the lack of HardFault exceptions raised it must be correctly handling unaligned data. I also disassembled the .elf file of the hid example and the implementation of __aeabi_memcpy uses ldrb and strb instructions, which work on unaligned data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I got this mixed up, but the whole time I was thinking it was the RP2040 that had problems with memcpy. #452 of course clearly states the bug affects RP2350...

And unsurprisingly the datasheet documents this:

image

This is rather annoying. How are we supposed to guarantee that the optimizer does not use unaligned LDR/LDRH? I originally wanted to avoid needlessly copying the buffers but that seems like the simplest option now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we must read/write data to some intermediate buffer (in main memory) to make sure that aligned nonoptimized memcpy operation is used right?

@arkadiuszwojcik
Copy link
Contributor

@piotrfila, what toolchain version are you using, and which boards were tested? I am using Zig 0.14.1 on Windows and tried to run this code on the RP2040 and RP2350 (Arm cores). For the RP2350, I get some Windows USB errors, and the RP2040 is somewhat unstable—sometimes it works, and sometimes it doesn't.

@piotrfila
Copy link
Contributor Author

I am also using 0.14.1, but I have done all the testing under Linux, where RP2040 seems to work fine.
RP2350 indeed HardFaults even before enumeration, oops. I should have tested that.

@piotrfila piotrfila marked this pull request as draft August 28, 2025 07:40
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.

2 participants