zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.82k stars 6.59k forks source link

Zephyr WebUSB example not working on STM32 NUCLEO-H7A3ZI-Q #78217

Closed FMC-Torsten closed 1 month ago

FMC-Torsten commented 1 month ago

Describe the bug

When running WebUSB example on a NUCLEO-H7A3ZI-Q development board, the USB device can't be recognize and fails with a USB device enumeration error.

I successfully followed the Zephyr getting started guide to install Zephyr on a Windows 10 machine.

I am able to build and flash basic examples, like samples\basic\blinky, with the expected outcome.

I am also able to build and flash samples\subsys\usb\testusb. When connecting to my Windows 10 machine, the USB device get's enumerated, though Windows is complaining about a missing driver.

However, when building samples\subsys\usb\webusb and connecting the board to a Windows machine, Windows complains with:

Unknown USB Device (Invalid Configuration Descriptor)

To Reproduce

Follow the Zephyr Getting Started Guide https://docs.zephyrproject.org/latest/develop/getting_started/index.html

Then, do the following

  1. cd %HOMEPATH%\zephyrproject\zephyr
  2. west build -p always -b nucleo_h7a3zi_q samples\subsys\usb\webusb
  3. west flash
  4. Connect Nucleo board USB FS connector (CN13) to Windows machine
  5. See error

Expected behavior

USB device should get enumerated and be ready to be controlled from https://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web as described here https://docs.zephyrproject.org/latest/samples/subsys/usb/webusb/README.html

Impact

This issue is currently a showstopper for my development project.

Logs and console output

Using Windows Kit USB Device Viewer, I see the following output:

\'\'\ [Port2] FailedEnumeration : Unknown USB Device (Invalid Configuration Descriptor)

Is Port User Connectable: yes Is Port Debug Capable: no Companion Port Number: 2 Companion Hub Symbolic Link Name: USB#VID_17EF&PID_A393#6&38eeef83&0&3#{f18a0e88-c30c-11d0-8815-00a0c906bed8} Protocols Supported: USB 1.1: yes USB 2.0: yes USB 3.0: no

   ---===>Device Information<===---

String Descriptor for index 2 not available while device is in low power state.

ConnectionStatus: FailedEnumeration Current Config Value: 0x00 -> Device Bus Speed: Full (is not SuperSpeed or higher capable) Device Address: 0x19 Open Pipes: 0 !ERROR: No open pipes!

      ===>Device Descriptor<===

bLength: 0x12 bDescriptorType: 0x01 bcdUSB: 0x0201 bDeviceClass: 0x00 !ERROR: Device enumeration failure \'\'\

Environment (please complete the following information):

Additional context

github-actions[bot] commented 1 month ago

Hi @FMC-Torsten! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

henrikbrixandersen commented 1 month ago

CC: @jfischer-no, @tmon-nordic

erwango commented 1 month ago

@FMC-Torsten Have you been able to check if the same issue happens on other STM32 (or other) targets?

FMC-Torsten commented 1 month ago

Unfortunately, I currently only have this one STM32 evalboard at hand...

Meanwhile, I was able to build some of the more advanced usb examples from zephyr, namely after

west build -p always -b nucleo_h7a3zi_q samples\subsys\usb\console west flash

my NUCLEO-H7A3ZI-Q correctly appears as a COMx device and I can connect via PuTTY and see the expected outcome.

Plus, I could set up a basic bare-metal application by deriving from TinyUSB's examples/device/webusb_serial which works from their https://example.tinyusb.org/webusb-serial/index.html

Knowing now that my board + Windows 10 machine can work together correctly via WebUSB and other Zephyr USB examples correctly work in my configuration, I suspect there is something wrong in the setup of the USB descriptors in the Zephyr webusb example.

Here is the respective USB Device Viewer output for the TinyUSB case:

\'\'\' [Port2] : USB Composite Device

Is Port User Connectable: yes Is Port Debug Capable: no Companion Port Number: 2 Companion Hub Symbolic Link Name: USB#VID_17EF&PID_A393#6&38eeef83&0&3#{f18a0e88-c30c-11d0-8815-00a0c906bed8} Protocols Supported: USB 1.1: yes USB 2.0: yes USB 3.0: no

Device Power State: PowerDeviceD0

   ---===>Device Information<===---

English product name: "TinyUSB Device"

ConnectionStatus:
Current Config Value: 0x01 -> Device Bus Speed: Full (is not SuperSpeed or higher capable) Device Address: 0x20 Open Pipes: 5

      ===>Device Descriptor<===

