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.

AM5728: USB 2.0 peripheral mode on AM5728

Part Number: AM5728

Hello, I am using USB1 port on AM5728. I would like connect USB1 to PC over USB 2.0 in peripheral mode. USB1 has been connected according to AM572x Sitara Processor Technical Reference Manual (Rev. K) "Figure 24-144. USB1 Controller Application: USB2.0 Device" with one exception VBUS is not connected.

I use Processor SDK Linux 06.00.00.07 with the modification of device tree:

&usb1 {
	dr_mode = "peripheral";
};

I inserted successfully kernel module g_serial:

modprove g_serial

When the PC is connected to Sitara, Linux kernel on PC returns error message:

[22120.452202] usb usb1-port9: attempt power cycle
[22121.095492] usb 1-9: new full-speed USB device number 118 using xhci_hcd
[22121.095644] usb 1-9: Device not responding to setup address.
[22121.302304] usb 1-9: Device not responding to setup address.
[22121.508802] usb 1-9: device not accepting address 118, error -71
[22121.632137] usb 1-9: new full-speed USB device number 119 using xhci_hcd
[22121.632257] usb 1-9: Device not responding to setup address.
[22121.838971] usb 1-9: Device not responding to setup address.
[22122.045488] usb 1-9: device not accepting address 119, error -71
[22122.045548] usb usb1-port9: unable to enumerate USB device

  • Hi Akel,

    Please run the following command on your board after run 'modprobe g_serial' and post its output.

    #!/bin/bash
    #
    # Util to check USB subsystem for Linux kernel 3.12+ on TI Sitara devices
    #
    # Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
    #
    #
    #  Redistribution and use in source and binary forms, with or without
    #  modification, are permitted provided that the following conditions
    #  are met:
    #
    #    Redistributions of source code must retain the above copyright
    #    notice, this list of conditions and the following disclaimer.
    #
    #    Redistributions in binary form must reproduce the above copyright
    #    notice, this list of conditions and the following disclaimer in the
    #    documentation and/or other materials provided with the
    #    distribution.
    #
    #    Neither the name of Texas Instruments Incorporated nor the names of
    #    its contributors may be used to endorse or promote products derived
    #    from this software without specific prior written permission.
    #
    #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    #  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    #  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    #  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    #  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    #  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    #  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    VERSION=0.2.9
    DTPATH=/sys/firmware/devicetree/base
    
    ### functions ###
    
    # $1 command to be checked
    check_command() {
        local _cmd=$1
    
        which $_cmd > /dev/null || {
            echo "Error: $_cmd command not found"
            exit 1
        }
    }
    
    # check if the kernel is supported
    # this tool only runs on v3.12+ kernel
    # return 0 - if kernel version >= 3.12
    #        1 - if kernel version < 3.12
    has_supported_kernel() {
    	local _ver
    	local _t
    
        check_command uname
        uname -a
    	_ver=`uname -r`
        _t=${_ver%%.*}
        # 2.x.x, unsupported
        [ $_t -ge 3 ] || return 1
        # 4.x.x, supported
        [ $_t -lt 4 ] || return 0
    
        _ver=${_ver#*.}
        _t=${_ver%%.*}
        # < 3.12.x, unsupported
        [ $_t -ge 12 ] || return 1
        return 0
    }
    
    # check if the platform is supported
    #    $PLATFORM - global variable
    # return 0 - if platform is supported
    #        1 - if platform is not supported
    check_platform () {
    	local _hw
    
        check_command grep
        [ "$PLATFORM" != "" ] || {
    	    _hw=`cat ${DTPATH}/compatible | tr '\0' ' '`
    	    DBG_PRINT $_hw
    
            if [[ "$_hw" == *"ti,am33xx"* ]]; then
                PLATFORM="am335x"
            elif [[ "$_hw" == *"ti,am43"* ]]; then
                PLATFORM="am437x"
            elif [[ "$_hw" == *"ti,dra7"* ]]; then
                PLATFORM="am57x"
            elif [[ "$_hw" == *"ti,k2g"* ]]; then
                PLATFORM="keystone"
            elif [[ "$_hw" == *"ti,am654"* ]]; then
                PLATFORM="am65x"
            else
                PLATFORM=$_hw
            fi
        }
    
        DBG_PRINT $PLATFORM
        case $PLATFORM in
            "am335x")
                USB0="$(find $DTPATH -name 'usb@47401000')"
                USB1="$(find $DTPATH -name 'usb@47401800')"
                return 0;;
            "am437x")
                USB0="$(find $DTPATH -name 'usb@48390000')"
                USB1="$(find $DTPATH -name 'usb@483d0000')"
                return 0;;
            "am57x" | "keystone")
                USB0="$(find $DTPATH -name 'usb@48890000')"
                USB1="$(find $DTPATH -name 'usb@488d0000')"
                return 0;;
            "am65x")
                USB0="$(find $DTPATH -name 'dwc3@4000000')/usb@10000"
                USB1="$(find $DTPATH -name 'dwc3@4020000')/usb@10000"
                return 0;;
            *)
                echo "Unsupported \"$PLATFORM\""
                return 1;;
        esac
    }
    
    # check a kernel CONFIG option
    # params $1 - the config option
    #        $2 = '-q', quiet output
    # return 0 - undefined
    #        1 - defined as 'm', kernel module
    #        2 - defined as 'y', kernel builtin
    check_kernel_config() {
        local _cfg
    
        [ -n "$1" ] || return 0
        check_command zcat
        _cfg=`zcat /proc/config.gz | grep "^$1\>"`
    
        case ${_cfg#*=} in
            "y") return 2;;
            "m") return 1;;
              *) [ "$2" = "-q" ] ||
                  echo "Error: $1 is undefined in kernel config"
              return 0;;
        esac
    }
    
    # check a kernel module
    # $1 - module name, relative path from drivers/, without .ko surfix
    # return 0 - found
    #        1 - error
    check_module() {
        local _modname
        local _moddep
    
        [ -n "$1" ] || return 1
    
        _modname="/lib/modules/`uname -r`/kernel/drivers/${1}.ko"
        _moddep="/lib/modules/`uname -r`/modules.dep"
    
        DBG_PRINT 1
        [ -f $_modname ] || {
            echo "Error: $_modname not found."
            echo "       Please ensure 'make module_install' is done properly."
            return 1
        }
    
        DBG_PRINT 2
        [ -f $_moddep ] || $moddep_checked || {
            echo "Error: $_moddep not found."
            echo "       Please ensure 'make module_install' is done properly."
            moddep_checked=true
        }
    
        DBG_PRINT 3
        check_command lsmod
        check_command basename
        check_command tr
    
        lsmod | grep `basename $1 | tr '-' '_'` > /dev/null || {
            DBG_PRINT ">>>> ${1}.ko:"
            if grep "${1}.ko:" $_moddep > /dev/null; then
                DBG_PRINT 5
                echo "Error: $_moddep seems to be valid,"
                echo "       but `basename $1`.ko is not loaded."
                echo "       Please provide /proc/config.gz and /lib/module/`uname -r`/*"
                echo "       for further investigation."
            else
                DBG_PRINT 6
                echo "Error: `basename $1`: $_moddep is invalid."
                echo "       Please run command 'depmod' on the target to re-generate it,"
                echo "       then reboot the target. If the issue still exists, please"
                echo "       ensure 'make module_install' is done properly."
            fi
    
            DBG_PRINT 7
            return 1
        }
        DBG_PRINT 8
        return 0
    }
    
    # check kernel config, and modules (if CONFIG_*=M) for musb
    check_musb_drivers() {
        check_kernel_config CONFIG_USB_MUSB_HDRC
        [ $? != 1 ] || check_module 'usb/musb/musb_hdrc'
    
        check_kernel_config CONFIG_USB_MUSB_DUAL_ROLE -q
        [ $? != 0 ] || echo "Warning: CONFIG_USB_MUSB_DUAL_ROLE undefined."
    
        check_kernel_config CONFIG_USB_OTG -q
        [ $? == 0 ] || echo "Warning: CONFIG_USB_OTG defined."
    
        check_kernel_config CONFIG_USB_MUSB_DSPS
        [ $? != 1 ] || {
            check_module 'usb/musb/musb_dsps'
            check_module 'usb/musb/musb_am335x'
        }
    
        check_kernel_config CONFIG_AM335X_PHY_USB
        [ $? != 1 ] || {
            check_module 'usb/phy/phy-am335x'
            check_module 'usb/phy/phy-am335x-control'
        }
    
        check_kernel_config CONFIG_MUSB_PIO_ONLY -q
        [ $? != 0 ] || {
           if check_kernel_config CONFIG_TI_CPPI41 -q; then
               echo "Error: MUSB CPPI DMA mode is enabled, but CPPI moudle is not enabled in DMA Engine."
               echo "       Please enable CONFIG_TI_CPPI41 under DMA Engine Support in kernel config."
           fi
        }
    }
    
    # check kernel config, and modules (if CONFIG_*=M) for dwc3
    check_dwc3_drivers() {
        check_kernel_config CONFIG_USB_DWC3
        [ $? != 1 ] || check_module 'usb/dwc3/dwc3'
    
        check_kernel_config CONFIG_USB_DWC3_DUAL_ROLE -q
        [ $? != 0 ] || echo "Warning: CONFIG_USB_DWC3_DUAL_ROLE undefined."
    
        check_kernel_config CONFIG_USB_OTG -q
        [ $? == 0 ] || echo "Warning: CONFIG_USB_OTG defined."
    
        check_kernel_config CONFIG_USB_DWC3_OMAP
        [ $? != 1 ] || check_module 'usb/dwc3/dwc3-omap'
    
        check_kernel_config CONFIG_USB_XHCI_HCD
        [ $? != 1 ] || {
            check_module 'usb/host/xhci-plat-hcd'
            check_module 'usb/host/xhci-hcd'
        }
    
        check_kernel_config CONFIG_OMAP_CONTROL_PHY
        [ $? != 1 ] || check_module 'phy/phy-omap-control'
    
        if [ $PLATFORM = am437x ]; then
            check_kernel_config CONFIG_OMAP_USB2
            [ $? != 1 ] || check_module 'phy/phy-omap-usb2'
        else
            check_kernel_config CONFIG_TI_PIPE3
            [ $? != 1 ] || check_module 'phy/phy-ti-pipe3'
        fi
    }
    
    check_musb_dt() {
        local _dt_dir
        local _ent
        local _sts
    
        _dt_dir='/proc/device-tree/ocp/usb@47400000'
        _ent='. control@44e10620 usb-phy@47401300 usb-phy@47401b00 dma-controller@47402000'
    
        for _t in $_ent; do
            _sts=$(tr -d '\0' <${_dt_dir}/${_t}/status)
            [ "$_sts" != "disabled" ] || echo $_t: disabled in devicetree
        done
    }
    
    ### debug ###
    
    g_log_file=/tmp/chkusb.log
    
    DBG_ENABLE() { g_dbg_enabled=true; }
    DBG_DISABLE() { g_dbg_enabled=false; }
    DBG_LOG_RESET() { ! $g_dbg_enabled || echo > $g_log_file; }
    DBG_PRINT() { ! $g_dbg_enabled || echo "$(date +%H:%M:%S) [$(basename $0)]: $*"; }
    DBG_LOG() { DBG_PRINT $* >> $g_log_file; }
    DBG_LOG_MARK() { DBG_PRINT "----------------" >> $g_log_file; }
    
    
    ### main ####
    
    moddep_checked=false
    
    echo "chkusb.sh Version $VERSION"
    
    [ "$V" = "1" ] && DBG_ENABLE && DBG_LOG_RESET || DBG_DISABLE
    
    has_supported_kernel ||
        { echo "Unsupported kernel version: `uname -r`"; exit 1; }
    check_platform || exit 2
    DBG_PRINT device: $PLATFORM
    
    check_command lsusb
    if lsusb > /dev/null 2>&1; then
        echo "USB is initialized"
    else
        echo "USB initialization failed"
    fi
    
    # check kernel configs
    
    if [ -f /proc/config.gz ]; then
        case $PLATFORM in
            am335x) check_musb_drivers;;
            am437x | am57x | keystone | am65x) check_dwc3_drivers;;
            *)
                echo "Error: unsupported platform $PLATFORM"
                exit 5;;
        esac
    else
        echo "Error: /proc/config.gz not found"
    fi
    
    case $PLATFORM in
        am335x)
            _debugfs=`sed -ne 's/^debugfs \(.*\) debugfs.*/\1/p' /proc/mounts`
            [ -z "$_debugfs" ] ||
                grep -i 'power\|devctl\|testmode' ${_debugfs}/musb-hdrc.?/regdump
            ;;
    esac
    
    # check dr_mode & gadget drivers
    
    [ -d ${DTPATH} ] || {
        echo "Warning: ${DTPATH} not found"
        if [ -d "/lib/modules/`uname -r`/" ]; then
            echo "The list of USB gadget drivers installed:"
            ls -1Rp "/lib/modules/`uname -r`/kernel/drivers/usb/gadget/"
        fi
        exit 0
    }
    
    check_command basename
    for _usb_dir in "${USB0}" "${USB1}"; do
        [ -n "$_usb_dir" ] || continue
    
        [ ! -d "$_usb_dir/status" ] &&
            _status='(null)' || _status=`tr -d '\0' <$_usb_dir/status`
        _dr_mode=`tr -d '\0'  <$_usb_dir/dr_mode`
        echo `basename $_usb_dir`: $_dr_mode, $_status
    
        [ "$_status" = "disabled" -o "$_dr_mode" = "host" ] || gadget_mode=true
    done
    
    case $PLATFORM in
        am335x) check_musb_dt;;
        *) ;;
    esac
    
    DBG_PRINT $gadget_mode
    $gadget_mode || exit 0
    
    echo
    
    check_kernel_config CONFIG_USB_LIBCOMPOSITE
    case $? in
        0) echo "Error: no any gadget driver enabled"
           exit 6;;
        1) is_gadget_builtin=false;;
        2) echo "The gadget driver is built-in"
           is_gadget_builtin=true;;
    esac
    
    check_kernel_config CONFIG_USB_ZERO -q ||
        echo "Gadget Kernel Config: g_zero is enabled"
    check_kernel_config CONFIG_USB_AUDIO -q ||
        echo "Gadget Kernel Config: g_audio is enabled"
    check_kernel_config CONFIG_USB_ETH -q ||
        echo "Gadget Kernel Config: g_ether is enabled"
    check_kernel_config CONFIG_USB_G_NCM -q ||
        echo "Gadget Kernel Config: g_ncm is enabled"
    check_kernel_config CONFIG_USB_MASS_STORAGE -q ||
        echo "Gadget Kernel Config: g_mass_storage is enabled"
    check_kernel_config CONFIG_USB_G_SERIAL -q ||
        echo "Gadget Kernel Config: g_serial is enabled"
    check_kernel_config CONFIG_USB_G_PRINTER -q ||
        echo "Gadget Kernel Config: g_printer is enabled"
    
    g_driver=`grep '^DRIVER=' /sys/class/udc/*/uevent 2>/dev/null`
    echo "gadget driver loaded: ${g_driver:-(none)}"
    
    echo
    
    if ! $is_gadget_builtin; then
        if [ -d "/lib/modules/`uname -r`/" ]; then
            echo "The list of USB gadget drivers installed:"
            ls -1Rp "/lib/modules/`uname -r`/kernel/drivers/usb/gadget/"
        else
            echo "Error: /lib/modules/`uname -r`/ not found"
            echo "       Please ensure 'make modules_install' is done properly."
            exit 7
        fi
    fi
    
    # vim: ft=sh:ts=4:sw=4:et
    

    Please share the USB section of your board schematics.

  • Thank you for your quick response. This is output of script:

    chkusb.sh Version 0.2.9 
    Linux buildroot 4.19.38 #1 SMP Fri Sep 6 14:21:47 CEST 2019 armv7l GNU/Linux 
    USB is initialized 
    usb@48890000: peripheral, (null) 
    usb@488d0000: peripheral, (null) 
    
    Gadget Kernel Config: g_zero is enabled 
    Gadget Kernel Config: g_serial is enabled 
    gadget driver loaded: /sys/class/udc/48890000.usb/uevent:DRIVER=g_serial 
    
    The list of USB gadget drivers installed: 
    /lib/modules/4.19.38/kernel/drivers/usb/gadget/: 
    function/ 
    legacy/ 
    libcomposite.ko 
    udc/ 
    
    /lib/modules/4.19.38/kernel/drivers/usb/gadget/function: 
    u_audio.ko 
    u_ether.ko 
    u_serial.ko 
    usb_f_acm.ko 
    usb_f_ecm.ko 
    usb_f_ecm_subset.ko 
    usb_f_eem.ko 
    usb_f_fs.ko 
    usb_f_hid.ko 
    usb_f_mass_storage.ko 
    usb_f_midi.ko 
    usb_f_ncm.ko 
    usb_f_obex.ko 
    usb_f_phonet.ko 
    usb_f_rndis.ko 
    usb_f_serial.ko 
    usb_f_ss_lb.ko 
    usb_f_uac1.ko 
    usb_f_uac2.ko 
    
    /lib/modules/4.19.38/kernel/drivers/usb/gadget/legacy: 
    g_nokia.ko 
    g_serial.ko 
    g_zero.ko 
    
    /lib/modules/4.19.38/kernel/drivers/usb/gadget/udc: 
    udc-core.ko

    I am using connector dedicated for host USB3.0 with USB 3.0 A/A connecting cable.

  • Akel,

    There seems to be a hw design issue. The schematic shows P1 USBVBUS on the connector is not connected to anywhere. It should go to a AM5728 GPIO through a fail-safe logic. Please refer to the AM57x GP EVM USB2 port design.