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.

OTG Host mode with AM3352

Other Parts Discussed in Thread: AM3352

Hello,

Issue with host mode on USB OTG controller

I am running Linux on a AM3352 and the USB controller is supposed to be a OTG. However, I only have the USB running as peripheral so far.

I followed the kernel configuration on the "AM335X USB Driver User Guide".

However checking the files "/proc/driver/musb_hdrc.X" does not seem to be promising

 

# cat /proc/driver/musb_hdrc.0
Status: MHDRC, Mode=Peripheral (Power=e0, DevCtl=80)
OTG state: b_idle; inactive

Options: ?dma?, otg (peripheral+host), [eps=16]

...

# cat /proc/driver/musb_hdrc.1
Status: MHDRC, Mode=Peripheral (Power=60, DevCtl=5d)
OTG state: a_idle; inactive
Options: ?dma?, otg (peripheral+host), [eps=16]

...

Since the "state" changes (it did switch to UNDEFINED or "b_idle" but never shows "b_host" or so), I guess that the "mode" should show something like "OTG".

Plugging in a thumb drive does not show show up in the message buffer at all. We are using a special USB Mini-B cable for OTG and I checked that pins 4 and 5 are short-circuited.

While writing this post, I've just found out that there is a "mode" setting in quite a few source files which probably should be set to MUSB_OTG in our case.

Unfortunately I am not yet sure about which files are relevant for our hardware environment, but I've seen that some do have "MUSB_PERIPHERAL" set. I will update the post as soon as I know more.

In case the source files are correct - could it also be a hardware issue that causes  the mode is displayed as "peripheral"?

OTG and switching between host/peripheral

