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 + -
显示快捷键?