bLength: 0x12 bDescriptorType: 0x01 bcdUSB: 0x0210 bDeviceClass: 0xEF -> This is a Multi-interface Function Code Device bDeviceSubClass: 0x02 -> This is the Common Class Sub Class bDeviceProtocol: 0x01 -> This is the Interface Association Descriptor protocol bMaxPacketSize0: 0x40 = (64) Bytes idVendor: 0xCAFE = Vendor ID not listed with USB.org idProduct: 0x4011 bcdDevice: 0x0100 iManufacturer: 0x01 English (United States) "TinyUSB" iProduct: 0x02 English (United States) "TinyUSB Device" iSerialNumber: 0x03 English (United States) "0123456789ABCDEF" bNumConfigurations: 0x01

      ---===>Open Pipes<===---

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0008 = 0x08 bytes bInterval: 0x10

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x03 -> Direction: OUT - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x82 -> Direction: IN - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

   ---===>Full Configuration Descriptor<===---

      ===>Configuration Descriptor<===

bLength: 0x09 bDescriptorType: 0x02 wTotalLength: 0x0062 -> Validated bNumInterfaces: 0x03 bConfigurationValue: 0x01 iConfiguration: 0x00 bmAttributes: 0x80 -> Bus Powered MaxPower: 0x32 = 100 mA

      ===>IAD Descriptor<===

bLength: 0x08 bDescriptorType: 0x0B bFirstInterface: 0x00 bInterfaceCount: 0x02 bFunctionClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class bFunctionSubClass: 0x02 bFunctionProtocol: 0x00 iFunction: 0x00

      ===>Interface Descriptor<===

bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x00 bAlternateSetting: 0x00 bNumEndpoints: 0x01 bInterfaceClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class bInterfaceSubClass: 0x02 bInterfaceProtocol: 0x00 iInterface: 0x04 English (United States) "TinyUSB CDC" -> This is a Communications (CDC Control) USB Device Interface Class

      ===>Descriptor Hex Dump<===

bLength: 0x05 bDescriptorType: 0x24 05 24 00 20 01 -> This is a Communications (CDC Control) USB Device Interface Class

      ===>Descriptor Hex Dump<===

bLength: 0x05 bDescriptorType: 0x24 05 24 01 00 01 -> This is a Communications (CDC Control) USB Device Interface Class

      ===>Descriptor Hex Dump<===

bLength: 0x04 bDescriptorType: 0x24 04 24 02 06 -> This is a Communications (CDC Control) USB Device Interface Class

      ===>Descriptor Hex Dump<===

bLength: 0x05 bDescriptorType: 0x24 05 24 06 00 01

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0008 = 0x08 bytes bInterval: 0x10

      ===>Interface Descriptor<===

bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x01 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0x0A -> This is a CDC Data USB Device Interface Class bInterfaceSubClass: 0x00 bInterfaceProtocol: 0x00 iInterface: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x82 -> Direction: IN - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Interface Descriptor<===

bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x02 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0xFF -> Interface Class Unknown to USBView bInterfaceSubClass: 0x00 bInterfaceProtocol: 0x00 iInterface: 0x05 English (United States) "TinyUSB WebUSB"

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x03 -> Direction: OUT - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>Endpoint Descriptor<===

bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00

      ===>BOS Descriptor<===

bLength: 0x05 bDescriptorType: 0x0F wTotalLength: 0x0039 bNumDeviceCaps: 0x02

      ===>Platform Capability Descriptor<===

bLength: 0x18 bDescriptorType: 0x10 bDevCapabilityType: 0x05 bReserved: 0x00 Platform Capability UUID: 3408B638-09A9-47A0-8BFD-A0768815B665 00 01 01 01

      ===>Platform Capability Descriptor<===

bLength: 0x1C bDescriptorType: 0x10 bDevCapabilityType: 0x05 bReserved: 0x00 Platform Capability UUID: D8DD60DF-4589-4CC7-9CD2-659D9E648A9F 00 00 03 06 B2 00 02 00 \'\'\'

jfischer-no commented 1 month ago

@erwango Is it correct, usb_otg_hs, compatible = "st,stm32-otghs", phys = <&otghs_fs_phy>;?

https://github.com/zephyrproject-rtos/zephyr/blob/884a4e5a35f3aabd804f74b9e6f31a25eda5be7c/dts/arm/st/h7/stm32h7a3.dtsi#L35-L46

marwaiehm-st commented 1 month ago

