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.

AM3352 USB: VBUS turns off on inserting some Bluetooth USB dongles

Other Parts Discussed in Thread: TPS2052C, AM3352

Hi,

we have a hardware design using both USBs of the AM3352 as hosts (i.e. both have a type A receptable). The VBUS is powered with a TPS2052C power distribution switch to let the Sitara turn the VBUS voltage on and off. In an error, our hardware designers did not inlcude the 120 uF low-ESR capacitance near to the USB receptable mentioned in USB spec -- only the "IN" pin of the TPS2052C is buffered with 100 uF, the outputs of the TPs2052C are only stabilized with a 100 nF ceramic cap each.

Because USB memory sticks work flawlessly, this error hasn't been detected up to now and we already have some devices without the 120 uF caps "in the wild". With some Bluetooth USB dongles connected to the device at boot time, we now encounter the issue that the VBUS voltage is only turned on for around 2 ms and the turned off again. This "2ms glitch" is repeated three more times before the VBUS stays turned off until reboot (yellow is the VBUSDRV signal from Sitara, cyan is the VBUS voltage measured close to Sitaras input):

You see the connected Bluetooth USB dongle causes the VBUS voltage to drop a bit after a first peak(because of missing capacitor)

I have spent some time analyzing the issue. From what I read from the USB registers, it looks that the Sitara thinks it is a "B" device and turns off VBUS, because in the case of failure, the MSB in the Mentor DEVCTL register is set.

I already tried to force host mode of the USB core, e.g. by altering the IDDIG and IDDIG_MUX bits in USBxMODE register, but without success. I always end up in the described situation.


Is there some other way to force the USB core to host mode and prevent the VBUS turn off? We do not need the OTG functionality and it would be very helpful if we could provide a SW fix for the devices that miss the capacitor.

  • Hi,

    I will forward this to the USB experts, however you should note that the >120uF capacitor is required by the USB specification.
  • Hi Biser,

    thanks. I know that the cap is required - the change has already been done in the hardware. But as mentioned, we have devices produced that miss it and a SW fix would ease the situation.
  • Frank,

    What kernel version do you use?
    We never tried any sw workaround for this issue. But there is one register bit _could_ do something - not guaranteed through.
    Please let me know your kernel version, then I will provide a patch for you to try.
  • Never mind, the register bit I had in my mind will not fix your problem. The action of turning off VBUS when VBUSERROR happens is purely a hw action. You have no sw workaround.
  • Hi Bin Liu,

    thanks for the info.

    I tried with three different kernel versions: 3.14 and 4.5.1 "vanilla" kernels and the kernel of processor-sdk-linux-03.00.00 -- I observed exactly the same behaviour with all three kernels.

    But are you really sure it is a hardware issue?
    What makes me wonder is that the Sitara Reference Manual (SPRUH73N, 16.2.7) says "The USB2.0 controller will the wait to for the voltage of the USBx_VBUSIN to go high. After 100 ms, if it does not see the voltage on the USBX_VBUSIN pin to be within a Vbus Valid range (>= 4.4V), it will generate a VBus error interrupt."
    But I observe that the voltage is turned off after less than 2 ms, and I see that the DEVCTL register indicates the role of a "B" device. This lets me think I do not see a "voltage too low after 100 ms" situation here but something different.
    My assumption was that negotiation of the device role goes wrong and my hope is that you could avoid this by forcing the USB controller to host role. So perhaps you can tell me about the registers you talked about in your first post to give it a try?
  • Frank,

    To be sure if this is indeed VBUS ERROR problem, please enable the following debug statement in dsps_interrupt() in drivers/usb/musb/musb_dsps.c, and provide the dmesg log.

    330         musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;          
    331         if (usbintr)                                                            
    332                 dsps_writel(reg_base, wrp->coreintr_status, usbintr);           
    333                                                                                 
    334         dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n",                  
    335                         usbintr, epintr);                                       
    336                                                                                 
    337         if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
    

    It will print all the interrupt events.

  • Hi Bin Liu,

    this is what I get after enabling the debug statement:

    [ 3088.649637] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (100) epintr(0)
    [ 3088.649704] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: VBUS on (a_wait_vrise), devctl 01
    [ 3088.651270] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (80) epintr(0)
    [ 3088.651331] musb-hdrc musb-hdrc.0.auto: VBUS_ERROR in a_wait_vrise (91, <VBusValid), retry #1, port1 00000100
    [ 3088.693769] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.1.auto: usbintr (100) epintr(0)
    [ 3088.693840] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.1.auto: VBUS on (a_wait_vrise), devctl 01
    [ 3088.705095] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (100) epintr(0)
    [ 3088.705159] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: VBUS on (a_wait_vrise), devctl 01
    [ 3088.706761] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (80) epintr(0)
    [ 3088.706820] musb-hdrc musb-hdrc.0.auto: VBUS_ERROR in a_wait_vrise (99, VALID), retry #2, port1 00000100
    [ 3088.760746] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (100) epintr(0)
    [ 3088.760813] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: VBUS on (a_wait_vrise), devctl 01
    [ 3088.762414] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (80) epintr(0)
    [ 3088.762470] musb-hdrc musb-hdrc.0.auto: VBUS_ERROR in a_wait_vrise (99, VALID), retry #3, port1 00000100
    [ 3088.816409] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (100) epintr(0)
    [ 3088.816478] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: VBUS on (a_wait_vrise), devctl 01
    [ 3088.818020] musb_dsps:dsps_interrupt: musb-hdrc musb-hdrc.0.auto: usbintr (80) epintr(0)
    [ 3088.818075] musb-hdrc musb-hdrc.0.auto: VBUS_ERROR in a_wait_vrise (98, VALID), retry #3, port1 00080108
    

    best regards,

    Frank

  • Frank,


    Thanks for the log. It clearly tells this is VBUSERROR condition, which mainly caused by insufficient VBUS cap. Unfortunately there is no sw workaround for this issue.

    The 100ms mentioned in the TRM is the maximum time while the PHY monitors the VBUS raising, but the monitoring has more complicated logic which could detect an error and turn off DRVVBUS pin earlier.

  • Hi Bin Liu,

    thank you for you support.