usbdl_usb_drv.c
来自「MTK 平台启动源码」· C语言 代码 · 共 2,365 行 · 第 1/5 页
C
2,365 行
/* under construction !*/
/* under construction !*/
#endif
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
void DRVPDN_Disable(kal_uint32 addr,kal_uint16 code,kal_uint8 handle)
{
#if ( (defined(MT6205)) || (defined(MT6208)) )
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
DRV_Reg(addr) &= (~code);
RestoreIRQMask(savedMask);
#else
DRV_Reg(addr+0x20) = code;
#endif /*MT6205B,MT6218*/
}
/* USB PDN disable, other modules may need USB PDN*/
void USB_PDNDisable(USB_PDN_OWNER owner)
{
kal_uint32 savedMask;
kal_bool enable_power = KAL_FALSE;
savedMask = SaveAndSetIRQMask();
if(g_usb_pdn_owner == 0)
{
enable_power = KAL_TRUE;
}
g_usb_pdn_owner |= (1<<owner);
RestoreIRQMask(savedMask);
if(enable_power == KAL_TRUE)
{
DRVPDN_Disable(DRVPDN_CON0, DRVPDN_CON0_USB, PDN_USB);
}
}
static void USBDL_CLK_ON(void)
{
#if defined(DRV_UPLL_V1)
DRV_Reg(DRVPDN_CON0_CLR) |= DRVPDN_CON0_UPLL;
#elif defined(DRV_UPLL_V2)
/* hardware issue */
USB_PDNDisable(USB_PDN_OWNER_UPLL);
DRV_Reg(DRVPDN_CON0_CLR) |= DRVPDN_CON0_UPLL;
#elif defined(DRV_UPLL_V3)
/* select UPLL clock source from PLL */
DRV_Reg(PLL) |= 0x0040;
#elif defined(DRV_UPLL_V4)
DRV_Reg(DRVPDN_CON0) &= (~DRVPDN_CON0_PLL2);
/* disable USB clock from external clock */
DRV_Reg(CLK_CON) &= ~0x4000;
DRV_Reg(PLLSEL) |= 0x0008;
#elif defined(DRV_UPLL_V5)
/* This will be changed in 6238 E2 */
DRV_Reg(PLL) |= 0x0040;
#endif
}
void USBDL_USBPowerON(void)
{
#if defined(DRV_USB_IP_V1)
volatile kal_uint8 IntrUSB;
#endif
USBDL_CLK_ON();
DRV_Reg(DRVPDN_CON0_CLR) |= DRVPDN_CON0_USB;
#if defined(DRV_USB_IP_V1)
// clear interrupt before previous power down PDN, the interrupts are read then clear
IntrUSB = DRV_Reg8(USB_INTRUSB);
IntrUSB = DRV_Reg8(USB_INTRIN1);
IntrUSB = DRV_Reg8(USB_INTROUT1);
DRV_WriteReg8(USB_ENABLE, USB_ENABLE_EN);
#endif
}
void USB_Set_DP_Pull_High(void)
{
#if defined(DRV_USB_IP_V3)
USB_Set_DP_Pull_Up(KAL_TRUE);
#else
USB_PowerControl(KAL_TRUE);
#endif
}
/* reset hw power*/
void USB_Reset_Drv(void)
{
#if defined(DRV_USB_IP_V3)
/* Enable software reset, USB IP only can be reset by SW when detecting reset signal from bus */
DRV_WriteReg(USB_SWRST, USB_SWRST_DISUSBRESET);
DRV_WriteReg8(USB_RSTINFO, 0xA6);
/* Because softconn has be decided to set or not */
DRV_WriteReg8(USB_POWER, (DRV_Reg8(USB_POWER)|USB_POWER_ISOUPDATE|USB_POWER_ENABLESUSPENDM));
// DRV_WriteReg8(USB_POWER, (DRV_Reg8(USB_POWER)|USB_POWER_ISOUPDATE));
#elif defined(DRV_USB_IP_V2)
WRITE_EP0_BDT_ADDR(USB_BDT_RX, USB_BDT_EVEN, USB_FIFO_RX0_EVEN);
WRITE_EP0_BDT_ADDR(USB_BDT_RX, USB_BDT_ODD, USB_FIFO_RX0_ODD);
WRITE_EP0_BDT_ADDR(USB_BDT_TX, USB_BDT_EVEN, USB_FIFO_TX0_ODD);
WRITE_EP0_BDT_ADDR(USB_BDT_TX, USB_BDT_ODD, USB_FIFO_TX0_ODD);
WRITE_EPN_BDT_ADDR(1, USB_BDT_RX, USB_FIFO_RX1);
WRITE_EPN_BDT_ADDR(1, USB_BDT_TX, USB_FIFO_TX1);
WRITE_EPN_BDT_ADDR(2, USB_BDT_RX, USB_FIFO_RX2);
WRITE_EPN_BDT_ADDR(2, USB_BDT_TX, USB_FIFO_TX2);
WRITE_EPN_BDT_ADDR(3, USB_BDT_RX, USB_FIFO_RX3);
WRITE_EPN_BDT_ADDR(3, USB_BDT_TX, USB_FIFO_TX3);
DRV_WriteReg8(USB_CTL, 0);
DRV_WriteReg8(USB_ENDPT_CTL(0), VUSB_ENDPT_DISABLE);
DRV_WriteReg8(USB_ENDPT_CTL(1), VUSB_ENDPT_DISABLE);
DRV_WriteReg8(USB_ENDPT_CTL(2), VUSB_ENDPT_DISABLE);
DRV_WriteReg8(USB_ENDPT_CTL(3), VUSB_ENDPT_DISABLE);
#elif defined(DRV_USB_IP_V1)
/* enable software reset, USB IP only can be reset by SW when detecting reset signal from bus */
DRV_WriteReg8(USB_POWER, USB_POWER_SETSUSPEND|USB_POWER_SWRSTENAB);
#endif
}
/* initialize drv registers, including system global interrupt and EP0 interrupt*/
void USB_Initialize_Drv(void)
{
#if defined(DRV_USB_IP_V3)
/* software reset */
DRV_WriteReg(USB_SWRST, (USB_SWRST_DISUSBRESET|USB_SWRST_SWRST));
/* enable system interrupts, but disable all ep interrupts */
USB_EnSysIntr();
DRV_WriteReg8(USB_INDEX, 0);
/* flush ep0 FIFO */
DRV_WriteReg(USB_CSR0, USB_CSR0_FLUSHFIFO);
/* enable EP0 interrupt */
USB_EP0En();
#elif defined(DRV_USB_IP_V2)
kal_uint32 index;
/*
This hardware has special hardware token done of 4 bytes deep FIFO
Clear the status FIFOs
*/
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_INT_STAT, VUSB_INT_STAT_TOKEN_DONE);
/* FIFO deep 4*/
DRV_WriteReg8(USB_FM_ERR_STAT, VUSB_FM_ERR_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_FM_ERR_STAT, VUSB_FM_ERR_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_FM_ERR_STAT, VUSB_FM_ERR_STAT_TOKEN_DONE);
DRV_WriteReg8(USB_FM_ERR_STAT, VUSB_FM_ERR_STAT_TOKEN_DONE);
/* clear all interrupts*/
DRV_WriteReg8(USB_INT_STAT, 0xff);
/* clear all endpoint ctrl */
for(index=0; index<=MAX_INTR_EP_NUM; index++)
DRV_WriteReg8(USB_ENDPT_CTL(index), 0);
/* USB addr=0 (default) */
DRV_WriteReg8(USB_ADDR, 0x00);
WRITE_EP0_BDT_PID(USB_BDT_RX, USB_BDT_EVEN,
(USB_EP0_MAXP<<VUSB_BDT_BC_SHIFT)|VUSB_BDT_OWNS_BIT);
WRITE_EP0_BDT_PID(USB_BDT_RX, USB_BDT_ODD,
(USB_EP0_MAXP<<VUSB_BDT_BC_SHIFT)|VUSB_BDT_OWNS_BIT);
WRITE_EP0_BDT_PID(USB_BDT_TX, USB_BDT_EVEN, USB_EP0_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EP0_BDT_PID(USB_BDT_TX, USB_BDT_ODD, USB_EP0_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(1, USB_BDT_RX, USBDL_EP_BULK_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(1, USB_BDT_TX, USBDL_EP_BULK_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(2, USB_BDT_RX, USBDL_EP_BULK_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(2, USB_BDT_TX, USBDL_EP_BULK_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(3, USB_BDT_RX, USB_EP_INTR_MAXP<<VUSB_BDT_BC_SHIFT);
WRITE_EPN_BDT_PID(3, USB_BDT_TX, USB_EP_INTR_MAXP<<VUSB_BDT_BC_SHIFT);
DRV_WriteReg8(USB_BDT_PAGE_01, 0xBD);
DRV_WriteReg8(USB_BDT_PAGE_02, 0xBD);
DRV_WriteReg8(USB_BDT_PAGE_03, 0xBD);
DRV_WriteReg8(USB_CTL, VUSB_CTL_ODD_RST|VUSB_CTL_USB_EN);
DRV_WriteReg8(USB_CTL, VUSB_CTL_USB_EN);
/* disable Fast mode*/
DRV_WriteReg8(USB_FM_CTL, (DRV_Reg8(USB_FM_CTL)&(~VUSB_FM_CTL_FMENB)));
DRV_WriteReg8(USB_FM_PKT_NUML, 0);
DRV_WriteReg8(USB_FM_PKT_NUMH, 0);
DRV_WriteReg8(USB_FM_PKT_CNTL, 0);
DRV_WriteReg8(USB_FM_PKT_CNTH, 0);
USB_EnSysIntr();
USB_EP0En(); /* enable EP0 */
#elif defined(DRV_USB_IP_V1)
/* software reset */
DRV_WriteReg8(USB_RSTCTRL, USB_RSTCTRL_SWRST);
DRV_WriteReg8(USB_RSTCTRL, 0);
/* When mcu set SWRST, the USB_POWER register will be clear as 0 */
DRV_WriteReg8(USB_POWER, USB_POWER_SETSUSPEND|USB_POWER_SWRSTENAB);
USB_EnSysIntr();
USB_EP0En(); /* enable EP0 */
#endif
}
void USB_Release_Drv(void)
{
#if defined(DRV_USB_IP_V2)
DRV_WriteReg8(USB_INT_ENB, 0);
DRV_WriteReg8(USB_INT_STAT, 0xff);
#endif
}
/* enable system global interrupt*/
static void USB_EnSysIntr(void)
{
#if defined(DRV_USB_IP_V3)
DRV_WriteReg(USB_INTRTXE, 0);
DRV_WriteReg(USB_INTRRXE, 0);
DRV_WriteReg8(USB_INTRUSBE, 0);
DRV_WriteReg8(USB_INTRUSBE, (USB_INTRUSBE_SUSPEND|USB_INTRUSBE_RESUME|USB_INTRUSBE_RESET|USB_INTRUSBE_DISCON));
// DRV_WriteReg8(USB_INTRUSBE, ~USB_INTRUSB_SOF);
#elif defined(DRV_USB_IP_V2)
DRV_WriteReg8(USB_INT_ENB, 0xff&(~(VUSB_INT_ENB_SOF|VUSB_INT_ENB_RESUME)));
DRV_WriteReg8(USB_ERR_ENB, 0xff);
DRV_WriteReg8(USB_PHY_EXTRA, VUSB_PHY_RESUME_INT_ENB);
#elif defined(DRV_USB_IP_V1)
DRV_WriteReg8(USB_INTRIN1E, 0);
DRV_WriteReg8(USB_INTROUT1E, 0);
DRV_WriteReg8(USB_INTRUSBE, 0);
DRV_WriteReg8(USB_INTRUSBE, (USB_INTRUSBE_SUSPEND|USB_INTRUSBE_RESUME|USB_INTRUSBE_RESET));
#endif
}
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#if defined(DRV_USB_IP_V2)
#ifdef __OTG_ENABLE__
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#endif
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#if defined(DRV_USB_IP_V2)
#ifdef __OTG_ENABLE__
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#endif
/* under construction !*/
#endif
/* set address for hw*/
void USB_SetAddress(kal_uint8 addr, UBS_SET_ADDR_STATE state)
{
#if defined(DRV_USB_IP_V3)
if(state == USB_SET_ADDR_STATUS)
DRV_WriteReg8(USB_FADDR, addr);
#elif defined(DRV_USB_IP_V2)
if(state==USB_SET_ADDR_STATUS)
DRV_WriteReg8(USB_ADDR, addr);
#elif defined(DRV_USB_IP_V1)
if(state==USB_SET_ADDR_DATA)
DRV_WriteReg8(USB_FADDR, addr);
#endif
}
kal_uint16 USB_GetFrameCount(void)
{
#if !defined(DRV_USB_IP_V3)
kal_uint8 count;
#endif
kal_uint16 sof;
#if defined(DRV_USB_IP_V3)
sof = DRV_Reg(USB_FRAME);
#elif defined(DRV_USB_IP_V2)
count = DRV_Reg8(USB_FRM_NUML);
sof = (kal_uint16)count;
count = DRV_Reg8(USB_FRM_NUMH);
sof+=(count<<8);
#elif defined(DRV_USB_IP_V1)
count = DRV_Reg8(USB_FRAME1);
sof = (kal_uint16)count;
count = DRV_Reg8(USB_FRAME2);
sof+=(count<<8);
#endif
return sof;
}
/************************************************************
EP ctrl functinos
*************************************************************/
/* initialize EP IN */
void USB_TxEPInit(kal_uint8 epno,kal_uint16 data_size, USB_ENDPT_TXFER_TYPE type)
{
#if defined(DRV_USB_IP_V3)
if(epno == 0)
ASSERT(0);
DRV_WriteReg8(USB_INDEX, epno);
/* double buffers, so flush twice */
DRV_WriteReg(USB_TXCSR, (USB_TXCSR_FLUSHFIFO|USB_TXCSR_CLRDATATOG));
DRV_WriteReg(USB_TXCSR, (USB_TXCSR_FLUSHFIFO|USB_TXCSR_CLRDATATOG));
DRV_WriteReg(USB_TXMAXP, data_size);
/* set FIFO address here */
if(type == USB_ENDPT_BULK)
{
#if 1
//double buffer
DRV_WriteReg8(USB_TXFIFOSZ, (USB_FIFOSZ_SIZE_512|USB_FIFOSZ_DPB));
DRV_WriteReg(USB_TXFIFOADD, (g_FIFOadd/8));
g_FIFOadd += USB_BULK_FIFO_UNIT_SIZE*2;
#else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
else if (type == USB_ENDPT_INTR)
{
#ifdef __INTR_HB__
DRV_WriteReg8(USB_TXFIFOSZ, USB_FIFOSZ_SIZE_4096);
DRV_WriteReg(USB_TXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_INTR_FIFO_UNIT_SIZE;
#else
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
#else
DRV_WriteReg8(USB_TXFIFOSZ, USB_FIFOSZ_SIZE_1024);
DRV_WriteReg(USB_TXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_INTR_FIFO_UNIT_SIZE;
#endif
#endif
}
else if (type == USB_ENDPT_ISO)
{
#ifdef __ISO_HB__
DRV_WriteReg8(USB_TXFIFOSZ, USB_FIFOSZ_SIZE_4096);
DRV_WriteReg(USB_TXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_ISO_FIFO_UNIT_SIZE;
#else
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
#else
DRV_WriteReg8(USB_TXFIFOSZ, USB_FIFOSZ_SIZE_1024);
DRV_WriteReg(USB_TXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_ISO_FIFO_UNIT_SIZE;
#endif
#endif
}
if(g_FIFOadd > 4096)
ASSERT(0);
#elif defined(DRV_USB_IP_V2)
kal_uint8 epctl_value = 0;
/* check the packet size, FIFO only 8 bytes*/
if((epno == 0)||((epno == 3)&&(data_size != 8)))
EXT_ASSERT(0, epno, 0, 0);
switch(type)
{
case USB_ENDPT_BULK:
epctl_value = VUSB_ENDPT_BULK_TX;
break;
case USB_ENDPT_INTR:
epctl_value = VUSB_ENDPT_BULK_TX;
break;
/* not support */
case USB_ENDPT_CTRL:
case USB_ENDPT_ISO:
ASSERT(0);
break;
}
g_UsbDrvInfo.ep_in_max_data_size[epno-1] = (kal_uint8)data_size;
DRV_WriteReg8(USB_ENDPT_CTL(epno), DRV_Reg8(USB_ENDPT_CTL(epno))|epctl_value);
#elif defined(DRV_USB_IP_V1)
if(epno==0)
ASSERT(0);
DRV_WriteReg8(USB_INDEX,epno);
DRV_WriteReg8(USB_INCSR1,(USB_INCSR1_CLRDATATOG | USB_INCSR1_FLUSHFIFO));
DRV_WriteReg8(USB_INMAXP, (kal_uint8)(data_size/8));
#endif
}
/* initialize EP OUT */
void USB_RxEPInit(kal_uint8 epno,kal_uint16 data_size, USB_ENDPT_TXFER_TYPE type)
{
#if defined(DRV_USB_IP_V3)
if(epno == 0)
ASSERT(0);
DRV_WriteReg8(USB_INDEX, epno);
DRV_WriteReg(USB_RXCSR, (USB_RXCSR_FLUSHFIFO|USB_RXCSR_CLRDATATOG));
DRV_WriteReg(USB_RXCSR, (USB_RXCSR_FLUSHFIFO|USB_RXCSR_CLRDATATOG));
DRV_WriteReg(USB_RXMAXP, data_size);
/* set FIFO address here */
if(type == USB_ENDPT_BULK)
{
#if 1
//double buffer
DRV_WriteReg8(USB_RXFIFOSZ, (USB_FIFOSZ_SIZE_512|USB_FIFOSZ_DPB));
DRV_WriteReg(USB_RXFIFOADD, (g_FIFOadd/8));
g_FIFOadd += USB_BULK_FIFO_UNIT_SIZE*2;
#else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
else if(type == USB_ENDPT_ISO)
{
#ifdef __ISO_HB__
DRV_WriteReg8(USB_RXFIFOSZ, USB_FIFOSZ_SIZE_4096);
DRV_WriteReg(USB_RXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_ISO_FIFO_UNIT_SIZE;
#else
#ifdef __ISO_2FIFO__
DRV_WriteReg8(USB_RXFIFOSZ, (USB_FIFOSZ_SIZE_1024|USB_FIFOSZ_DPB));
DRV_WriteReg(USB_RXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_ISO_FIFO_UNIT_SIZE*2;
#else
DRV_WriteReg8(USB_RXFIFOSZ, USB_FIFOSZ_SIZE_1024);
DRV_WriteReg(USB_RXFIFOADD, (kal_uint16)(g_FIFOadd/8));
g_FIFOadd += USB_ISO_FIFO_UNIT_SIZE;
#endif
#endif
}
else
{
ASSERT(0);
}
if(g_FIFOadd > 4096)
ASSERT(0);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?