This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM62X: PROCESSOR-SDK-AM62X_dts

Part Number: PROCESSOR-SDK-AM62X
Other Parts Discussed in Thread: AM62A7

Tool/software:

Subject: Issue with USB Peripheral Mode on [Your Target Board] - UDC Driver Binding Failure

Hello,

I am experiencing an issue with the USB peripheral mode on my target board [Your Target Board Model]. The USB device is not being recognized, and I receive the following kernel errors:

[ 68.736750] udc driver binding ret:-19
[ 68.740569] udc 31000000.usb: failed to start g: -19

Here are the details of my current setup:

  • Device Tree Configuration:

&usbss0 {
status = "okay";
};

&usb0 {
dr_mode = "peripheral";
pinctrl-names = "default";
pinctrl-0 = <&main_usb0_pins_default>;
};

main_usb0_pins_default: main_usb0_pins_default {
pinctrl-single,pins = <
AM62AX_IOPAD(0x0254, PIN_INPUT, 0) /* (C20) USB0_DRVVBUS */
>;
};

I have verified the following:

  1. Device tree configuration appears to be correct.
  2. Kernel configuration includes the necessary options for USB gadget support.
  3. UDC driver modules (dwc3 and dwc3-gadget) are loaded.
  4. Hardware connections are properly made.

Despite these checks, the USB peripheral mode is not working, although it functions correctly in host mode.

Could you please provide guidance on resolving this issue? Are there any additional configurations or steps required to get the USB peripheral mode working correctly?

Thank you for your assistance.

Best regards,

