arm/stm32: Fix USB device driver handling on M0 parts. - #19903
Merged
xiaoxiang781216 merged 4 commits intoAug 20, 2026
Conversation
The packet memory area (PMA) accessors in the M0 USB device driver were carried over from the STM32F1 implementation, where the PMA is seen by the CPU as 16-bit values placed on 32-bit boundaries. On the STM32F0, STM32L0 and other M0 parts the PMA is a linear 16-bit memory, so the F1 scaling is wrong: - STM32_USB_BTABLE_RADDR() shifted the computed buffer descriptor offset left by one, addressing every second descriptor entry. - The buffer descriptor accessors declared the descriptor entries as uint32_t and accessed them 32 bits at a time, so each write clobbered the adjacent entry. - stm32_copytopma() and stm32_copyfrompma() scaled the PMA offset by two when computing the packet buffer address. The result is that endpoint buffer descriptors and packet data are written to the wrong offsets in packet memory, and no transfer completes correctly. Drop the F1 scaling and use 16-bit accesses throughout. Note that the sibling stm32_usbfs.h defines STM32_USB_BTABLE_RADDR() without the shift already, so this brings the M0 header in line with it. Assisted-by: GitHub Copilot:claude-opus-5 Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
The correct transfer loop in stm32_usb_interrupt() dispatched every completion to stm32_epdone(), including those for endpoint 0. stm32_epdone() implements the generic bulk/interrupt endpoint completion path. It does not decode the SETUP stage, does not maintain the EP0 state machine, and does not apply the EP0 specific RX/TX status rules. Control transfers therefore never completed correctly and the device could not be enumerated. Dispatch endpoint 0 to stm32_ep0done(), which is the control endpoint handler and is already used for the same purpose by the low priority transfer path in stm32_lptransfer(). Assisted-by: GitHub Copilot:claude-opus-5 Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
The initial interrupt mask enabled only reset, suspend and correct transfer. Error conditions reported by the controller, USB_ISTR_ERR and USB_ISTR_PMAOVRN, were neither enabled nor acknowledged. Because the status bits are never cleared, an error condition latched in USB_ISTR remains set and is re-evaluated on every subsequent interrupt, which makes the reported status misleading when debugging transfer problems. Add ERRM and PMAOVRN to the initial mask and clear the corresponding status bits when they are seen. Assisted-by: GitHub Copilot:claude-opus-5 Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
The code that claimed to "enable clocking to the USB peripheral" cleared RCC_APB1ENR_USBEN inside RCC_APB1RSTR. That is both the wrong register and the wrong bit: USBEN belongs to RCC_APB1ENR, while APB1RSTR holds RCC_APB1RSTR_USBRST. The peripheral clock is enabled by the RCC setup performed at boot, so the write had no useful effect and merely cleared an unrelated reset bit. Issue a proper reset pulse on RCC_APB1RSTR_USBRST instead, so the controller starts from a known state. On STM32L0 the D+/D- lines are connected to the USB transceiver automatically once the peripheral is enabled and there is no alternate function to select, so skip the GPIO configuration on that chip. The board GPIO_USB_DM/GPIO_USB_DP definitions do not exist there. Assisted-by: GitHub Copilot:claude-opus-5 Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
jsanchez-2g
requested review from
acassis,
jerpelea,
raiden00pl and
xiaoxiang781216
as code owners
August 20, 2026 01:09
xiaoxiang781216
approved these changes
Aug 20, 2026
jerpelea
approved these changes
Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix four defects in the shared STM32 M0 USB device driver:
memory, but the driver used STM32F1-style offset scaling and 32-bit
descriptor accesses.
instead of the generic endpoint handler.
The combined defects prevented correct control transfers and USB enumeration on
STM32 M0 USB device parts.
Impact
related M0 USB device implementations.
API and behavior; broken USB device paths become functional.
Testing
Build host:
Hardware:
Before:
devices when tested from pristine apache/master plus board support.
After:
Validation:
PR verification Self-Check