In this thread (well the hyperlink here gets transformed to a picture tha I can't remove anymore...) I have seen there seems to be a difference between running the USB controller as "OTG" and as "switching between peripheral/host".

Could you please tell me the difference? For me that was the same so far...OTG is supposed to switch between states "peripheral" and "host".

Thanks four your help in advance!

  • Stephan,

    Please clarify the following questions to help me understand the issue.

    - Which SDK version do you use? SDK6?

    - Which USB port has the issue, USB0, or USB1, or both? In SDK6, USB0 by default is in OTG mode, but USB1 is in host-only mode.

    - Please post the USB portion of your schematics.

    - Please don't forget you have to load a gadget driver for the OTG port to be functional.

  • Hi,

    I try to provide the information as good as I can, however I just got dropped into this task very recently and might not be able to provide everything yet.

    1. Environment

    I did not find any information on an SDK. What I received is a build environment with a linux kernel and build scripts.

    The kernel name/version is "linux-3.2.0-psp04.06.00.11" - some options on OTG that I found during research may not be available anymore with kernel 3.2 .

    E.g. "CONFIG_USB_MUSB_OTG" is an option listed in some tutorials but is only available in "2.6.27–2.6.39, 3.0" according to cateee.net Linux driver database.



    2. USB port



    Our controller only has one physical USB port attached, and, well, two "virtual" USB controllers, I guess, and I can find the directories

    /sys/devices/platform/omap/musb-ti81xx/musb-hdrc.0/

    /sys/devices/platform/omap/musb-ti81xx/musb-hdrc.1/

    and the files

    /proc/driver/musb_hdrc.0

    /proc/driver/musb_hdrc.1



    Schematics

    I don't have direct contact to the hardware supplier but I'm working on getting the USB wiring schematics.

    Gadget driver

    The gadget module g_ether is loaded at boot, and it's running perfectly fine (network via USB). Only the OTG host mode is not working

    DMESG

    I put some „dmesg | grep -i usb“ output on pastebin:

    http://pastebin.com/0vMbC4qG

    I think that's important to debug the issue since it shows the startup of USB drivers etc.



    Attaching a „normal“ USB Mini B cable to the controller (connected to a PC) sets up a network interface "usb0" and changes the state to "peripheral" in those files:

    /proc/driver/musb_hdrc.0

    /sys/devices/platform/omap/musb-ti81xx/musb-hdrc.0/mode

    Attaching a Mini B OTG cable that short-circuits pins 4 and five sets the state to UNDEFINED in those very files.



    U-Boot bootloader and thumb drive



    On our controller we use an uboot Bootloader, and we can use a USB thumb drive. Uboot reads from the USB thumb drive. So the controller is either a real USB host or hast OTG running in host mode. We use a normal USB cable with Mini B on controller side.

    With the Linux system started, we can use a normal USB cable for networking, and the controller is working in peripheral mode

    Does that mean that the hardware wiring is definitely okay, or could it still be that OTG (host mode) is not working correctly due to wrong wiring?



    Relevant kernel configuration

    Here the options I think are relevant are listed:

    CONFIG_USB_SUPPORT=y

    CONFIG_USB_COMMON=y

    CONFIG_USB_ARCH_HAS_HCD=y

    CONFIG_USB_ARCH_HAS_OHCI=y

    CONFIG_USB_ARCH_HAS_EHCI=y

    CONFIG_USB=y

    CONFIG_USB_DEBUG=y

    CONFIG_USB_ANNOUNCE_NEW_DEVICES=y

    CONFIG_USB_DEVICEFS=y

    CONFIG_USB_DEVICE_CLASS=y

    # CONFIG_USB_DYNAMIC_MINORS is not set

    CONFIG_USB_SUSPEND=y

    CONFIG_USB_OTG=y

    # CONFIG_USB_EHCI_HCD=y

    # CONFIG_USB_OHCI_HCD=y

    CONFIG_USB_MUSB_HDRC=y

    CONFIG_USB_MUSB_TUSB6010_GLUE=y

    CONFIG_USB_MUSB_TI81XX_GLUE=y

    CONFIG_USB_MUSB_TI81XX=y

    CONFIG_USB_TI_CPPI41_DMA_HW=y

    CONFIG_USB_INVENTRA_DMA=y

    CONFIG_USB_TI_CPPI_DMA=y

    CONFIG_USB_TI_CPPI41_DMA=y

    CONFIG_USB_ACM=y

    CONFIG_USB_STORAGE=y

    CONFIG_USB_SERIAL=y

    CONFIG_USB_SERIAL_GENERIC=y

    CONFIG_USB_GADGET=y

    CONFIG_USB_GADGET_VBUS_DRAW=2

    CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2

    CONFIG_USB_GADGET_MUSB_HDRC=y

    CONFIG_USB_GADGET_DUALSPEED=y

    CONFIG_USB_ETH=m

    CONFIG_USB_ETH_RNDIS=y

    CONFIG_USB_MASS_STORAGE=m

    CONFIG_USB_OTG_UTILS=y

    CONFIG_NOP_USB_XCEIV=y

    CONFIG_MMC=y

    CONFIG_MMC_UNSAFE_RESUME=y

    CONFIG_MMC_OMAP_HS=y

    I'm not quite sure whether the following settings are correct:

    # CONFIG_USB_OTG_WHITELIST is not set

    CONFIG_USB_ARCH_HAS_HCD=y

    CONFIG_USB_ARCH_HAS_OHCI=y

    CONFIG_USB_ARCH_HAS_EHCI=y

    # CONFIG_USB_EHCI_HCD is not set

    # CONFIG_USB_OHCI_HCD is not set

    # CONFIG_MUSB_PIO_ONLY is not set

    CONFIG_USB_INVENTRA_DMA=y

    CONFIG_USB_TI_CPPI_DMA=y

    CONFIG_USB_TI_CPPI41_DMA=y

  • Stephan,

    Please work with your hardware supplier to get USB fully working, the supplier knows the system better than anyone else.

    Since USB host works in uboot, I believe the issue is in software side in kernel.

  • pre.cjk { font-family: "Droid Sans Fallback",monospace; }h4.cjk { font-family: "Droid Sans Fallback"; }h4.ctl { font-family: "FreeSans"; }p { margin-bottom: 0.25cm; line-height: 120%; }

    Bin Liu,

    I'll try to involve the hardware supplier but do not know how much they can help with the Linux kernel sources.

    Kernel patch

    I don't think the kernel configuration is wrong, but it seems the kernel always starts with mode setting "peripheral". I managed to get a thumb drive working with a small patch in function

    musb_init_controller()

    in file

    linux-3.2.0-psp04.06.00.11/drivers/usb/musb/musb_core.c

    static int __devinit
    musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
    
    {
      int status;
      struct musb *musb;
    
      struct musb_hdrc_platform_data *plat = dev->platform_data;
    
      plat->mode = MUSB_OTG; // ---------> patch
    
      struct platform_device *pdev = to_platform_device(dev);
      ...
    }
    

    The setting allows to use a thumb drive if it is connected to the USB port at boot time. Switching to peripheral mode also works, but switching from "peripheral" mode to "host" mode does not work. Setting the mode via procfs still does not have any effect



    dmesg output

    At boot I keep seeing the dmesg line

    mux: Failed to setup hwmod io irq -22

    Could that be a problem for /with the USB ports?



    Uboot USB address

    I'm wondering about different addresses for the USB drivers.

    Uboot tells:

    USB Host mode controller at 47401000 using PIO, IRQ 0

    while the Linux dmesg says

    [ 0.182922] musb-hdrc musb-hdrc.0: USB Peripheral mode controller at e083c000 using PIO, IRQ 18

    [ 0.184570] musb-hdrc musb-hdrc.1: USB Peripheral mode controller at e083e800 using PIO, IRQ 19

  • Stephan,

    Stephan Schwarzmann said:
    I'll try to involve the hardware supplier but do not know how much they can help with the Linux kernel sources.

    So the supplier only provides the board, not sw package?

    If so, please try to collect answers for the following questions, then I can try to help.

    - Is this on USB0 or USB1 port?

    - The USB portion of the Schematics.

    Stephan Schwarzmann said:

    mux: Failed to setup hwmod io irq -22

    Could that be a problem for /with the USB ports?

    I don't think this is USB related. But we will figure out it later.

    Stephan Schwarzmann said:

    I'm wondering about different addresses for the USB drivers.

    Uboot tells:

    USB Host mode controller at 47401000 using PIO, IRQ 0

    while the Linux dmesg says

    [ 0.182922] musb-hdrc musb-hdrc.0: USB Peripheral mode controller at e083c000 using PIO, IRQ 18

    I don't think there is problem in here, the address from uboot is a physical address, but the in Linux is virtual address.

  • Hello,

    here you go, I hope the following info answers your questions sufficiently:

    The supplier provides...

    a basic linux kernel but without a proper configuration. Several features like CAN etc have not been working with the supplier's configuration.

    USB0/USB1 and schematics

    Please find some schematics attached now

    I used "insert file" and I hope you can somehow access those links after I posted my reply...

    /cfs-file/__key/communityserver-discussions-components-files/791/usb_5F00_excerpt03.pdf

    /cfs-file/__key/communityserver-discussions-components-files/791/usb_5F00_excerpt01.pdf

    /cfs-file/__key/communityserver-discussions-components-files/791/usb_5F00_excerpt02.pdf

    According to those a 3G module is connected via USB1 and so our USB apparently is USB0. That makes sense.

    Uboot

    Okay so we don't worry about the address any more.

    TI CPU / SOC Architecture

    I am digging into the Linux kernel sources to figure out where USB gets configured as OTG/Host/peripheral.

    There's quite a confusion with terms that I encounter...

    • Our CPU should be AM3552, based on ARM architecture
    • I read a lot about OMAP which (omap1, omap2, omap3, omap4) which seems to be a processor architecture
    • I also read about TI81XX which is called a cpu in Linux sources...at least there is a function "cpu_is_ti816x()"

    I wrote to the hardware supplier to get more information on that...

    arch/arm/mach-omap2/soc.h

    ...
    } else if (cpu_is_ti816x()) { cpu_name = "TI816X"; } else if (soc_is_am335x()) { cpu_name = "AM335X";
    }
    ...


    So this would be a hint that our CPU is either AM335X or TI816X. Here it could be both or one of those:

    drivers/usb/musb/cppi41_dma.c
    if (cpu_is_ti816x() || cpu_is_am33xx()) 

    Debugging


    echo D8 > /proc/driver/musb_hdrc.0


    is not implemented in our kernel version

    The commands
    echo "force host" > /sys/kernel/debug/musb-hdrc.0/testmode

    echo "force otg" > /sys/kernel/debug/musb-hdrc.0/testmode

    did not cause any changes.



    USB settings for AM33XX / TI81XX

    The wiki "Usbgeneralpage" shows different settings for the kernel:

    * DM816X: TI816X usb connector's ID pin control (from software setting)

    * TI814X PG2.x/TI811X: TI816X usb connector's ID pin control (from usb connector)

    It sems that our kernel version does not offer such a Configuration-option, however we see that a SW-setting is used in case of "cpu_is_ti816x" in kernel sources

    file:

    board-support/linux-3.2.0-psp04.06.00.11/drivers/usb/musb/ti81xx.c

     

    TI81XX/TI811X

    The wiki says "TI81XX/TI811X: OTG not supported."...So is the Dual-role controller a workaround for missing OTG and we do not have a real OTG controller?


  • Stephan,

    Let's put aside the wiki for now, it was mainly for AM38x/DM81xx devices for 2.6.37 kernel, part of the info is applicable to AM335x, which is the one you use, but only for 2.6.37 kernel, you are using 3.2 kernel now.

    The schematics in overall looks ok, only one thing that the CAP (C47) on VBUS0 is too small for host mode. The USB2.0 Specs require >120uF for host mode, and <10uF for device mode. So it is kinda tricky to pick one for dual-role mode. You can see on TI AM335x GP EVM the CAP is 4.7uF which works in most cases for both dual-role mode.

    To debug this issue, first please hard wire the USB0_ID pin to ground directly, in case the micro-B cable you use is not modified properly. And reverted any USB related changes you did in the kernel.

    Then to check if the small CAP C47 causes the issue, you can either

    - Temporarily put on a bigger CAP, for example 150uF, to see if a USB device is numerated;

    - Or use a scope to measure USB0_DRVVBUS and USB0_VBUS pins - after a USB device is plugged in, USB0_DRVVBUS should go high, and USB0_VBUS should rise >4.4V and stay high.

    If the USB device is still not enumerated:

    - please provide any console log;

    - log of 'cat /proc/driver/musb-hdrc.0' before and after the USB device is plugged in;

    Further debug is to rebuild the kernel image with DYNAMIC_DEBUG enabled if it wasn't, then boot the board and run the following command

    # mount -t debugfs none /sys/kernel/debug

    # echo 'func ti81xx_interrupt =p' > /sys/kernel/debug/dynamic_debug/control

    # echo 'func musb_interrupt =p' > /sys/kernel/debug/dynamic_debug/control

    then provide the dmesg log after the USB device is plugged in.

  • Another simple test is run the following command after the USB device is plugged in, and provide any console log.

    # echo F > /proc/driver/musb-hdrc.0
  • CAP

    Hm...generally we had the USB working as both PERIPHERAL (usually when Linux is running, we use network over USB) and HOST (e.g. with uboot, or with our hard-coded HOST fix as per post yesterday).

    Anyway our CAP with 0.1uF seems to be completely mis-dimensioned for dual-role / OTG. I'll inform the hardware supplier about the issue with the capacitor.

    When you talk about "dual-role-mode" - is it the same os OTG? Because for OTG I guess there should be a specification mentioning the CAP.

    Debugging

    * I'm afraid I do not have the equipment to replace the capacitor here, but let's see what the hardware supplier is gonna do about it. It's gonna take some time.

    * I checked the mini-B cable that we are using, it definitely short-circuits pins 4 and 5

    * With uboot and HOST mode, it doesn't matter whether we use a OTG cable or a normal USB cable which does not short-circuit those pins.

    Other ideas

    I was thinking about using an older kernel version for troubleshooting the USB issue, but couldn't find a TI SDK with kernel 2.6.X.

    We had a deep look into the kernel sources and I'm not quite sure whether it CAN work at all but it's not easy to figure out.

    I'm gonna quit for today (different time zone) and try your other suggestions for debugging tomorrow. Thanks so far!