Laxman

  • Hi Laxman,

    The Processor SDK Linux by default is already configured AM62x USB0 port in dual role mode which can work in peripheral mode. You don't need to modify anything in USB related in kernel defconfig and kernel device tree.

    The only thing you need to do it boot the board and load a USB gadget driver then connect the USB0 port to the USB host.

  • Hi Bin Liu,

    I am facing an issue with enabling USB0 in peripheral mode on my [target board name]. I have loaded all the USB-related modules, but my PC is not detecting the target board through USB. Here are the details:

    Kernel Version: linux-5.10.168

     Board: am62a7

    Device Tree Settings:

    &usbss0 {

    status = "okay";

    ti,vbus-divider;

    };

    &usb0 {

    dr_mode = "host";

    pinctrl-names = "default";

    pinctrl-0 = <&main_usb0_pins_default>;

    };

    main_usb0_pins_default: main_usb0_pins_default {
    pinctrl-single,pins = <
    AM62AX_IOPAD(0x0254, PIN_INPUT, 0) /* (C20) USB0_DRVVBUS */
    >;
    };

    Modules Loaded:

    # lsmod | grep usb
    usb_f_acm 16384 2
    u_serial 20480 1 usb_f_acm
    usb_f_fs 49152 3
    usb_f_rndis 32768 2
    u_ether 28672 1 usb_f_rndis
    libcomposite 61440 13 usb_f_rndis,g_serial,usb_f_fs,usb_f_acm
    usbcore 266240 3 xhci_hcd,ehci_hcd,xhci_plat_hcd
    udc_core 32768 7 usb_f_rndis,u_ether,u_serial,libcomposite,usb_f_fs,usb_f_acm,dwc3
    usb_common 16384 6 xhci_hcd,usbcore,libcomposite,xhci_plat_hcd,dwc3,udc_core

    Output of /sys/class/udc:

    # pwd
    /sys/class/udc
    # ls
    # (no output)

    # lsusb
    Bus 001 Device 001: ID 1d6b:0002
    Bus 002 Device 001: ID 1d6b:0003

    Steps Taken:

    1. Loaded all USB-related modules.
    2. Checked the device tree settings.

    Despite these steps, the PC is still not detecting the target board. There is no UDC listed under /sys/class/udc.

    Questions:

    1. Is there anything specific I need to change in the kernel or device tree to enable USB0 in peripheral mode?
    2. Are there additional configurations or modules I might be missing?
    3. How can I debug this issue further to identify why the UDC is not showing up?

    Any help or suggestions would be greatly appreciated.

    Thank you!

  • &usb0 {

    dr_mode = "host";

    Are you connecting USB0 to PC? If so your kernel dts sets USB0 in host mode, PC won't detect it.

    Is there anything specific I need to change in the kernel or device tree to enable USB0 in peripheral mode?

    As I said, the SDK by default configures USB0 in dual role mode, which supports USB as peripheral. You don't have to change any config.

    Are there additional configurations or modules I might be missing?

    Likely not, since your USB0 works in host mode. You just need to ensure the USB gadget driver, which you intend to use, is enabled.

    How can I debug this issue further to identify why the UDC is not showing up?

    As I said, your USB0 is not in device mode.

  • Hi Bin Lu,

    I have already loaded the g_serial gadget module but am unsure how to verify that USB0 is indeed operating in peripheral mode.

    # dmesg | grep g_serial
    [ 209.266630] udc-core: couldn't find an available UDC - added [g_serial] to list of pending drivers

    # lsusb
    Bus 001 Device 001: ID 1d6b:0002
    Bus 002 Device 001: ID 1d6b:0003

    # ifconfig usb0
    usb0: error fetching interface information: Device not found
    #

    Despite these steps, I am not certain if USB0 is correctly configured as a peripheral. Could you please provide guidance on:

    Additional steps or commands to verify USB0 is in peripheral mode?

    Thank you for your assistance.

    Best regards,

    Laxman

  • Inquiry about "failed to enable ep0out" Error with DWC3 USB Gadget

    Hello Bin Lu,

    I'm encountering an issue with the DWC3 USB controller. When attempting to use the g_mass_storage gadget or g_serial gadget, I consistently receive the following error in the kernel logs:

    [ 862.883326] dwc3 31000000.usb: failed to enable ep0out

    Details:

    1. Setup and Configuration:

      • I have configured the USB0 interface in peripheral mode in the device tree as follows
    • &usb0 {
    • dr_mode = "peripheral";
    • pinctrl-names = "default";
    • pinctrl-0 = <&main_usb0_pins_default>; };

    Module Loading:

    • When loading g_mass_storage with /dev/mmcblk1 as the file:

    [ 862.833565] registering udc driver.
    [ 862.837915] Mass Storage Function, version: 2009/09/11
    [ 862.843356] LUN: removable file: (no medium)
    [ 862.848062] LUN: file: /dev/mmcblk1
    [ 862.855067] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11
    [ 862.870380] g_mass_storage gadget: g_mass_storage ready
    [ 862.875930] udc driver binding ret:0
    [ 862.883326] dwc3 31000000.usb: failed to enable ep0out

    Similarly, g_serial gadget also encounters the ep0out error:

    [ 535.629467] registering udc driver.
    [ 535.634217] g_serial gadget: Gadget Serial v2.4
    [ 535.639068] g_serial gadget: g_serial ready
    [ 535.643436] udc driver binding ret:0
    [ 535.652452] dwc3 31000000.usb: failed to enable ep0out

    Further Information:

    • I have verified the device tree configuration (dts) and kernel configuration (config) for USB gadget support (CONFIG_USB_GADGET, CONFIG_USB_DWC3, etc.).
    • The gadget modules (g_mass_storage and g_serial) load successfully, but the ep0out endpoint fails to enable.\
    Memory updated

    Certainly! When asking for assistance on the TI forum regarding the failed to enable ep0out error with USB gadget configurations, it's important to provide clear and detailed information. Here's a suggested format for your inquiry:


    Title: Inquiry about "failed to enable ep0out" Error with DWC3 USB Gadget

    Body:

    Hello TI Forum,

    I am currently working on configuring USB gadgets on my [Your Board Model], and I'm encountering an issue with the DWC3 USB controller. When attempting to use the g_mass_storage gadget or g_serial gadget, I consistently receive the following error in the kernel logs:

    bash
    Copy code
    [ 862.883326] dwc3 31000000.usb: failed to enable ep0out

    Details:

    1. Setup and Configuration:

      • I have configured the USB0 interface in peripheral mode in the device tree as follows:
        arduino
        Copy code
        &usb0 { dr_mode = "peripheral"; pinctrl-names = "default"; pinctrl-0 = <&main_usb0_pins_default>; };
    2. Module Loading:

      • When loading g_mass_storage with /dev/mmcblk1 as the file:

        yaml
        Copy code
        [ 862.833565] registering udc driver. [ 862.837915] Mass Storage Function, version: 2009/09/11 [ 862.843356] LUN: removable file: (no medium) [ 862.848062] LUN: file: /dev/mmcblk1 [ 862.855067] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11 [ 862.870380] g_mass_storage gadget: g_mass_storage ready [ 862.875930] udc driver binding ret:0 [ 862.883326] dwc3 31000000.usb: failed to enable ep0out
      • Similarly, g_serial gadget also encounters the ep0out error:

        less
        Copy code
        [ 535.629467] registering udc driver. [ 535.634217] g_serial gadget: Gadget Serial v2.4 [ 535.639068] g_serial gadget: g_serial ready [ 535.643436] udc driver binding ret:0 [ 535.652452] dwc3 31000000.usb: failed to enable ep0out
    3. Further Information:

      • I have verified the device tree configuration (dts) and kernel configuration (config) for USB gadget support (CONFIG_USB_GADGET, CONFIG_USB_DWC3, etc.).
      • The gadget modules (g_mass_storage and g_serial) load successfully, but the ep0out endpoint fails to enable.

    Request:

    Could you please provide guidance on:

    • Possible causes for the failed to enable ep0out error with the DWC3 USB controller?
    • Any specific configurations or settings in the device tree or kernel that might affect the USB gadget operation?
    • Steps to diagnose and resolve this issue effectively?

    Your assistance in resolving this matter would be greatly appreciated.

    Thank you.

    Best regards,

    Laxman

  • Laxman,

    I feel that both of your latest posts have conflict messages, and the second post has a lot of noise, and improperly formatted. I am having a hard time to form a clear picture of the issue you have.

    Can you pleas edit both posts to describe the problem clearly?

  • Hi Bin Liu,

    I hope you're doing well.

    First, I want to apologize for any confusion caused by my previous messages. I realize they might not have been clear, and I appreciate your patience.

    I'm encountering an issue with the UDC binding while configuring USB gadget drivers using ConfigFS in the latest version. In the past, I managed to get UDC binding working with the older version by simply loading the g_ether module. However, with the new version and the ConfigFS interface, I'm seeing the following error in dmesg:


    [ 51.029853] registering udc driver.
    [ 51.155890] udc driver binding ret:-19
    [ 51.159889] udc 31000000.usb: failed to start g: -19
    Here's the ConfigFS script I'm using:

    Below script i'm using binding udc driver:


    #!/bin/sh

    # Check if script is running as root
    if [ "$(id -u)" -ne 0 ]; then
    echo "This script must be run as root"
    exit 1
    fi

    # Move USB IRQ to Core 3
    USB_IRQ=$(awk '/usb/ {print $1}' /proc/interrupts | sed 's/://g')
    if [ -n "$USB_IRQ" ]; then
    echo "Found USB IRQs: $USB_IRQ"
    for IRQ in $USB_IRQ; do
    IRQ_PATH="/proc/irq/$IRQ/smp_affinity"
    if [ -e "$IRQ_PATH" ]; then
    echo 8 > "$IRQ_PATH"
    echo "Set IRQ $IRQ affinity to Core 3"
    else
    echo "smp_affinity file not found for IRQ $IRQ at $IRQ_PATH"
    fi
    done
    else
    echo "No USB IRQs found"
    fi

    # Load necessary kernel modules
    modprobe libcomposite
    modprobe usb_f_rndis
    modprobe usb_f_fs
    modprobe usb_f_acm
    modprobe usbcore
    modprobe ehci_hcd
    modprobe xhci_hcd

    # Mount the configfs filesystem
    mount -t configfs none /sys/kernel/config

    # Create and configure the gadget
    cd /sys/kernel/config/usb_gadget/
    mkdir g && cd g

    # Set up USB gadget descriptors
    echo 0x099E > idVendor # Trimble
    echo 0x0004 > idProduct # Trimble USB Product ID
    echo 0x0100 > bcdDevice # v1.0.0
    echo 0x0200 > bcdUSB # USB 2.0

    echo 0xEF > bDeviceClass
    echo 0x02 > bDeviceSubClass
    echo 0x01 > bDeviceProtocol

    # Set up gadget strings
    mkdir -p strings/0x409
    echo "Trimble" > strings/0x409/manufacturer
    echo "Alloy" > strings/0x409/product

    # Create functions for serial, network, and MTP
    mkdir -p functions/acm.usb0 # serial
    mkdir -p functions/rndis.usb0 # network
    mkdir -p functions/ffs.mtp # mtp

    # Create configuration and link functions to it
    mkdir -p configs/c.1
    echo 250 > configs/c.1/MaxPower
    ln -s functions/rndis.usb0 configs/c.1/
    ln -s functions/acm.usb0 configs/c.1/
    ln -s functions/ffs.mtp configs/c.1

    # Set up FunctionFS for MTP and start the service
    mkdir /dev/ffs-mtp
    mount -t functionfs mtp /dev/ffs-mtp

    # Check if FFS mount was successful
    if [ $? -ne 0 ]; then
    echo "Failed to mount FunctionFS for MTP"
    exit 1
    fi

    # Start the umtprd service
    /usr/sbin/umtprd > /dev/null &
    if [ $? -ne 0 ]; then
    echo "Failed to start umtprd service"
    exit 1
    fi

    # OS descriptors
    echo 1 > os_desc/use
    echo 0xcd > os_desc/b_vendor_code
    echo MSFT100 > os_desc/qw_sign

    echo RNDIS > functions/rndis.usb0/os_desc/interface.rndis/compatible_id
    echo 5162001 > functions/rndis.usb0/os_desc/interface.rndis/sub_compatible_id

    ln -s configs/c.1 os_desc

    # Ensure all configurations are set before binding
    udevadm settle -t 5 || :

    # Bind the UDC driver
    ls /sys/class/udc/ > UDC
    if [ $? -ne 0 ]; then
    echo "Failed to bind UDC driver"
    exit 1
    fi

    echo "USB gadget setup complete"


    Despite following the steps, the UDC binding fails with the error code -19. Could you please help me understand what might be causing this issue and how I can resolve it?

    Thank you in advance for your assistance.

    Best regards,

    Laxman

  • Hi Laxman,

    Thanks for the new details. It is much cleaner!

    In the past, I managed to get UDC binding working with the older version by simply loading the g_ether module. However, with the new version and the ConfigFS interface, I'm seeing the following error in dmesg:

    Let's take one step back, in the new SDK version, instead of USB configfs, can you get g_ether module working in the same way as the old SDK version?

  • Hi Bin Liu,

    I am currently using kernel version 5.10.168. I have managed to get the g_ether module working as it did in the old SDK version. However, I am encountering issues with the new ConfigFS interface. Specifically, I see the following error in dmesg when attempting to bind the UDC:

    [ 62.292675] USB_ADD_FUNCTION:ret:-19

    [ 62.308068] udc 31000000.usb: failed to start g1: -19

    Would you have any insights on how to resolve this issue with ConfigFS

    Thanks,

    Laxman

  • Hi Laxman,

    Instead of your USB configfs script, can you please test with the script attached below to see if you can create the USB gadget with just a single functions - serial?

    #!/bin/bash
    # $1: -d - tear down
    
    #FUNCS=("mass_storage.usb0")
    #FUNCS=("hid.usb0")
    #FUNCS=("uvc.usb0")
    #FUNCS=("uac1.usb0")
    #FUNCS=("uac2.usb0")
    #FUNCS=("SourceSink.usb0")
    #FUNCS=("uvc.usb0" "hid.usb0")
    #FUNCS=("acm.usb0" "ncm.usb0" "acm.usb1")
    
    #FUNCS=("uac1.usb0" "hid.usb0")
    #FUNCS=("uac2.usb0" "hid.usb0")
    #FUNCS=("acm.usb0" "acm.usb1")
    #FUNCS=("ecm.usb0" "rndis.usb0")
    FUNCS=("acm.usb0")
    
    CFS=/sys/kernel/config/usb_gadget
    VID="0x1d6d"
    PID="0x0104"
    LANG="0x409"
    GNAME=g1
    
    RNDIS_DEV_ADDR="12:22:33:44:55:66"
    RNDIS_HOST_ADDR="12:22:33:44:55:65"
    ECM_DEV_ADDR="12:22:33:44:55:68"
    ECM_HOST_ADDR="12:22:33:44:55:67"
    
    hid_report="\\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0"
    
    
    
    init()
    {
    	zcat /proc/config.gz | grep 'CONFIGFS_FS=' > /dev/null || exit 1
    	lsmod | grep libcomposite > /dev/null || modprobe libcomposite || exit 2
    	mount | grep configfs > /devnull || 
    		mount -t configfs none $(dirname $CFS) || exit 3
    }
    
    create_gadget()
    {
    	[ ! -d ${CFS}/${GNAME} ] || exit 5
    	mkdir ${CFS}/${GNAME} && cd ${CFS}/${GNAME} || exit 6
    	echo "$VID" > idVendor
    	echo "$PID" > idProduct
    
    	mkdir strings/$LANG
    	echo "0123456789" > strings/$LANG/serialnumber
    	echo "Foo Inc" > strings/$LANG/manufacturer
    	echo "Bar gadget" > strings/$LANG/product
    }
    
    # configuraton naming: configs/<name>.<number>
    create_config()
    {
    	[ -d ${CFS}/${GNAME} ] && cd ${CFS}/${GNAME} || exit 5
    	mkdir configs/c.1
    	mkdir configs/c.1/strings/$LANG
    	echo "conf1" > configs/c.1/strings/$LANG/configuration
    }
    
    # $1 - function name
    # function naming: functions/<name>.<instance_name>
    create_func_single()
    {
    	local _func=$1
    
    	mkdir functions/${_func} || return
    	case $_func in
    	"mass_storage."*)
    		local _msc=/dev/shm/gmsc-${_func#*.}.file
    
     		[ -f $_msc ] || dd if=/dev/zero of=$_msc bs=1M count=32
    		echo $_msc > functions/${_func}/lun.0/file
    		;;
    	"hid."*)
    		echo 1 > functions/${_func}/protocol
    		echo 1 > functions/${_func}/subclass
    		echo 8 > functions/${_func}/report_length
    		echo -ne $hid_report > functions/${_func}/report_desc
    		;;
    	"uvc."*)
    		mkdir functions/${_func}/control/header/h
    		cd functions/${_func}/control
    		ln -s header/h class/fs
    		ln -s header/h class/ss
    		cd ${CFS}/${GNAME}
    
    		_w=640
    		_h=360
    		_fps=30
    
    		mkdir -p functions/${_func}/streaming/uncompressed/u/${_h}p
    		cd functions/${_func}/streaming/uncompressed/u/${_h}p
    		echo $_w > wWidth
    		echo $_h > wHeight
    		echo $((_h * _w * 2 * _fps)) > dwMaxBitRate
    		echo $((_h * _w * 2 * _fps)) > dwMinBitRate
    		echo $((_h * _w * 2)) > dwMaxVideoFrameBufferSize
    		echo 333333 > dwFrameInterval
    		echo 333333 > dwDefaultFrameInterval
    #666666
    #1000000
    #5000000
    		cd ${CFS}/${GNAME}
    		mkdir functions/${_func}/streaming/header/h
    		cd functions/${_func}/streaming/header/h
    		ln -s ../../uncompressed/u
    		cd ../../class/fs
    		ln -s ../../header/h
    		cd ../../class/hs
    		ln -s ../../header/h
    		cd ../../class/ss
    		ln -s ../../header/h
    		cd ${CFS}/g1
    
    		echo 1024 > functions/${_func}/streaming_maxpacket
    		;;
    	"rndis."*)
    #		echo $RNDIS_HOST_ADDR > functions/${_func}/host_addr
    #		echo $RNDIS_DEV_ADDR > functions/${_func}/dev_addr
    
    		# match MS built-in RNDIS driver
    		echo EF > functions/${_func}/class
    		echo 04 > functions/${_func}/subclass
    		echo 01 > functions/${_func}/protocol
    		;;
    	"ecm."*)
    #		echo $ECM_HOST_ADDR > functions/${_func}/host_addr
    #		echo $ECM_DEV_ADDR > functions/${_func}/dev_addr
    		;;
    	esac
    	ln -s functions/${_func} configs/c.1
    }
    
    activate()
    {
    	local _udc
    
    	_udc=$(ls /sys/class/udc/)
    	# TODO check $_udc
    #	case $port in
    #	"1") _udc=48890000.usb ;;
    #	"2") _udc=488d0000.usb;;
    #	esac
    	echo _ $_udc _
    	echo "$_udc" > UDC
    }
    
    teardown()
    {
    	# TODO: test hid & uvc
    	local _ent
    
    	[ -d ${CFS}/${GNAME} ] && cd ${CFS}/${GNAME} || exit 5
    	echo "" > UDC
    	for _ent in $(ls configs/c.1/); do
    		[[ "$_ent" != "MaxPower" ]] || continue
    		[[ "$_ent" != "bmAttributes" ]] || continue
    		[[ "$_ent" != "strings" ]] || continue
    		
    		rm -f configs/c.1/$_ent
    	done
    
    	for _ent in $(ls functions/); do
    		case $_ent in
    		"uvc."*)
    			rm -rf functions/$_ent/streaming 2>/dev/null
    			;;
    		esac
    
    		rm -rf functions/$_ent 2>/dev/null
    	done
    
    	rmdir configs/c.1/strings/$LANG
    	rmdir configs/c.1
    	rmdir strings/$LANG
    	cd .. && rmdir $GNAME
    	echo "toredown"
    }
    
    ### MAIN ###
    
    case "$1" in
    "-d") teardown; exit 0;;
    #"1") port=1;;
    #"2") port=2;;
    #*) echo "invalid param $1."; exit 1;;
    esac
    
    init
    create_gadget
    create_config
    for func in ${FUNCS[*]}; do
    	echo "creating $func ..."
    	create_func_single $func
    done
    activate
    echo created
    
    

  • Hi Bin Lu,

    I am writing to inform you that the USB gadget configuration script executed successfully. Below are the details of the execution and the current status of the USB gadget.

    creating acm.usb0 ...
    [ 56.079965] registering udc driver.
    [ 56.083542] configfs_composite bind funtion
    [ 56.091627] composite dev prepare ret:0
    [ 56.095893] Attempting to add function: acm
    [ 56.100854] USB_ADD_FUNCTION:ret:0
    [ 56.104575] Successfully added function: acm
    [ 56.114746] udc driver binding ret:0
    created

    # dmesg | grep -i usb
    [ 56.100854] USB_ADD_FUNCTION:ret:0

    # ls /sys/kernel/config/usb_gadget/g1/
    UDC bMaxPacketSize0 functions os_desc
    bDeviceClass bcdDevice idProduct strings
    bDeviceProtocol bcdUSB idVendor
    bDeviceSubClass configs max_speed

    # cat /sys/kernel/config/usb_gadget/g1/UDC
    31000000.usb
    #

    The above results indicate that the USB gadget was created successfully and the UDC is bound to the device 31000000.usb.

    Please let me know if further information or actions are required.

    Best regards,

    Laxman B

  • Okay, now if you connect the AM62x USB0 port to PC USB port, does the PC detect it as a serial port?

  • Yes, its showing COM17 Usb Serial Device

  • Okay, it means you don't have USB hardware or Linux problems on your board. The issue is likely in your USB configfs script.

    Please compare your script with mine, from the single serial function, gradually adding new feature/function, and debug to see where in your script causes the problem.