Skip to main content
Associate
August 27, 2026
Question

STM32MP257F-EV1: USB gadget (UVC) never attaches on CN15 — dwc3 stuck in device mode but DCTL.RUN_STOP never set despite correct Type-C/UCSI neg

  • August 27, 2026
  • 9 replies
  • 98 views

Board: STM32MP257F-EV1
Image: FLASH-stm32mp2-openstlinux-6.6-yocto-scarthgap-mpu-v26.06.10
Kernel: Linux 6.6.129
USB port: CN15 (USB_DRD, Type-C)

I'm trying to run a USB gadget (UVC, via configfs/libcomposite) on CN15, and
the UDC never attaches, even though every layer up to dwc3's pullup step
looks correct:

- Type-C/UCSI (M33 firmware USBPD_DRP_UCSI_CM33_NonSecure_stripped.elf,
  ucsi-stm32g0-i2c driver) correctly negotiates the port as UFP/device:
  /sys/class/typec/port0/data_role = host [device]
  /sys/class/typec/port0/power_role = source [sink]
  A partner is detected, and the UCSI power-supply object confirms VBUS at
  5V. This all live-updates correctly on physical cable unplug/replug.

- dwc3 correctly switches to device mode:
  /sys/kernel/debug/usb/48300000.usb/mode → "device"

- But the pullup never actually happens:
  /sys/class/udc/48300000.usb/state stays "not attached" indefinitely

Manually retrying via soft_connect just logs "UDC had already started" —
the UDC core believes the connect step already ran, but the hardware
register was never actually written.

I reproduced this identically across several devicetree configurations
(static role-switch-default-mode="peripheral" with the Type-C controller
disabled, dynamic UCSI-only, and both combined) — same result every time,
which rules out a devicetree/overlay misconfiguration on my end.