Hi @jfischer-no The configuration of the USB OTG HS peripheral on an STM32H7A3 microcontroller is correct:

jfischer-no commented 1 month ago

Hi @jfischer-no The configuration of the USB OTG HS peripheral on an STM32H7A3 microcontroller is correct:

* The compatible string "**st,stm32-otghs**" matches the driver in the Zephyr source code that handles the USB OTG HS controller.

* The phys property correctly references the PHY node, and the **otghs_fs_phy** node is defined in the DTS files.

Then USB_DC_HAS_HS_SUPPORT should not be set for this device.

git grep USB_DC_HAS_HS_SUPPORT boards/ boards/st/nucleo_h7a3zi_q/Kconfig.defconfig:config USB_DC_HAS_HS_SUPPORT

I guess the workaround is to build the sample for this device with -DCONFIG_USB_DC_HAS_HS_SUPPORT=n.

FMC-Torsten commented 1 month ago

I added

CONFIG_USB_DC_HAS_HS_SUPPORT=n

to samples/subsys/usb/webusb/prj.conf and this works now!

Thanks so much, everyone!

marwaiehm-st commented 1 month ago

Hi @jfischer-no The configuration of the USB OTG HS peripheral on an STM32H7A3 microcontroller is correct:

* The compatible string "**st,stm32-otghs**" matches the driver in the Zephyr source code that handles the USB OTG HS controller.

* The phys property correctly references the PHY node, and the **otghs_fs_phy** node is defined in the DTS files.

Then USB_DC_HAS_HS_SUPPORT should not be set for this device.

git grep USB_DC_HAS_HS_SUPPORT boards/ boards/st/nucleo_h7a3zi_q/Kconfig.defconfig:config USB_DC_HAS_HS_SUPPORT

I guess the workaround is to build the sample for this device with -DCONFIG_USB_DC_HAS_HS_SUPPORT=n.

Its correct using Full-Speed can improve compatibility and stability on the WebUSB sample, but it means that on this device there is an issue related to High-Speed USB operation when using WebUSB sample. I test on the board nucleo_h753zi and didn't face the problem: Screenshot from 2024-09-12 14-14-10 Screenshot from 2024-09-12 14-13-37

FMC-Torsten commented 1 month ago

I think, the problem is in zephyr/boards/st/nucleo_h7a3zi_q/Kconfig.defconfig

\'\'\' # STM32H7A3ZI-Q Nucleo board configuration

# Copyright (c) 2021 Electrolance Solutions # SPDX-License-Identifier: Apache-2.0

if BOARD_NUCLEO_H7A3ZI_Q

config USB_DC_HAS_HS_SUPPORT default y depends on USB_DC_STM32

endif # BOARD_NUCLEO_H7A3ZI_Q

\'\'\'

which explicitly sets USB HS support, whereas in zephyr/boards/st/nucleo_h753zi/Kconfig.defconfig

it is not set.

according to nucleo-h7a3zi-q.pdf

both, Nucleo-H7A3ZI-Q and Nucleo-H753ZI only support USB OTG FS on Micro-AB connector.

marwaiehm-st commented 1 month ago

I think, the problem is in zephyr/boards/st/nucleo_h7a3zi_q/Kconfig.defconfig

''' # STM32H7A3ZI-Q Nucleo board configuration

Copyright (c) 2021 Electrolance Solutions # SPDX-License-Identifier: Apache-2.0

if BOARD_NUCLEO_H7A3ZI_Q

config USB_DC_HAS_HS_SUPPORT default y depends on USB_DC_STM32

endif # BOARD_NUCLEO_H7A3ZI_Q

'''

which explicitly sets USB HS support, whereas in zephyr/boards/st/nucleo_h753zi/Kconfig.defconfig

it is not set.

according to nucleo-h7a3zi-q.pdf

both, Nucleo-H7A3ZI-Q and Nucleo-H753ZI only support USB OTG FS on Micro-AB connector.

I enabled USB_DC_HAS_HS_SUPPORT before launching the test on the board nucleo_h753zi. I think the problem is reproduced only on the board NUCLEO_H7A3ZI_Q.

marwaiehm-st commented 1 month ago

It works on Nucleo H753ZI because it supports High-Speed USB OTG thanks to an integrated USB controller with built-in PHY. This allows high-speed USB communications without requiring additional components. But Nucleo H7A3ZI-Q only supports USB OTG Full-Speed (12 Mbps), to activate High-Speed mode we should use an external PHY (ULPI PHY).