小弟目前在8168evm 上使用RTOS系統做開發,因為需使用USB功能,所以將ezsdk上/driver/usb/musb上的ti81xx.c 上的ti81xx_musb_init()移植過來做初始化測試,而usb列舉與傳輸等等過程已經購買3rd party的source code做連接。
目前狀況是:
(1) 當usb裝置(如鼠標)已經插入EVM板子時,開機後鼠標的LED燈都不亮,但會進入isr。
(2)當開機後,再插入鼠標,鼠標的LED燈會閃一下就不亮了。
是否是列舉失敗或是供電問題,或是我的初始化有問題?
下面附上我的初始化代碼:
/////////register open/////////////////
val = RD_MEM_32(RM_DEFAULT_RSTCTRL);
val &=0xFFFFFF9F;
WR_MEM_32(RM_DEFAULT_RSTCTRL, val);
while(((RD_MEM_32(RM_DEFAULT_RSTST) & 0x00000060)>>5)!=0x3);
val = RD_MEM_32(RM_DEFAULT_RSTST);
val |= 0x00000060;
WR_MEM_32(RM_DEFAULT_RSTST, val);
WR_MEM_32(CM_DEFAULT_L3_SLOW_CLKSTCTRL, 0x02); // L3_SLOW_CLKSTCTRL (Enable Interconnect Clock)
val = RD_MEM_32(CM_DEFAULT_USB_CLKCTRL);
val = 0x02;
WR_MEM_32(CM_DEFAULT_USB_CLKCTRL, val);
while(((RD_MEM_32(CM_DEFAULT_USB_CLKCTRL) & 0x70000)>>16)==0x7);
WR_MEM_32(0x48140620, 0x3);//0
//////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------//
///////usb_HW_setup from usb linux kernel : ti81xx.c /////////
//----------------------------------------------------------//
#define usb_HW_setup
#ifdef usb_HW_setup
//use usb0 as example...
#define USB_REVISION_REG 0x0000 //USB0REV
#define USB_CTRL_REG 0x0014 //USB0CTRL
#define USB_STAT_REG 0x0018 //USB0STAT
#define USB_IRQ_MERGED_STATUS 0x0020 //USB0IRQMSTAT
#define USB_IRQ_EOI 0x0024 //USB0IRQEOI
#define USB_IRQ_STATUS_RAW_0 0x0028 //USB0IRQSTATRAW0
#define USB_IRQ_STATUS_RAW_1 0x002c //USB0IRQSTATRAW1
#define USB_IRQ_STATUS_0 0x0030 //USB0IRQSTAT0
#define USB_IRQ_STATUS_1 0x0034 //USB0IRQSTAT1
#define USB_IRQ_ENABLE_SET_0 0x0038 //USB0IRQENABLESET0
#define USB_IRQ_ENABLE_SET_1 0x003c //USB0IRQENABLESET1
#define USB_IRQ_ENABLE_CLR_0 0x0040 //USB0IRQENABLECLR0
#define USB_IRQ_ENABLE_CLR_1 0x0044 //USB0IRQENABLECLR1
// TI816X PHY controls bits
#define TI816X_USBPHY0_NORMAL_MODE (1 << 0)
#define TI816X_USBPHY1_NORMAL_MODE (1 << 1)
#define TI816X_USBPHY_REFCLK_OSC (1 << 8)
#define TI816X_PHYCTRL0 0x0624
#define TI816X_PHYCTRL1 0x062c
#define TI816X_PHY_TXRISETUNE 1
#define TI816X_PHY_TXVREFTUNE 0xc
#define TI816X_PHY_TXPREEMTUNE 0x2
#define USB_PHY_UTMI_REG 0x00e0
#define USB_PHY_UTMI_LB_REG 0x00e4
#define USB_MODE_REG 0x00e8
#define USBMODE_USBID_MUXSEL 0x80
#define USBMODE_USBID_HIGH 0x100
#define MUSB_FADDR 0x00 /* 8-bit */
#define MUSB_POWER 0x01 /* 8-bit */
#define MUSB_INTRTX 0x02 /* 16-bit */
#define MUSB_INTRRX 0x04
#define MUSB_INTRTXE 0x06
#define MUSB_INTRRXE 0x08
#define MUSB_INTRUSB 0x0A /* 8 bit */
#define MUSB_INTRUSBE 0x0B /* 8 bit */
#define MUSB_FRAME 0x0C
#define MUSB_INDEX 0x0E /* 8 bit */
#define MUSB_TESTMODE 0x0F /* 8 bit */
/* POWER */
#define MUSB_POWER_ISOUPDATE 0x80
#define MUSB_POWER_SOFTCONN 0x40
#define MUSB_POWER_HSENAB 0x20
#define MUSB_POWER_HSMODE 0x10
#define MUSB_POWER_RESET 0x08
#define MUSB_POWER_RESUME 0x04
#define MUSB_POWER_SUSPENDM 0x02
#define MUSB_POWER_ENSUSPEND 0x01
//USBSS reg
#define USBSS_REVISION 0x0000
#define USBSS_SYSCONFIG 0x0010
/* USBSS EOI interrupt register */
#define USBSS_IRQ_EOI 0x0020
/* USBSS interrupt generation/status register */
#define USBSS_IRQ_STATUS_RAW 0x0024
/* USBSS interrupt status register */
#define USBSS_IRQ_STATUS 0x0028
/* USBSS interrupt enable register */
#define USBSS_IRQ_ENABLE_SET 0x002c
/* USBSS interrupt clear register */
#define USBSS_IRQ_ENABLE_CLEAR 0x0030
#define USBSS_BASE 0x47400000
#define MUSB_HOST 1
#define MUSB_PERIPHERAL 0
//ti81xx_musb_init
u32 rev;
u32 reg_base; //usb0 = 0x47401000 , usb1 = 0x47401800;
u32 mentor_regs; //usb0 = 0x47401400 , usb1 = 0x47401C00
u32 temp_reg=0;
u32 usb_ctrl0 = 0x48140620, usb_ctrl1=0x48140628; //usb_ctrl0 = 0x48140620 , usb_ctrl1 = 0x48140628
u32 usb_phy0 = 0x48140624, usb_phy1 = 0x4814062C;
u32 usb_phy,usb_ctrl;
u8 current_use_usb = 0; //0=usb0, 1=usb1
u8 devctl=0;
//usbotg_ss_init();
if(current_use_usb ==0)
{
usb_ctrl= usb_ctrl0;
usb_phy= usb_phy0;
reg_base=0x47401000;
mentor_regs = 0x47401400;
}
else
{
usb_ctrl= usb_ctrl1;
usb_phy= usb_phy1;
reg_base=0x47401800;
mentor_regs = 0x47401C00;
}
//////// Returns zero if e.g. not clocked
temp_reg = reg_base + USB_REVISION_REG;
rev = RD_MEM_32(temp_reg);
if (!rev)
return 0;// no device
/////// Reset the controller
temp_reg = reg_base + USB_CTRL_REG;
WR_MEM_32(temp_reg, 1);
// wait till reset bit clears
//while ((musb_readl(reg_base, USB_CTRL_REG) & 0x1))
// cpu_relax();
while((RD_MEM_32(temp_reg) & 0x1 )== 1);
/////// Start the on-chip PHY and its PLL.
u32 phy_ctrl_reg;
u32 phy_value;
phy_value = RD_MEM_32(usb_ctrl);
phy_value |= (TI816X_USBPHY0_NORMAL_MODE
| TI816X_USBPHY1_NORMAL_MODE);
phy_value &= ~(TI816X_USBPHY_REFCLK_OSC);
phy_ctrl_reg = RD_MEM_32(usb_phy);
phy_ctrl_reg |= TI816X_PHY_TXRISETUNE |
TI816X_PHY_TXVREFTUNE |
TI816X_PHY_TXPREEMTUNE;
WR_MEM_32(usb_phy,phy_ctrl_reg);
WR_MEM_32(usb_ctrl,phy_value);
//musb->a_wait_bcon = A_WAIT_BCON_TIMEOUT;
//musb->isr = ti81xx_interrupt;
/////// set musb controller to host mode
musb_set_mode(reg_base,MUSB_HOST);
DMV_delay_us(100000); //100ms
////// irq isr setup
isr_register(hcd_musb_interrupt_handler, USB0INT); //USB0INT =18
interrupt_enable(USB0INT);
////////// enable babble workaround
#ifdef 0 //babble
/* Reset the controller */
temp_reg = reg_base + USB_CTRL_REG;
WR_MEM_32(temp_reg, 1);
while((RD_MEM_32(temp_reg) & 0x1 )== 1);
/* Shutdown the on-chip PHY and its PLL. */
/* do not shut down the phy if rxcalib is enabled
* performing rxcalibration second time does not work
*/
phy_value = RD_MEM_32(usb_ctrl);
phy_value &= ~(TI816X_USBPHY0_NORMAL_MODE
| TI816X_USBPHY1_NORMAL_MODE
| TI816X_USBPHY_REFCLK_OSC);
WR_MEM_32(usb_ctrl,phy_value);
DMV_delay_us(100);
//reset host mode
musb_set_mode(reg_base,MUSB_HOST);
/* turn on the vbus */
DMV_delay_us(100000);
/* enable the usbphy */
phy_value = RD_MEM_32(usb_ctrl);
phy_value |= (TI816X_USBPHY0_NORMAL_MODE
| TI816X_USBPHY1_NORMAL_MODE);
phy_value &= ~(TI816X_USBPHY_REFCLK_OSC);
phy_ctrl_reg = RD_MEM_32(usb_phy);
phy_ctrl_reg |= TI816X_PHY_TXRISETUNE |
TI816X_PHY_TXVREFTUNE |
TI816X_PHY_TXPREEMTUNE;
WR_MEM_32(usb_phy,phy_ctrl_reg);
WR_MEM_32(usb_ctrl,phy_value);
DMV_delay_us(100000);
//if (musb->ops->reinit)
// musb->ops->reinit(plat->config->multipoint, musb);
#endif
/////////////////////////////////////////////////////
//Non-highlander interrupt enable
temp_reg = reg_base + USB_CTRL_REG;
WR_MEM_32(temp_reg, 0x00000008);
//Enable interrupts for all endpoints in RX and TX.
temp_reg = reg_base + USB_IRQ_ENABLE_SET_0;
WR_MEM_32(temp_reg, 0xFFFFFFFF);
temp_reg = reg_base + USB_IRQ_ENABLE_SET_1;
WR_MEM_32(temp_reg, 0xFFFFFFFF);
//Enable the USB interrupt register
temp_reg=mentor_regs+MUSB_INTRTXE;
WR_MEM_16(temp_reg, 0xFFFF);
temp_reg=mentor_regs+MUSB_INTRRXE;
WR_MEM_16(temp_reg, 0xFFFE);
temp_reg=mentor_regs+MUSB_INTRUSBE;
WR_MEM_8(temp_reg, 0xFF);
//temp_reg=mentor_regs+MUSB_TESTMODE;
//WR_MEM_8(temp_reg, 0);
// put into basic highspeed mode and start session
temp_reg=mentor_regs+MUSB_POWER;
WR_MEM_8(temp_reg, MUSB_POWER_ISOUPDATE | MUSB_POWER_SOFTCONN | MUSB_POWER_HSENAB);
//ssession start 0x60:DEVCTL
temp_reg = mentor_regs + 0x60;
devctl = RD_MEM_32(temp_reg);
devctl &= ~0x1;
devctl |= 0x1;
WR_MEM_8(temp_reg,devctl);