Skip to content

Conversation

maribu
Copy link
Member

@maribu maribu commented Sep 14, 2025

Contribution description

The STM32F3 requires a dedicated digital signal to emulate a disconnect event by pulling D+ down via a 1.5 kOhm resistor. Some boards, such as the OLIMEXINO-STM32F3, do not directly connect a GPIO but place a transistor in between. Depending on the exact implementation, the logic level may end up being inverted compared to directly connecting a GPIO.

This adds a flag member to the stm32_usbdev_fs_config_t and a new flag to indicate inverted logic. In addition the members in the struct are sorted by alignment, as this is a foolproof algorithm to prevent wasting memory on unneeded padding.

Finally, the USB driver is adapted to honor the flag.

Testing procedure

No regressions on STM32 boards with the usbdev_fs USB peripheral (e.g. Nucleo-F303Ze, Bluepill with STM32F1, p-Nucleo-WB55).

We do not have a board upstream that has an inverted disconnect pin yet, but I pinky-promise I tested this with one downstream for which this fixed an issue of USB not re-enumerating on reboot.

Issues/PRs references

None

@maribu maribu added Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Sep 14, 2025
@github-actions github-actions bot added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: cpu Area: CPU/MCU ports labels Sep 14, 2025
@riot-ci
Copy link

riot-ci commented Sep 14, 2025

Murdock results

✔️ PASSED

3e6e965 cpu/stm32/usbdev_fs: allow inverted disconnect GPIO

Success Failures Total Runtime
10516 0 10516 09m:11s

Artifacts

@crasbe
Copy link
Contributor

crasbe commented Sep 15, 2025

We do not have a board upstream that has an inverted disconnect pin yet, but I pinky-promise I tested this with one downstream for which this fixed an issue of USB not re-enumerating on reboot.

Did you also test it with a board where the pin is not inverted? One of the upstream boards?

I think I have a board with USB peripheral somewhere to test this.

@maribu
Copy link
Member Author

maribu commented Sep 15, 2025

No, I "tested" this by "staring hard at the diff". But I'm having a Bluepill somewhere in reach, I'll give it a spin in a sec.

@maribu
Copy link
Member Author

maribu commented Sep 15, 2025

Tested just now:

Type '/exit' to exit.
help
2025-09-15 11:15:59,643 # in(): This is mhelp
2025-09-15 11:15:59,644 # shell: command not found: main():
> 
2025-09-15 11:16:00,504 # help
2025-09-15 11:16:00,505 # Command              Description
2025-09-15 11:16:00,505 # ---------------------------------------
2025-09-15 11:16:00,506 # pm                   interact with layered PM subsystem
2025-09-15 11:16:00,507 # ps                   Prints information about running threads.
2025-09-15 11:16:00,510 # rtc                  control RTC peripheral interface
2025-09-15 11:16:00,511 # saul                 interact with sensors and actuators using SAUL
2025-09-15 11:16:00,512 # version              Prints current RIOT_VERSION
2025-09-15 11:16:00,514 # reboot               Reboot the node
> reboot
2025-09-15 11:16:02,079 # reboot
2025-09-15 11:16:02,679 # Serial port disconnected, waiting to get reconnected...
2025-09-15 11:16:03,680 # Try to reconnect to /dev/ttyACM0 again...
2025-09-15 11:16:03,684 # Reconnected to serial port /dev/ttyACM0
help
2025-09-15 11:16:10,005 # : This is  emain(help
2025-09-15 11:16:10,006 # shell: command not found: main():
> 
2025-09-15 11:16:11,812 # help
2025-09-15 11:16:11,812 # Command              Description
2025-09-15 11:16:11,813 # ---------------------------------------
2025-09-15 11:16:11,814 # pm                   interact with layered PM subsystem
2025-09-15 11:16:11,815 # ps                   Prints information about running threads.
2025-09-15 11:16:11,817 # rtc                  control RTC peripheral interface
2025-09-15 11:16:11,819 # saul                 interact with sensors and actuators using SAUL
2025-09-15 11:16:11,820 # version              Prints current RIOT_VERSION
2025-09-15 11:16:11,821 # reboot               Reboot the node
[ 9952.018172] usb 1-1: new full-speed USB device number 13 using xhci_hcd
[ 9952.170525] usb 1-1: New USB device found, idVendor=1209, idProduct=7d00, bcdDevice= 1.00
[ 9952.170539] usb 1-1: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[ 9952.170546] usb 1-1: Product: bluepill-stm32f103c8
[ 9952.170551] usb 1-1: Manufacturer: RIOT-os.org
[ 9952.170556] usb 1-1: SerialNumber: 6B28815B8E2570ED
[ 9952.260484] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
[ 9952.260527] usbcore: registered new interface driver cdc_acm
[ 9952.260530] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[ 9966.425346] usb 1-1: USB disconnect, device number 13
[ 9966.666215] usb 1-1: new full-speed USB device number 14 using xhci_hcd
[ 9966.818565] usb 1-1: New USB device found, idVendor=1209, idProduct=7d00, bcdDevice= 1.00
[ 9966.818579] usb 1-1: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[ 9966.818586] usb 1-1: Product: bluepill-stm32f103c8
[ 9966.818591] usb 1-1: Manufacturer: RIOT-os.org
[ 9966.818596] usb 1-1: SerialNumber: 6B28815B8E2570ED
[ 9966.872578] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

