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.

AM335x USB Overcurrent

Hi All,

I want to know the overcurrent handling mechanism in linux USB driver of  AM335x. Using SDK7.0, linux-3.12. I want to know how exactly it is done based on hardware pin notification.

Regards,

Gangadhar

  • Hi Gangadhar,

    I will forward this to the USB experts for clarification.

  • There is no discrete OC input on AM335x SoC.

    The SoC relies on the USBn_VBUS pin to determine when the USB power switch has experienced an error and will assert VBUS_ERROR and clear the session bit when the voltage of this pin falls below the threshold value as a result of said error.

    Many customers utilize a GPIO on the SoC for OC notifications from the USB power switch/supply when such functionality is desired.

  • Hi DK,
    Thanks for the info. I want to know whether overcurrent handling is done in linux driver or clearing of session bit by SoC is sufficient.
    You have also mentioned that a GPIO can be utilized for overcurrent notification - I want to know how it can be done and the action that need to be taken under overcurrent condition?

    Regards,
    Gangadhar
  • Gangadhar Gangu said:
    I want to know whether overcurrent handling is done in linux driver or clearing of session bit by SoC is sufficient.

    When USBn_VBUS detects VBUS voltage drops below the valid threshold, the SoC will clear the session and generate VBUS_ERROR interrupt. The linux driver will try to recover the condition by setting the session.

    In SDK6.0 or older releases, this recover has no retry limit - the driver will set the session whenever VBUS_ERROR interrupt is generated. But since SDK7.0, the driver will only retry upto three times. If all the three retries failed, the driver will leave the session off, and the host port is disabled.

  • Hi Bin Liu,
    Thanks for the reply. Yes, in our board, USB port gets disabled on overcurrent condition. We've to restart the board for the port to work. But we want to enable the USB port without restarting the board. For this we have a external circuit which notifies the SoC on a GPIO line whenever overcurrent condition happens. When the faulty device is removed from board, this line goes to normal state. When this goes to normal state we've to enable the USB port. Please tell me the steps/logic to re-enable the USB port.

    Regards,
    Gangadhar
  • Well, if the issue is indeed caused by overcurrent condition, I think fixing this error condition to ensure overcurrent never happen is the best approach. The current driver does not have a way to keep the port disabled and re-enalbe it after the offensive device is removed.

  • Ok, please try the following from the console to see if it re-enables the port.

    # cd /sys/bus/usb/drivers/usb
    # ls
    bind uevent unbind usb0 usb1

    (assume you want to enable usb1 port)
    # echo unbind > usb1
    # echo bind > usb1
    # echo usb1 > unbind
    # echo usb1 > bind

  • I corrected the commands in the post above, in case you only check the e2e notification email and will not receive the updated version.
  • Hi everyone,
    I have an issue with usb devices such as mouse or touchscreen monitor. Sometimes the device stop working and the only way to resume it is to restart the system. The problem is probably related to an interference in the usb cable from the host to the device. I can see usb signals using an oscilloscope and the interference cause the 5V line to drop down until 4V but this occur in 3-4mSec after that the signal goes to 5V again. Often the device continues to work even with interferences, but sometimes the 5V line goes to 0V and the device can't work until a reboot. I read the register 0x47401818 which is USB1STAT and it give the current DRVVBUS value, the value is 1 when the device work correctly and the 5V line is high but it is 0 when the 5V line goes to 0V. Is there a way to activate the line again automatically or by a command in order to make the device operating without restart the system?
    I have the kernel 3.8.13-bone30 and Ubuntu saucy as OS. I tried the commands posted above but it doesn't make effect.

    Regards,
    Alessio
  • AM335x doesn't have a dedicated USB OC pin so USBn_VBUS is used to monitor the state of VBUS. If VBUS droops below ~4.4V while in session the controller will assume the power switch is in OC and will exit the session and de-assert DRVVBUS (if in Host mode).

    What kind of interference is causing a 1V drop in VBUS? Can you describe your cable? Do you have the required >=120uF of capacitance on VBUS?

  • Hi DK,
    Thanks for reply.

    The capacitance is present on the VBUS, I'm using a usb mouse connected via its own cable. In the case of the touch monitor it is connected with an Hi-Speed usb cable type A-B. I'm searching for the voltage drop cause.

    Is there a way to soft resume the usb session without restarting the AM335x? I can monitor the USB1STAT that give the DRVVBUS status and in the case it is low I can run a procedure to resume the usb session.
  • Excuse me,
    I checked the schematic of the PCB between AM335x and the USB connector, the capacitor I have is only 100uF and it is placed before the power switch. Is it correct in that place? I attached the part of the schematic.

  • I'm not an expert on the power switches, but based on a cursory review of the data manual I don't see this as being a big problem. I'd always prefer that bulk capacitance be placed as close to the sink (the USB socket in this case) as possible though. Any chance you could replace C35 with =>120uF and retest?

    Also, FB8 and FB7 shouldn't typically be needed.

  • I'll try to replace C35 and I can mount a capacitor on VBUS near the USB socket in order to check if the issue persist. This will take a while for me.
    Anyway is there a way to restore the USB session by software when it is cleared?
  • Nobody know if there is a software method to restore the USB session?

    I need only one device so it is directly connected to the usb port of the processor without any hub. I'm not been able to replace the capacitor so far. I prefer to use a soft reset to restore the usb session.
  • Alessio Cellante said:
    I have the kernel 3.8.13-bone30 and Ubuntu saucy as OS. I tried the commands posted above but it doesn't make effect.

    Please try it again and ensure you do it right.

    # cd /sys/bus/usb/drivers/usb
    # ls
    bind uevent unbind usb0 usb1

    (assume you want to enable usb1 port)
    # echo usb1 > unbind
    # echo usb1 > bind

    Please note that depending on your kernel config, you might get 'usb0 usb1' or 'usb1 usb2' under this directory. Regardless, the one with lower suffix is for MUSB0 port, and the one with higher suffix is for MUSB1 port. Please ensure you unbind/bind the right port.

  • I've made some tests following the procedure above. This is used to unload and reload the usb driver. In order to make my device to work again I need to repeat unbind and bind many times. Frequently the "unbind" requires about 1 minute and a half to complete. Is it normal? Sometimes during I wait for unbind completion the whole system reboots itself. I think this procedure isn't very stable. The only thing I need is to re-enable the usb power line. Do you know about the usb driver sources? Are they available somewhere? Can you give me some info about them? I can watch inside them in order to find some low level action that (if possible) I can implement in a PRU module in order to only re-enable the usb power.
  • Alessio Cellante said:
    Frequently the "unbind" requires about 1 minute and a half to complete. Is it normal?

    I don't think it is normal. I've never seen it takes that long.

    Alessio Cellante said:
    Sometimes during I wait for unbind completion the whole system reboots itself.

    It sounds like the system locked up then watch dog ticked in which causes system reboot.

    Alessio Cellante said:
    Do you know about the usb driver sources?

    The usb source is under drivers/usb/{core,musb}/.

    Alessio Cellante said:
    Are they available somewhere?

    I am not sure where you got your 3.8.13-bone30 kernel from, but I do know it is not released/supported by TI.

    Alessio Cellante said:
    I can watch inside them in order to find some low level action that (if possible) I can implement in a PRU module in order to only re-enable the usb power.

    I would say this is very dangerous hacking, unless you know kernel USB module very well. I would think the best solution is to fix the over-current condition.

  • Thanks for quick reply,

    I've made tests also using larger capacitor near the usb socket. It reduces the locking of the usb but not at all.

    Is there drivers or kernel released/supported by TI for this AM335x that was tested with this unit? And that is possible to use for restoring correctly the usb session?

    If not, is possible to have the kernel you use for testing the device?

    I can switch to yours if it's possible for my application.

    I know that operating as I wrote to re-enable the usb is dangerous but I want to understand the problem of the time consuption. I can't understand the low level instruction for usb initilization reading the TechnicalReferenceManual. Can you help me in this way?
  • Alessio Cellante said:
    Is there drivers or kernel released/supported by TI for this AM335x that was tested with this unit?

    Here is TI released Linux package for AM335x: http://software-dl.ti.com/processor-sw/esd/PROCESSOR-SDK-LINUX-AM335X/latest/index_FDS.html.

    Alessio Cellante said:
    And that is possible to use for restoring correctly the usb session?

    No, neither TI kernel or community mainline kernel provides an interface for manipulating the session. It supposed to be transparent to upper layer applications, if the board is designed correctly.

    Alessio Cellante said:
    I can't understand the low level instruction for usb initilization reading the TechnicalReferenceManual. Can you help me in this way?

    I am sorry, but I am unable to help you on this. We don't support non-TI released or customized Linux driver/kernel.

  • Ok, in mainline kernel v4.1 I do have a patch to add an interface to manually enable/disable session, please check the mainline patch: usb: musb: add softconnect for host mode, but I am not sure it will solve your problem, since over-current condition causes an internal flag set in musb driver, I never checked if this flag will be cleared when disable/enable session.

  • Hi,
    I left this project for a while, but I performed some tests.
    I switched to TI 4.1.13-g8dc6617 kernel from the TI SDK.
    I made a test bench in order to generate the overcurrent condition using a trackball mouse or a USB key directly connected to the USB host port.
    When the overcurrent condition appears, I get:

    [ 1767.838576] musb-hdrc musb-hdrc.1.auto: VBUS_ERROR in a_wait_vrise (90, <VBusValid), retry #3, port1 0008030d
    [ 1768.121885] usb 1-1: new low-speed USB device number 12 using musb-hdrc

    I remove the overload, in this case the VBUS remain low and I get the following:

    [ 1783.241902] usb 1-1: device descriptor read/64, error -110
    [ 1798.471900] usb 1-1: device descriptor read/64, error -110
    [ 1798.701886] usb 1-1: new low-speed USB device number 13 using musb-hdrc
    [ 1813.821889] usb 1-1: device descriptor read/64, error -110
    [ 1829.051895] usb 1-1: device descriptor read/64, error -110
    [ 1829.281885] usb 1-1: new low-speed USB device number 14 using musb-hdrc
    [ 1839.701897] usb 1-1: device not accepting address 14, error -110
    [ 1839.821878] usb 1-1: new low-speed USB device number 15 using musb-hdrc
    [ 1850.241890] usb 1-1: device not accepting address 15, error -110
    [ 1850.248096] usb usb1-port1: unable to enumerate USB device
    [ 1850.471908] usb usb1-port1: over-current condition
    [ 1850.771874] usb 1-1: new low-speed USB device number 16 using musb-hdrc
    [ 1850.919370] usb 1-1: New USB device found, idVendor=047d, idProduct=2048
    [ 1850.926201] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    [ 1850.933965] usb 1-1: Product: Kensington Eagle Trackball
    [ 1850.939353] usb 1-1: Manufacturer: Primax
    [ 1850.968077] input: Primax Kensington Eagle Trackball as /devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1:1.0/0003:047D:2048.0006/input/input6
    [ 1851.008001] hid-generic 0003:047D:2048.0006: input,hidraw0: USB HID v1.11 Mouse [Primax Kensington Eagle Trackball] on usb-musb-hdrc.1.auto-1/input0

    at this point the VBUS is high and the device is working. I observe that VBUS remain low until 1850.xxxxxx. This test was good and everything were automatically restored.

    Making another test I get:

    [ 2274.746954] musb-hdrc musb-hdrc.1.auto: VBUS_ERROR in a_wait_vrise (90, <VBusValid), retry #3, port1 0008030f

    VBUS remains low and lsusb shows:

    Bus 001 Device 016: ID 047d:2048 Kensington Orbit Trackball with Scroll Ring
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

    using the method of unbind, bind usb1 I get:

    [ 2480.400083] usb 1-1: USB disconnect, device number 16
    [ 2480.482499] musb_bus_suspend 2484: trying to suspend as a_wait_vrise while active
    [ 2496.309103] hub 1-0:1.0: USB hub found
    [ 2496.318623] hub 1-0:1.0: 1 port detected
    [ 2496.651924] usb usb1-port1: over-current condition
    [ 2496.991879] usb 1-1: new low-speed USB device number 18 using musb-hdrc
    [ 2497.571860] usb 1-1: new low-speed USB device number 19 using musb-hdrc
    [ 2498.151865] usb 1-1: new low-speed USB device number 20 using musb-hdrc
    [ 2498.691873] usb 1-1: new low-speed USB device number 21 using musb-hdrc

    VBUS is high but the device doesn't work. lsusb shows:

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

    If I unplug and reconnect the device back, it is recognised and it starts working.

    In the previous post I read about a patch to add an interface to manually enable/disable session in mainline kernel v4.1.
    Can you explain how to use this patch?
    Why in some cases the device returns to work and sometimes it doesn't?
    I can see different codes (last number) on VBUS_ERROR lines. What are these codes?

    Hope for help in order to find a method to permit devices' restore without unplug them.
    Thanks, best regards.
  • Anyone can help me about the questions in the previous post?
  • Please add the following into your uboot bootargs to see if it makes difference.

    usbcore.autosuspend=-1
  • Thanks Bin for your reply. I'll try it as soon as possible.

    There is an aspect that I want to understand. Assuming all is working fine and there are no overcurrent issues with USB, when I use this command:
    # echo usb1 > unbind
    I can disable the USB functionality.
    To resume it, I do:
    # echo usb1 > bind
    At this point the device that is connected won't restart. To resume its operation I need to physically unplug and reconnect the device again.

    I observed that if the device is disconnected after 'unbind' and a different one is plugged in before 'bind', the new device starts working automatically after 'bind'.

    Is there a reason with this? Is it possible to have the same device working after the 'unbind', 'bind'?

    Thanks
  • Hi, anyone can help me in understanding the 'unbind', 'bind' procedure as described in the previous post?
    Thanks
  • Alessio Cellante said:
    At this point the device that is connected won't restart. To resume its operation I need to physically unplug and reconnect the device again.

    I observed that if the device is disconnected after 'unbind' and a different one is plugged in before 'bind', the new device starts working automatically after 'bind'.

    I confirm that I observe the same on am335x EVM. I will be traveling for a few weeks from next week, and will take a look at this once I am back.

  • Alessio Cellante said:
    Assuming all is working fine and there are no overcurrent issues with USB, when I use this command:
    # echo usb1 > unbind
    I can disable the USB functionality.
    To resume it, I do:
    # echo usb1 > bind
    At this point the device that is connected won't restart. To resume its operation I need to physically unplug and reconnect the device again.

    It turns out that unbind/bind the usb core driver does not notify the musb controller driver, which causes the failure of enumerating the plugged device. So instead the right sequence should be unbind/bind the musb-dsps driver as following:

    # echo '47401400.usb' > /sys/bus/platform/drivers/musb-dsps/unbind
    # echo '47401400.usb' > /sys/bus/platform/drivers/musb-dsps/bind

    This is for MUSB0 port. For MUSB1 port please use '47401c00.usb' in the commands above.

    Please also note that if the port is in otg mode (dr_mode = otg in DT file), you also have to reload the gadget driver after rebind musb-dsps driver.

    # modprobe -r <the-gadget-driver>
    # modprobe <the-gadget-driver>