Questions:
1. Is there a known issue in the dwc3-stm32 glue driver (or the
   USBPD_DRP_UCSI_CM33 firmware's notification path) on kernel 6.6.129 /
   OpenSTLinux v26.06.10 preventing dwc3_gadget_pullup()/DCTL.RUN_STOP from
   being asserted after a successful Type-C role switch to device?
2. Is the M33 UCSI firmware required for USB2 peripheral-mode gadget
   operation on CN15, or should the static role-switch-default-mode path
   work standalone? 
3. Is there a newer OpenSTLinux release that addresses this?

 

9 replies

Erwan SZYMANSKI
ST Technical Moderator
August 27, 2026

Hello ​@Parikshit8829 ,
Do you have some details about the USB gadget you configured and how ? (Maybe you have a gadget config script you can share).

I am preparing a setup to reproduce on my side.

Kind regards,
Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Erwan SZYMANSKI
ST Technical Moderator
August 27, 2026

@Parikshit8829 ,
I just have flashed a Linux image based on OpenSTLinux 6.2.1 (same version as you have).

The gadget configuration seems to work as we have a default gadget configured in our distribution. This is the ETH over USB gadget. When you start the board and connect a laptop to USB DRD connector (CN15), you well see the usb0 ethernet interface created showing that the gadget is well configured.

Be careful, you need to be sure to remove this default gadget before trying to put your own one.

What you can do as a quick method is to rename the USB gadget script present on the board by default so that it will not be launched anymore:

Board $> mv /usr/sbin/stm32_usbotg_eth_config.sh /usr/sbin/stm32_usbotg_eth_config.sh.backup
Board $> reboot

 

Let me know if you can move forward after that.

Kind regards,
Erwan.

 

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Associate
August 27, 2026

Hello Erwan ,
Let me check , will get back to you soon ...

Associate
August 27, 2026

Hi Erwan ,
Below scriprt i have used for UVC configuration 

 

#!/bin/bash

# ============================================================
# STM32MP2 UVC Gadget
# OpenSTLinux 5.0.17 / Linux 6.6
#
# Creates gadget g1 from scratch.
#
# UVC:
#   MJPEG 640x480 @ 30/15 FPS
#   YUYV  640x480 @ 30/15 FPS
#
# UDC:
#   48300000.usb
# ============================================================

set -e

CONFIGFS="/sys/kernel/config"
G="$CONFIGFS/usb_gadget/g1"
UVC="$G/functions/uvc.usb0"
CFG="$G/configs/c.1"
UDC="48300000.usb"

echo "========================================"
echo " STM32MP2 UVC Gadget"
echo "========================================"

# ------------------------------------------------------------
# 1. Configfs
# ------------------------------------------------------------

echo "[1/10] Checking configfs..."

if ! mountpoint -q "$CONFIGFS"; then
    mount -t configfs none "$CONFIGFS"
fi

# ------------------------------------------------------------
# 2. Load modules
# ------------------------------------------------------------

echo "[2/10] Loading USB gadget modules..."

modprobe libcomposite
modprobe usb_f_uvc

if [ ! -d "$CONFIGFS/usb_gadget" ]; then
    echo "ERROR: usb_gadget configfs subsystem not available"
    exit 1
fi

# ------------------------------------------------------------
# 3. Check UDC
# ------------------------------------------------------------

echo "[3/10] Checking UDC..."

if [ ! -e "/sys/class/udc/$UDC" ]; then
    echo "ERROR: UDC $UDC not found"
    ls -l /sys/class/udc/
    exit 1
fi

echo "UDC: $UDC"

# ------------------------------------------------------------
# 4. Remove old g1 if present
# ------------------------------------------------------------

echo "[4/10] Cleaning existing g1..."

if [ -d "$G" ]; then

    CURRENT_UDC=$(cat "$G/UDC" 2>/dev/null || true)

    if [ -n "$CURRENT_UDC" ]; then
        echo "Unbinding $CURRENT_UDC..."
        echo "" > "$G/UDC"
        sleep 1
    fi

    # Remove configuration links first
    rm -f "$CFG/uvc.usb0" 2>/dev/null || true

    # Remove gadget only after it is unbound
    rmdir "$UVC" 2>/dev/null || true
    rmdir "$CFG/strings/0x409" 2>/dev/null || true
    rmdir "$CFG/strings" 2>/dev/null || true
    rmdir "$CFG" 2>/dev/null || true
    rmdir "$G/strings/0x409" 2>/dev/null || true
    rmdir "$G/strings" 2>/dev/null || true

    rmdir "$G" 2>/dev/null || true
fi

# ------------------------------------------------------------
# 5. Create gadget
# ------------------------------------------------------------

echo "[5/10] Creating gadget..."

mkdir -p "$G"
cd "$G"

echo 0x1d6b > idVendor
echo 0x0104 > idProduct
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB

# Strings
mkdir -p strings/0x409

echo "STM32 UVC Gadget" > strings/0x409/product
echo "1234567890" > strings/0x409/serialnumber
echo "STMicroelectronics" > strings/0x409/manufacturer

# Configuration
mkdir -p configs/c.1/strings/0x409

echo "UVC Config" \
    > configs/c.1/strings/0x409/configuration

# ------------------------------------------------------------
# 6. Create UVC function
# ------------------------------------------------------------

echo "[6/10] Creating UVC function..."

mkdir -p "$UVC"

# ============================================================
# CONTROL
# ============================================================

mkdir -p "$UVC/control/header/h"

cd "$UVC/control"

# FS
if [ -d class/fs ]; then
    ln -s header/h class/fs/h
fi

# SS
if [ -d class/ss ]; then
    ln -s header/h class/ss/h
fi

# ============================================================
# STREAMING
# ============================================================

mkdir -p "$UVC/streaming/header/h"

# ------------------------------------------------------------
# MJPEG
# ------------------------------------------------------------

echo "Creating MJPEG 640x480..."

mkdir -p "$UVC/streaming/mjpeg/m/f1"

echo 640 \
    > "$UVC/streaming/mjpeg/m/f1/wWidth"

echo 480 \
    > "$UVC/streaming/mjpeg/m/f1/wHeight"

echo 333333 \
    > "$UVC/streaming/mjpeg/m/f1/dwFrameInterval"

echo 666666 \
    >> "$UVC/streaming/mjpeg/m/f1/dwFrameInterval"

# ------------------------------------------------------------
# YUYV
# ------------------------------------------------------------

echo "Creating YUYV 640x480..."

mkdir -p "$UVC/streaming/uncompressed/u/f1"

echo 640 \
    > "$UVC/streaming/uncompressed/u/f1/wWidth"

echo 480 \
    > "$UVC/streaming/uncompressed/u/f1/wHeight"

echo 333333 \
    > "$UVC/streaming/uncompressed/u/f1/dwFrameInterval"

echo 666666 \
    >> "$UVC/streaming/uncompressed/u/f1/dwFrameInterval"

# ------------------------------------------------------------
# Streaming header links
# ------------------------------------------------------------

cd "$UVC/streaming/header/h"

ln -s ../../mjpeg/m m
ln -s ../../uncompressed/u u

# FS
cd ../../class/fs
ln -s ../../header/h h

# HS
cd ../hs
ln -s ../../header/h h

# SS
cd ../ss
ln -s ../../header/h h

# ------------------------------------------------------------
# 7. Link function to configuration
# ------------------------------------------------------------

echo "[7/10] Linking UVC function..."

cd "$CFG"

ln -s ../../functions/uvc.usb0 uvc.usb0

# ------------------------------------------------------------
# 8. Verify
# ------------------------------------------------------------

echo "[8/10] Verifying..."

echo
echo "CONTROL:"
ls -la "$UVC/control/header/h"
ls -la "$UVC/control/class/fs"
ls -la "$UVC/control/class/ss"

echo
echo "STREAMING HEADER:"
ls -la "$UVC/streaming/header/h"

echo
echo "STREAMING CLASS:"
ls -la "$UVC/streaming/class/fs"
ls -la "$UVC/streaming/class/hs"
ls -la "$UVC/streaming/class/ss"

echo
echo "CONFIGURATION:"
ls -la "$CFG"

# ------------------------------------------------------------
# 9. Bind
# ------------------------------------------------------------

echo
echo "[9/10] Binding gadget to $UDC..."

echo "$UDC" > "$G/UDC"

sleep 2

# ------------------------------------------------------------
# 10. Status
# ------------------------------------------------------------

echo
echo "[10/10] Status..."

echo
echo "========================================"
echo " UVC GADGET STARTED"
echo "========================================"

echo
echo "UDC:"
cat "$G/UDC"

echo
echo "UDC state:"
cat "/sys/class/udc/$UDC/state"

echo
echo "Gadget:"
ls -la "$G"

echo
echo "Done."

Erwan SZYMANSKI
ST Technical Moderator
August 27, 2026

Hello ​@Parikshit8829 ,
What about the output logs ? Do you have some error reported or anything ? 

Kind regards,
Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Associate
August 31, 2026

Hi Erwan ,

Below are our observations:
Type-C partner: port0 and port0-partner are both present.
Data role: host [device] — device role is correctly selected.
DWC3 mode: device.
UCSI/M33: remoteproc is running, and VBUS is confirmed at 5 V.

So, all the Type-C/UCSI and DWC3 role checks appear to be correct. However, the UDC still remains in the not attached state when we use the UVC gadget.

To narrow down the issue further, we tested two other gadgets on exactly the same setup:
Stock NCM/ETH gadget — attaches successfully; the host detects it through lsusb/dmesg.
Minimal CDC-ACM gadget — also attaches successfully.

The only significant difference we can identify is that UVC requires an isochronous streaming endpoint, whereas NCM and CDC-ACM do not.

We also tested a stripped-down UVC configuration with a single format and a single frame, but it still does not attach.

Could you please check whether there is any known issue with isochronous endpoint handling in the DWC3 / dwc3-stm32 driver on this SoC, particularly with the current OpenSTLinux/kernel version?
If possible, it would also be helpful to know whether there are any known patches, workarounds, or recommended kernel/OpenSTLinux versions for UVC gadget support on STM32MP2.

Please check below terminal output for your reference 
1) Stock NCM/eth gadget: attaches successfully: -

Host side:

parikshit@GJSHD-0519:~$ sudo dmesg | tail -10

[sudo] password for parikshit:

[21434.817448] cdc_ncm 1-9:1.0 enx60f0f4bb49da: unregister 'cdc_ncm' usb-0000:00:14.0-9, CDC NCM (NO ZLP)

[27920.163461] usb 1-9: new high-speed USB device number 13 using xhci_hcd

[27920.290262] usb 1-9: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00

[27920.290266] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3

[27920.290267] usb 1-9: Product: STM32MP

[27920.290268] usb 1-9: Manufacturer: STMicroelectronics

[27920.290268] usb 1-9: SerialNumber: 004800274236500700333258

[27920.311104] cdc_ncm 1-9:1.0: MAC-Address: 60:f0:f4:bb:49:da

[27920.311401] cdc_ncm 1-9:1.0 eth0: register 'cdc_ncm' at usb-0000:00:14.0-9, CDC NCM (NO ZLP), 60:f0:f4:bb:49:da

[27920.322307] cdc_ncm 1-9:1.0 enx60f0f4bb49da: renamed from eth0

parikshit@GJSHD-0519:~$ lsusb

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 001 Device 013: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget

Bus 001 Device 003: ID 046d:c077 Logitech, Inc. M105 Optical Mouse

Bus 001 Device 002: ID 046d:c31c Logitech, Inc. Keyboard K120

Bus 001 Device 009: ID 0483:3753 STMicroelectronics STLINK-V3

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

 

Board side:
root@stm32mp2-e3-e7-ee:~# /usr/sbin/stm32_usbotg_eth_config.sh start

Start usb gadget

root@stm32mp2-e3-e7-ee:~# dmesg | tail

[   15.579254] stm32-dwmac 482d0000.eth2 end0: IEEE 1588-2008 Advanced Timestamp supported

[   15.595982] stm32-dwmac 482d0000.eth2 end0: registered PTP clock

[   15.606847] stm32-dwmac 482d0000.eth2 end0: FPE workqueue start

[   15.607209] stm32-dwmac 482d0000.eth2 end0: configuring for phy/rgmii-id link mode

[   17.679357] stm32-dwmac 482d0000.eth2 end0: Link is Up - 100Mbps/Full - flow control rx/tx

[   24.042773] weston[1456]: memfd_create() called without MFD_EXEC or MFD_NOEXEC_SEAL set

[   32.141503] vddio3: disabling

[   32.141578] vddio4: disabling

[  109.001099] configfs-gadget.g1 gadget.0: HOST MAC 60:f0:f4:bb:49:da

[  109.001757] configfs-gadget.g1 gadget.0: MAC 86:0b:25:7d:2f:c3

root@stm32mp2-e3-e7-ee:~# cat /sys/kernel/debug/usb/48300000.usb/regdump | grep -iE 'dctl|dsts'

DCTL = 0x8cf00a00

DSTS = 0x008ad9e0

root@stm32mp2-e3-e7-ee:~#

 

2) Minimal CDC-ACM gadget: attaches successfully

 

Host side:

parikshit@GJSHD-0519:~$ sudo dmesg | tail -10

[27920.322307] cdc_ncm 1-9:1.0 enx60f0f4bb49da: renamed from eth0

[27979.619876] usb 1-9: USB disconnect, device number 13

[27979.620008] cdc_ncm 1-9:1.0 enx60f0f4bb49da: unregister 'cdc_ncm' usb-0000:00:14.0-9, CDC NCM (NO ZLP)

[27981.750396] usb 1-9: new high-speed USB device number 14 using xhci_hcd

[27981.878589] usb 1-9: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00

[27981.878593] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3

[27981.878595] usb 1-9: Product: STM32 ACM Test

[27981.878596] usb 1-9: Manufacturer: STMicroelectronics

[27981.878596] usb 1-9: SerialNumber: 1234567890

[27981.880867] cdc_acm 1-9:1.0: ttyACM2: USB ACM device

parikshit@GJSHD-0519:~$ lsusb

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 001 Device 014: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget

Bus 001 Device 003: ID 046d:c077 Logitech, Inc. M105 Optical Mouse

Bus 001 Device 002: ID 046d:c31c Logitech, Inc. Keyboard K120

Bus 001 Device 009: ID 0483:3753 STMicroelectronics STLINK-V3

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

 

 

Board side:
root@stm32mp2-e3-e7-ee:/sys/kernel/config/usb_gadget/g1# dmesg | tail

[   15.579254] stm32-dwmac 482d0000.eth2 end0: IEEE 1588-2008 Advanced Timestamp supported

[   15.595982] stm32-dwmac 482d0000.eth2 end0: registered PTP clock

[   15.606847] stm32-dwmac 482d0000.eth2 end0: FPE workqueue start

[   15.607209] stm32-dwmac 482d0000.eth2 end0: configuring for phy/rgmii-id link mode

[   17.679357] stm32-dwmac 482d0000.eth2 end0: Link is Up - 100Mbps/Full - flow control rx/tx

[   24.042773] weston[1456]: memfd_create() called without MFD_EXEC or MFD_NOEXEC_SEAL set

[   32.141503] vddio3: disabling

[   32.141578] vddio4: disabling

[  109.001099] configfs-gadget.g1 gadget.0: HOST MAC 60:f0:f4:bb:49:da

[  109.001757] configfs-gadget.g1 gadget.0: MAC 86:0b:25:7d:2f:c3

root@stm32mp2-e3-e7-ee:/sys/kernel/config/usb_gadget/g1# cat /sys/kernel/debug/usb/48300000.usb/regdump | grep -iE 'dctl|dsts'

DCTL = 0x8cf00a00

DSTS = 0x00033e78

3) UVC gadget (full config): does NOT attach

 

Board side:
root@stm32mp2-e3-e7-ee:~# /root/setup_uvc.sh

========================================

STM32MP2 UVC Gadget

========================================

[1/10] Checking configfs...

[2/10] Loading USB gadget modules...

[3/10] Checking UDC...

UDC: 48300000.usb

[4/10] Cleaning existing g1...

[5/10] Creating gadget...

[6/10] Creating UVC function...

Creating MJPEG 640x480...

Creating YUYV 640x480...

[7/10] Linking UVC function...

[8/10] Verifying...

 

CONTROL:

total 0

drwxr-xr-x 2 root root    0 Aug 27 12:10 .

drwxr-xr-x 3 root root    0 Aug 27 12:10 ..

-rw-rw-rw- 1 root root 4096 Aug 27 12:10 bcdUVC

-rw-rw-rw- 1 root root 4096 Aug 27 12:10 dwClockFrequency

total 0

drwxr-xr-x 2 root root 0 Aug 27 12:10 .

drwxr-xr-x 4 root root 0 Aug 27 12:10 ..

lrwxrwxrwx 1 root root 0 Aug 27 12:10 h -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/control/header/h

total 0

drwxr-xr-x 2 root root 0 Aug 27 12:10 .

drwxr-xr-x 4 root root 0 Aug 27 12:10 ..

lrwxrwxrwx 1 root root 0 Aug 27 12:10 h -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/control/header/h

 

STREAMING HEADER:

total 0

drwxr-xr-x 2 root root    0 Aug 27 12:10 .

drwxr-xr-x 3 root root    0 Aug 27 12:10 ..

-r--r--r-- 1 root root 4096 Aug 27 12:10 bStillCaptureMethod

-r--r--r-- 1 root root 4096 Aug 27 12:10 bTerminalLink

-r--r--r-- 1 root root 4096 Aug 27 12:10 bTriggerSupport

-r--r--r-- 1 root root 4096 Aug 27 12:10 bTriggerUsage

-r--r--r-- 1 root root 4096 Aug 27 12:10 bmInfo

lrwxrwxrwx 1 root root    0 Aug 27 12:10 m -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/streaming/mjpeg/m

lrwxrwxrwx 1 root root    0 Aug 27 12:10 u -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/streaming/uncompressed/u

 

STREAMING CLASS:

total 0

drwxr-xr-x 2 root root 0 Aug 27 12:10 .

drwxr-xr-x 5 root root 0 Aug 27 12:10 ..

lrwxrwxrwx 1 root root 0 Aug 27 12:10 h -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/streaming/header/h

total 0

drwxr-xr-x 2 root root 0 Aug 27 12:10 .

drwxr-xr-x 5 root root 0 Aug 27 12:10 ..

lrwxrwxrwx 1 root root 0 Aug 27 12:10 h -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/streaming/header/h

total 0

drwxr-xr-x 2 root root 0 Aug 27 12:10 .

drwxr-xr-x 5 root root 0 Aug 27 12:10 ..

lrwxrwxrwx 1 root root 0 Aug 27 12:10 h -> ../../../../../../../usb_gadget/g1/functions/uvc.usb0/streaming/header/h

 

CONFIGURATION:

total 0

drwxr-xr-x 3 root root    0 Aug 27 12:10 .

drwxr-xr-x 3 root root    0 Aug 27 12:10 ..

-rw-r--r-- 1 root root 4096 Aug 27 12:10 MaxPower

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bmAttributes

drwxr-xr-x 3 root root    0 Aug 27 12:10 strings

lrwxrwxrwx 1 root root    0 Aug 27 12:10 uvc.usb0 -> ../../../../usb_gadget/g1/functions/uvc.usb0

 

[9/10] Binding gadget to 48300000.usb...

DCTL/DSTS (ground truth):

DCTL = 0x0cf00a00

DSTS = 0x00d3a029

 

[10/10] Status...

 

========================================

UVC GADGET STARTED

========================================

 

UDC:

48300000.usb

 

UDC state:

configured

 

Gadget:

total 0

drwxr-xr-x 7 root root    0 Aug 27 12:10 .

drwxr-xr-x 3 root root    0 Aug 27 12:10 ..

-rw-r--r-- 1 root root 4096 Aug 27 12:10 UDC

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bDeviceClass

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bDeviceProtocol

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bDeviceSubClass

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bMaxPacketSize0

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bcdDevice