So even re-enumeration after reboot (the important part) does still work.

Copy link
Contributor

@crasbe crasbe left a comment

Choose a reason for hiding this comment

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

I wonder if the file should rather be in the cpu_stm32_usbdev subgroup [3], because currently the entries are not added to that group and the cpu_stm32 page also does not show the content explicitly [1]. You have to nagivate to the file [2], which is not easy to find IMO.

[1] https://ci.riot-os.org/results/76a1ab86808d47e8ba3d70c69f14fcec/doc-preview/group__cpu__stm32.html
[2] https://ci.riot-os.org/results/76a1ab86808d47e8ba3d70c69f14fcec/doc-preview/cpu__usbdev_8h.html
[3] https://ci.riot-os.org/results/76a1ab86808d47e8ba3d70c69f14fcec/doc-preview/group__cpu__stm32__usbdev.html

#define USBDEV_CPU_DMA_REQUIREMENTS __attribute__((aligned(USBDEV_CPU_DMA_ALIGNMENT)))

/**
* @name Flags used in @ref stm32_usbdev_fs_config_t
Copy link
Contributor

Choose a reason for hiding this comment

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

@maribu maribu force-pushed the cpu/stm32/usbdev_fs/inverted-disconnect-pin branch from 2e0f128 to 3b8fef7 Compare September 15, 2025 14:33
@maribu
Copy link
Member Author

maribu commented Sep 15, 2025

Ah, we could do better having the different two flavors of the USB peripheral more prominently appear in the doc. I'll rework it here soonish

The STM32F3 requires a dedicated digital signal to emulate a disconnect
event by pulling D+ down via a 1.5 kOhm resistor. Some boards, such as
the OLIMEXINO-STM32F3, do not directly connect a GPIO but place a
transistor in between. Depending on the exact implementation, the logic
level may end up being inverted compared to directly connecting a
GPIO.

This adds a flag member to the `stm32_usbdev_fs_config_t` and a new flag
to indicate inverted logic. In addition the members in the struct are
sorted by alignment, as this is a foolproof algorithm to prevent wasting
memory on unneeded padding.

Finally, the USB driver is adapted to honor the flag.
@maribu maribu force-pushed the cpu/stm32/usbdev_fs/inverted-disconnect-pin branch from 3b8fef7 to 3e6e965 Compare September 15, 2025 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants