* The Mentor core doesn't debounce VBUS as needed
* to cope with device connect current spikes. This
* means it's not uncommon for bus-powered devices
* to get VBUS errors during enumeration.
*
* This is a workaround, but newer RTL from Mentor
* seems to allow a better one: "re"-starting sessions
* without waiting for VBUS to stop registering in
* devctl.
*/
musb->int_usb &= ~MUSB_INTR_VBUSERROR;
musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
mod_timer(&musb->otg_workaround,
jiffies + POLL_SECONDS * HZ);
WARNING("VBUS error workaround (delay coming)\n"); 这句话会一直打印,目前猜测的是硬件的电压不太稳定,所以才会一直打印。
} else if (is_host_enabled(musb) && drvvbus) {
if ((devctl & MUSB_DEVCTL_SESSION) &&
!(devctl & MUSB_DEVCTL_BDEVICE) &&
!(devctl & MUSB_DEVCTL_HM)) {
dev_dbg(musb->controller,
"Only micro-A plug is connected\n");
} else {
if (musb->is_active)
del_timer(&musb->otg_workaround);
else
musb->is_active = 1;
MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
}
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
musb->xceiv->default_a = 0;
musb->xceiv->state = OTG_STATE_B_IDLE;
}
/* NOTE: this must complete power-on within 100 ms. */
dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
drvvbus ? "on" : "off",
otg_state_string(musb->xceiv->state),
err ? " ERROR" : "",
devctl);
ret = IRQ_HANDLED;
}
if (musb->int_tx || musb->int_rx || musb->int_usb)
ret |= musb_interrupt(musb);
eoi:
/* EOI needs to be written for the IRQ to be re-asserted. */
if (ret == IRQ_HANDLED || epintr || usbintr) {
/* write EOI */
musb_writel(reg_base, USB_IRQ_EOI, 1);
}
/* Poll for ID change */
if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
mod_timer(&musb->otg_workaround, jiffies + POLL_SECONDS * HZ);
spin_unlock_irqrestore(&musb->lock, flags);
if (ret != IRQ_HANDLED) {
if (epintr || usbintr)
/*
* We sometimes get unhandled IRQs in the peripheral
* mode from EP0 and SOF…
*/
dev_dbg(musb->controller, "Unhandled USB IRQ %08x-%08x\n",
epintr, usbintr);
else if (printk_ratelimit())
/*
* We've seen series of spurious interrupts in the
* peripheral mode after USB reset and then after some
* time a real interrupt storm starting…
*/
dev_dbg(musb->controller, "Spurious IRQ, CPPI 4.1 status %08x, %08x\n",
pend1, pend2);
}
if (is_babble) {
if (musb->enable_babble_work)
schedule_work(&musb->work);
else {
musb_writeb(musb->mregs, MUSB_DEVCTL,
musb_readb(musb->mregs, MUSB_DEVCTL) |
MUSB_DEVCTL_SESSION);
}
}
return ret;
}
Yaoming Qin:
请您贴下usb部分包括和AM335x连接部分的原理图
kun huang2:
回复 Yaoming Qin:
您好!谢谢你的回复。
Steven Liu1:
回复 kun huang2:
USB_DC是由谁供的?直连的5V输入?还是通过一个LDO+使能脚控制?
kun huang2:
回复 Steven Liu1:
您好!USB_DC是直接连的5v电源
Steven Liu1:
回复 kun huang2:
建议你在测试中,加上一个patch:http://e2e.ti.com/support/arm/sitara_arm/f/791/p/333490/1163908
原因如下:
As I suspected, you tied USB0_VBUS directly to 5V rail.
As mentioned in the AM335x TRM, the musb is a dual-role controller, its USBx_VBUS pin has to be controlled by a power switch device to switch between host or device mode.
You could modify your design to add a a power switch as in AM335x EVM reference. Or since you use host-only mode for USB0 port, you could try the following patch, and then please post the output of 'cat /proc/driver/musb_hdrc.0' after applied the patch.
kun huang2:
回复 Steven Liu1:
您好!这个我加过了,还是不行,
除了USB电源芯片可以保证提供足够所需的电流外,更重要的是,AM335x可以通过USBx_DRVVBUS这个脚控制VBUS电源的开关。一旦在 HOST模式发生VBUS 错误或者说过流错误,AM335x会先通过DRVVBUS暂时关闭VBUS电源,以防止重新开始OTG工作模式检测时误判断为device模式
这种方法也试过了,没有成功。
Yaoming Qin:
回复 kun huang2:
请参考下面的一个补丁,所以总体来说,建议您在硬件上参考我们的标准设计
The default 3.2 kernel only works if the USBx_VBUS pin is controlled by a power switch, as the EVM does.
If you tied USBx_VBUS directly to 5V, you have to apply the following patch (also attached) to ignore the first VBUS sensing while transitioning to host mode.
diff –git a/arch/arm/mach-omap2/omap_phy_internal.c
b/arch/arm/mach-omap2/omap_phy_internal.c
index 13bfef3..6aa64b4 100644
— a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -288,8 +288,8 @@ void ti81xx_musb_phy_power(u8 id, u8 on , bool wkup)
TI816X_USBPHY0_NORMAL_MODE;
usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC;
} else if (cpu_is_am33xx()) {
– usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
– usbphycfg |= (USBPHY_OTGVDET_EN |
USBPHY_OTGSESSEND_EN);
+ usbphycfg &= ~(USBPHY_CM_PWRDN |
USBPHY_OTG_PWRDN | USBPHY_OTGVDET_EN);
+ usbphycfg |= USBPHY_OTGSESSEND_EN;
usbwkupctrl = AM33XX_USB_WKUP_CTRL_DISABLE;
}
} else {
Just for your reference, this patch is only applicable to the case that
*both* ports are configured to be in host mode and their USBx_VBUS pin is tied to 5V. If just one port is like so, the patch is different to set its own phycfg correspondingly.
kun huang2:
回复 Yaoming Qin:
你好!这些方法都实验过了,还是不行,是不是硬件的问题,电压是1.33 比正常的高了(1.11),是不是因为电压不正确导致的呢?
Yaoming Qin:
回复 kun huang2:
整理下,按照你目前的想法,vubs直接接5v,您需确定如下几件事:
1. vbus直接拉到5v
2. ID 拉地
3. 打上我给的patch。
请您确保以上三点同时都做了。
谢谢!
kun huang2:
回复 Yaoming Qin:
您好!谢谢你一直的回答!!!
刚才在硬件工程师的协助下,这几点都完成了,还是没什么区别,我都有点怀疑是硬件的问题了。