-rw-r--r-- 1 root root 4096 Aug 27 12:10 bcdUSB

drwxr-xr-x 3 root root    0 Aug 27 12:10 configs

drwxr-xr-x 3 root root    0 Aug 27 12:10 functions

-rw-r--r-- 1 root root 4096 Aug 27 12:10 idProduct

-rw-r--r-- 1 root root 4096 Aug 27 12:10 idVendor

-rw-r--r-- 1 root root 4096 Aug 27 12:10 max_speed

drwxr-xr-x 2 root root    0 Aug 27 12:10 os_desc

drwxr-xr-x 3 root root    0 Aug 27 12:10 strings

drwxr-xr-x 2 root root    0 Aug 27 12:10 webusb

 

Done.

root@stm32mp2-e3-e7-ee:~# dmesg | tail -3

[  109.001099] configfs-gadget.g1 gadget.0: HOST MAC 60:f0:f4:bb:49:da

[  109.001757] configfs-gadget.g1 gadget.0: MAC 86:0b:25:7d:2f:c3

[  375.780267] configfs-gadget.g1 gadget.0: uvc: uvc_function_bind()

root@stm32mp2-e3-e7-ee:~# cat /sys/kernel/debug/usb/48300000.usb/regdump | grep -iE 'dctl|dsts'

DCTL = 0x0cf00a00

DSTS = 0x00d3a029

root@stm32mp2-e3-e7-ee:~#

Host side:

parikshit@GJSHD-0519:~$ sudo dmesg | tail -10

[27979.619876] usb 1-9: USB disconnect, device number 13

[27979.620008] cdc_ncm 1-9:1.0 enx60f0f4bb49da: unregister 'cdc_ncm' usb-0000:00:14.0-9, CDC NCM (NO ZLP)

[27981.750396] usb 1-9: new high-speed USB device number 14 using xhci_hcd

[27981.878589] usb 1-9: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00

[27981.878593] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3

[27981.878595] usb 1-9: Product: STM32 ACM Test

[27981.878596] usb 1-9: Manufacturer: STMicroelectronics

[27981.878596] usb 1-9: SerialNumber: 1234567890

[27981.880867] cdc_acm 1-9:1.0: ttyACM2: USB ACM device

[28023.288712] usb 1-9: USB disconnect, device number 14

parikshit@GJSHD-0519:~$ lsusb

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 001 Device 003: ID 046d:c077 Logitech, Inc. M105 Optical Mouse

Bus 001 Device 002: ID 046d:c31c Logitech, Inc. Keyboard K120

Bus 001 Device 009: ID 0483:3753 STMicroelectronics STLINK-V3

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

parikshit@GJSHD-0519:~$

If possible could you please help me in this case ...


Thanks ,
Parikshit 

Erwan SZYMANSKI
ST Technical Moderator
August 31, 2026

Hello ​@Parikshit8829 ,
I just have realized that we have an example script for gadget configuration in UVC use case under /usr/sbin (you can find it in your filesystem too I guess).

stm32_usbotg_uvc_config.sh:

#!/bin/sh
#
# Copyright (c) 2024 STMicroelectronics.
# All rights reserved.
#
# This software is licensed under MIT License terms that can be found here:
#
# https://opensource.org/license/mit

# This script configures USB Gadget configfs to use USB OTG as a USB serial
# and USB UVC gadgets

configfs="/sys/kernel/config/usb_gadget"
g=g1
c=c.1
d="${configfs}/${g}"
func_uvc=uvc.0

VENDOR_ID="0x483"
PRODUCT_ID="0x5740"

create_frame() {
    # Example usage:
    # create_frame <function name> <width> <height> <format> <name>

    FUNCTION=$1
    WIDTH=$2
    HEIGHT=$3
    FORMAT=$4
    NAME=$5

    wdir=${d}/functions/$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p

    mkdir -p $wdir
    echo $WIDTH > $wdir/wWidth
    echo $HEIGHT > $wdir/wHeight
    # YUV422 format
    echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize
    # MJPEG format
    #echo $(( $WIDTH * $HEIGHT )) > $wdir/dwMaxVideoFrameBufferSize
    # dwFrameInterfal is in 100-ns units (fps = 1/(dwFrameInterval * 10000000))
    # The targetted FPS is a parameter. default is 30fps -> 333333
    echo $((10000000 / $FPS)) > $wdir/dwFrameInterval
}

do_start() {
    if [ ! -d ${configfs} ]; then
        modprobe libcomposite
        if [ ! -d ${configfs} ]; then
        exit 1
        fi
    fi

    if [ -d ${d} ]; then
        exit 0
    fi

    udc=$(ls -1 /sys/class/udc/)
    if [ -z $udc ]; then
        echo "No UDC driver registered"
        exit 1
    fi

    mkdir ${d}
    echo ${VENDOR_ID} > ${d}/idVendor
    echo ${PRODUCT_ID} > ${d}/idProduct

    # Both interface may not operate independently
    echo 0xEF > ${d}/bDeviceClass
    echo 0x02 > ${d}/bDeviceSubClass
    echo 0x01 > ${d}/bDeviceProtocol

    mkdir -p ${d}/strings/0x409
    tr -d '\0' < /proc/device-tree/serial-number > ${d}/strings/0x409/serialnumber
    echo "STMicroelectronics" > ${d}/strings/0x409/manufacturer
    echo "STM32MP" > ${d}/strings/0x409/product

    # Config
    mkdir -p ${d}/configs/${c}
    mkdir -p ${d}/configs/${c}/strings/0x409
    echo "CDC UVC" > ${d}/configs/${c}/strings/0x409/configuration

    # Create UVC function
    mkdir -p ${d}/functions/${func_uvc}
    # mjpeg 480p config (not working with gstreamer uvcsink => need to debug it)
    # The width and height are parameters of this script. Default is 640x480
    create_frame ${func_uvc} $FRAME_WIDTH $FRAME_HEIGHT mjpeg m
    # yuv420 480p config
    # The width and height are parameters of this script. Default is 640x480
    create_frame ${func_uvc} $FRAME_WIDTH $FRAME_HEIGHT uncompressed u
    mkdir -p ${d}/functions/${func_uvc}/streaming/header/h

    cd ${d}/functions/${func_uvc}/streaming/header/h
    ln -s ../../uncompressed/u
    ln -s ../../mjpeg/m
    cd ../../class/fs
    ln -s ../../header/h
    cd ../../class/hs
    ln -s ../../header/h
    cd ../../class/ss
    ln -s ../../header/h
    cd ../../../control
    mkdir header/h
    ln -s header/h class/fs
    ln -s header/h class/ss
    cd ../../../
    # Set the packet size: uvc gadget max size is 3k...
    echo 3072 > functions/${func_uvc}/streaming_maxpacket
    echo 2048 > functions/${func_uvc}/streaming_maxpacket
    echo 1024 > functions/${func_uvc}/streaming_maxpacket
    echo 1 > functions/${func_uvc}/streaming_interval
    ln -s ${d}/functions/${func_uvc} ${d}/configs/${c}

    # Bind USB Device Controller
    echo ${udc} > ${d}/UDC

    # user information
    echo "#########################################################"
    echo "# for sending data with this uvc gadget, use the tools"
    echo "# uvc-gadget"
    echo "#"
    echo "# send a mir via uvc gadget"
    echo "# $> uvc-gadget uvc.0"
    echo "# send the camera content (libcamera)"
    echo "# $> uvc-gadget -c 0 uvc.0"
    

}

do_stop() {
    streaming_dir=${d}/functions/${func_uvc}/streaming
    if [ ! -d "${streaming_dir}" ];
    then
        echo "Nothing to do"
        return
    fi

    echo "" > ${d}/UDC

    # Delete UVC gadget
    [ -L ${d}/configs/${c}/${func_uvc} ] && rm ${d}/configs/${c}/${func_uvc}
    [ -L ${d}/functions/${func_uvc}/control/class/fs/h ] && rm ${d}/functions/${func_uvc}/control/class/fs/h
    [ -L ${d}/functions/${func_uvc}/control/class/ss/h ] && rm ${d}/functions/${func_uvc}/control/class/ss/h
    [ -L ${d}/functions/${func_uvc}/streaming/class/fs/h ] && rm ${d}/functions/${func_uvc}/streaming/class/fs/h
    [ -L ${d}/functions/${func_uvc}/streaming/class/hs/h ] && rm  ${d}/functions/${func_uvc}/streaming/class/hs/h
    [ -L ${d}/functions/${func_uvc}/streaming/class/ss/h ] && rm  ${d}/functions/${func_uvc}/streaming/class/ss/h
    [ -L ${d}/functions/${func_uvc}/streaming/header/h/m ] && rm  ${d}/functions/${func_uvc}/streaming/header/h/m
    [ -d ${d}/functions/${func_uvc}/streaming/mjpeg/m ] && rmdir ${d}/functions/${func_uvc}/streaming/mjpeg/m/*/
    [ -d ${d}/functions/${func_uvc}/streaming/mjpeg/m ] && rmdir ${d}/functions/${func_uvc}/streaming/mjpeg/m
    [ -L ${d}/functions/${func_uvc}/streaming/header/h/u ] && rm  ${d}/functions/${func_uvc}/streaming/header/h/u
    [ -d ${d}/functions/${func_uvc}/streaming/uncompressed/u ] && rmdir ${d}/functions/${func_uvc}/streaming/uncompressed/u/*/
    [ -d ${d}/functions/${func_uvc}/streaming/uncompressed/u ] && rmdir ${d}/functions/${func_uvc}/streaming/uncompressed/u
    [ -d ${d}/functions/${func_uvc}/streaming/header/h ] && rmdir ${d}/functions/${func_uvc}/streaming/header/h
    [ -d ${d}/functions/${func_uvc}/control/header/h ] && rmdir ${d}/functions/${func_uvc}/control/header/h
    [ -d ${d}/functions/${func_uvc} ] && rmdir ${d}/functions/${func_uvc}

    [ -d ${d}/configs/${c}/strings/0x409 ] && rmdir ${d}/configs/${c}/strings/0x409
    [ -d ${d}/configs/${c} ] && rmdir ${d}/configs/${c}
    [ -d ${d}/strings/0x409/ ] && rmdir ${d}/strings/0x409/
    [ -d ${d} ] && rmdir ${d}
}

FRAME_WIDTH=${2:-320}  # Default width to 320 if not provided
FRAME_HEIGHT=${3:-240} # Default height to 240 if not provided
FPS=${4:-30}          # Default to 30 FPS if not provided

case $1 in
    start)
        echo "Start UVC gadget with $FRAME_WIDTH x $FRAME_HEIGHT resolution @$FPS fps"
        do_start
        ;;
    stop)
        echo "Stop UVC gadget"
        do_stop
        ;;
    restart)
        echo "Stop UVC gadget"
        do_stop
        sleep 1
        echo "Start UVC gadget with $FRAME_WIDTH x $FRAME_HEIGHT resolution @$FPS fps"
        do_start
        ;;
    *)
        echo "Usage: $0 <stop | start | restart> [fps]"
        ;;
esac

 

Could you please use it to make a test on your side ?

Kind regards,
Erwan.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Associate
August 31, 2026

Hi Erwan ,
Thanks for sharing ,will check and get back to you soon … !

 

Associate
August 31, 2026

Hi Erwan,

Thanks - we ran /usr/sbin/stm32_usbotg_uvc_config.sh exactly as provided (it was already present on our board), no modifications.

Result: it fails identically to our own gadget. UDC never attaches.

Board side: $ /usr/sbin/stm32_usbotg_uvc_config.sh start Start UVC gadget with 320 x 240 resolution @30 fps ...

$ cat /sys/kernel/debug/usb/48300000.usb/regdump | grep -iE 'dctl|dsts' DCTL = 0x00f00000 (bit31 RUN_STOP = 0, controller never started) DSTS = 0x00d38e64

Host side (Ubuntu): $ sudo dmesg | tail -10 (nothing - no new device, no error) $ lsusb (no device with idVendor 0x483/idProduct 0x5740, nothing new at all)

For comparison, on the exact same board/boot, both the stock NCM/eth gadget and a minimal hand-built CDC-ACM gadget attach successfully every time (DCTL.RUN_STOP=1, confirmed on host via lsusb/dmesg). Only UVC fails, including your reference script.

This rules out our gadget configuration as the cause - your own script hits the identical failure. At this point we're fairly confident this is a genuine issue in isochronous endpoint handling in dwc3/dwc3-stm32 on this board/kernel (Linux 6.6.129, OpenSTLinux v26.06.10), not anything fixable from userspace/configfs.

We also found a second, separate issue that may be relevant: pushing an actual video frame into the UVC gadget's local V4L2 output node (/dev/video7) fails with a SWIOTLB buffer allocation error in dmesg:

dwc3 48300000.usb: swiotlb buffer is full (sz: 524288 bytes), total 32768 (slots), used 0 (slots)

We confirmed this is independent of buffer size (an 80x60 test gadget still fails to attach with the same RUN_STOP=0, ruling out a size-dependent connection between the two), so it looks like two separate bugs rather than one.

 

Thanks,
Parikshit