usb_drv.c

来自「8032底层驱动部分。因为可以移植 所以单独来拿出来」· C语言 代码 · 共 2,312 行 · 第 1/5 页

C
2,312
字号
		nCount = (kal_uint32)DRV_Reg8(USB_COUNT0);
	}
#endif

	return nCount;
}

/* ep in data prepared ready, set ready bit */
void USB_EP_Bulk_In_Ready(kal_uint8 ep_num)
{
	if((ep_num==0)||(ep_num>MAX_INTR_EP_NUM))
		EXT_ASSERT(0, ep_num, 0, 0);

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	WRITE_EPN_BDT_PID(ep_num, USB_BDT_TX, 
							(READ_EPN_BDT_PID(ep_num, USB_BDT_TX) & VUSB_BDT_BC_MASK) |
							(g_UsbDrvInfo.ep_in_data01[ep_num-1]<<VUSB_BDT_DATA01_SHIFT) |
							VUSB_BDT_DTS_BIT | VUSB_BDT_OWNS_BIT);
	g_UsbDrvInfo.ep_in_data01[ep_num-1]^=1;
#else
	DRV_WriteReg8(USB_INDEX,ep_num);
	DRV_WriteReg8(USB_INCSR1, USB_INCSR1_INPKTRDY);
#endif
}

/* return ep out received packet length*/
kal_uint32 USB_EP_Out_Pkt_Len(kal_uint8 ep_num)
{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
#else
	kal_uint8 byCSR;
#endif
	kal_uint32 nCount = 0;
	
	if((ep_num==0)||(ep_num>MAX_INTR_EP_NUM))
		EXT_ASSERT(0, ep_num, 0, 0);
	
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	if((READ_EPN_BDT_PID(ep_num, USB_BDT_RX)&VUSB_BDT_OWNS_BIT)==0)
	{
		nCount = (READ_EPN_BDT_PID(ep_num, USB_BDT_RX)&VUSB_BDT_BC_MASK) 
				>> VUSB_BDT_BC_SHIFT;
	}
#else	
	DRV_WriteReg8(USB_INDEX,ep_num);
	byCSR = DRV_Reg8(USB_OUTCSR1);
	
	if(byCSR & USB_OUTCSR1_OUTPKTRDY)
	{
		nCount = (kal_uint32)DRV_Reg8(USB_OUTCOUNT1);
	}
#endif
	return nCount;
}	

/* ep out data already read out, clear the data*/
void USB_EP_Bulk_Out_Ready(kal_uint8 ep_num)
{
	if((ep_num==0)||(ep_num>MAX_INTR_EP_NUM))
		EXT_ASSERT(0, ep_num, 0, 0);

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	WRITE_EPN_BDT_PID(ep_num, USB_BDT_RX, 
								(g_UsbDrvInfo.ep_out_max_data_size[ep_num-1] << VUSB_BDT_BC_SHIFT) |
								(g_UsbDrvInfo.ep_out_data01[ep_num-1]<<VUSB_BDT_DATA01_SHIFT) |
								VUSB_BDT_DTS_BIT | VUSB_BDT_OWNS_BIT);
	g_UsbDrvInfo.ep_out_data01[ep_num-1]^=1;
#else
	DRV_WriteReg8(USB_INDEX,ep_num);
	DRV_WriteReg8(USB_OUTCSR1, 0);
#endif
}

/* Get status. See if ep in fifo is empty. 
   If false, it means some data in fifo still wait to send out */
kal_bool USB_Is_EP_Bulk_In_Empty(kal_uint8 ep_num)
{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
#else
	kal_uint8 byCSR;
#endif
	kal_bool bRet;
	
	if((ep_num==0)||(ep_num>MAX_INTR_EP_NUM))
		EXT_ASSERT(0, ep_num, 0, 0);

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	/* own bit 1 means the data is still not sent out */
	if((READ_EPN_BDT_PID(ep_num, USB_BDT_TX)&VUSB_BDT_OWNS_BIT)!=0)
		bRet = KAL_FALSE;
	else
		bRet = KAL_TRUE;	
#else	
	DRV_WriteReg8(USB_INDEX, ep_num);	
	byCSR = DRV_Reg8(USB_INCSR1);
	if(byCSR&USB_INCSR1_FIFONOTEMPTY)
		bRet = KAL_FALSE;
	else
		bRet = KAL_TRUE;	
#endif
	
	return bRet;
}

/* clear the fifo for ep IN*/
void USB_Clear_IN_EP_FIFO(kal_uint8 ep_num)
{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
#else	
	DRV_WriteReg8(USB_INDEX, ep_num);
	DRV_WriteReg8(USB_INCSR1, USB_INCSR1_FLUSHFIFO);
	DRV_WriteReg8(USB_INCSR1, USB_INCSR1_FLUSHFIFO);
#endif
}

/* clear the fifo for ep OUT*/
void USB_Clear_OUT_EP_FIFO(kal_uint8 ep_num)
{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
#else	
	DRV_WriteReg8(USB_INDEX, ep_num);
	DRV_WriteReg8(USB_OUTCSR1, USB_OUTCSR1_FLUSHFIFO);
	DRV_WriteReg8(USB_OUTCSR1, USB_OUTCSR1_FLUSHFIFO);
#endif
}

/************************************************************
        DMA contorl functions
*************************************************************/

/* get dma channel for logical endpoint*/
void USB_Get_DMA_Channel(kal_uint8 ep_num)
{
	switch (ep_num)
	{
	case 1:
		g_UsbDrvInfo.dma_port[ep_num - 1]= DMA_GetChannel(DMA_USB1TX);
		break;
#ifdef USB_SUPPORT_MUTIPLE_APP		
	case 2:
		g_UsbDrvInfo.dma_port[ep_num- 1] = DMA_GetChannel(DMA_USB2TX);
		break;
#endif /* USB_SUPPORT_MUTIPLE_APP */		
	default:
		EXT_ASSERT(0, ep_num, 0 , 0);
		break;
	}
}

/* stop DMA channel*/
void USB_Stop_DMA_Channel(kal_uint8 ep_num)
{
	kal_uint32 savedMask;
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))		
	kal_uint32 fm_pkt_num = 0;
	kal_uint32 fm_pkt_cnt = 0;
#endif	

	if(ep_num>MAX_DMA_EP_NUM)
		EXT_ASSERT(0, ep_num, 0, 0);

	if(g_UsbDrvInfo.dma_port[ep_num - 1] != 0)
	{
		if (DMA_CheckRunStat(g_UsbDrvInfo.dma_port[ep_num - 1]))
		{
			DMA_Stop(g_UsbDrvInfo.dma_port[ep_num - 1]);
		}
	
		savedMask = SaveAndSetIRQMask();
		if (DMA_CheckITStat(g_UsbDrvInfo.dma_port[ep_num - 1]))
		{	
			DMA_ACKI(g_UsbDrvInfo.dma_port[ep_num - 1]);
			IRQClearInt(IRQ_DMA_CODE);
		}
		RestoreIRQMask(savedMask);
}

		g_UsbDrvInfo.dma_pktrdy[ep_num - 1] = KAL_FALSE;
		g_UsbDrvInfo.dma_running[ep_num - 1] = KAL_FALSE;
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))	

	/* disable Fast mode*/
	DRV_WriteReg8(USB_FM_CTL, (DRV_Reg8(USB_FM_CTL)&(~VUSB_FM_CTL_FMENB)));

	fm_pkt_num = DRV_Reg8(USB_FM_PKT_NUML) + (DRV_Reg8(USB_FM_PKT_NUMH)<<8);
	fm_pkt_cnt = DRV_Reg8(USB_FM_PKT_CNTL) + (DRV_Reg8(USB_FM_PKT_CNTH)<<8);
	
	if(fm_pkt_num>0)
	{
		/* check whether any packet is sent or not */
		if(DRV_Reg(DMA_COUNT(g_UsbDrvInfo.dma_port[ep_num - 1]))==DRV_Reg(DMA_RLCT(g_UsbDrvInfo.dma_port[ep_num - 1])))
		{
			/* Fast mode is start but no any packet is transmitted */	
			/* restore data01 according to fast mode round */
			if(fm_pkt_num&0x1)
			{
				if(g_UsbDrvInfo.dma_tx_ep!=0)
					g_UsbDrvInfo.ep_in_data01[ep_num-1]^=1; 
				else
					g_UsbDrvInfo.ep_out_data01[ep_num-1]^=1; 
			}		
		}
		else
		{
			/* Fast mode has sent some packet, so data01 can be known from register */
			if((fm_pkt_num-fm_pkt_cnt)&0x1)
			{
				if(g_UsbDrvInfo.dma_tx_ep!=0)
					g_UsbDrvInfo.ep_in_data01[ep_num-1]^=1; 
				else
					g_UsbDrvInfo.ep_out_data01[ep_num-1]^=1; 
			}		
		}
	}	

	g_UsbDrvInfo.dma_tx_ep = 0;
	g_UsbDrvInfo.dma_res_tx_ep = 0;
	g_UsbDrvInfo.fast_mode_tx_ep= 0;
#endif	
}

/* stop and free DMA channel resource*/
void USB_Free_DMA_Channel(kal_uint8 ep_num)
{
	if(ep_num>MAX_DMA_EP_NUM)
		EXT_ASSERT(0, ep_num, 0, 0);
	
	if(g_UsbDrvInfo.dma_port[ep_num - 1] != 0)
	{
		USB_Stop_DMA_Channel(ep_num);
		DMA_FreeChannel(g_UsbDrvInfo.dma_port[ep_num - 1]);
	}	
		g_UsbDrvInfo.dma_port[ep_num - 1] = 0;
}

/* DMA callback for endpoint 1*/
static void USB_DMA_Callback_EP1(void)
{
	kal_uint32 ep_num = 1;
	usb_dma_callback callback = g_UsbDrvInfo.dma_callback[ep_num-1];

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	kal_uint32 		fm_dma_index;

	/* clear tx dma ep flag */
	g_UsbDrvInfo.dma_tx_ep = 0;
	
	if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
		fm_dma_index = VUSB_FM_DMA_TX1;
	else
		fm_dma_index = VUSB_FM_DMA_RX1;

	/* disable DMA*/
	DRV_WriteReg8(USB_DMA_DIS, 1<<fm_dma_index);
#endif

	g_UsbDrvInfo.dma_callback[ep_num-1] = NULL;

	/* the last one pkt length not multiple of MAX_PKT_LEN, clear corresponding bits*/	
	if (g_UsbDrvInfo.dma_pktrdy[ep_num-1])
	{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))	
		if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
	{
			/* tx, config the last one packet */
			WRITE_EPN_BDT_PID(ep_num, USB_BDT_TX, 
									(g_UsbDrvInfo.dma_pktlength[ep_num-1] << VUSB_BDT_BC_SHIFT) |
									(g_UsbDrvInfo.ep_in_data01[ep_num-1]<<VUSB_BDT_DATA01_SHIFT) |
									VUSB_BDT_DTS_BIT | VUSB_BDT_OWNS_BIT);
			g_UsbDrvInfo.ep_in_data01[ep_num-1]^=1;
		}
		else
		{
			/* rx, the last one already recevd*/
			/* nothing need to do */
		}
#else		
		if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
			USB_EP_Bulk_In_Ready(ep_num);
		else
			USB_EP_Bulk_Out_Ready(ep_num);
#endif		
	}

	g_UsbDrvInfo.dma_pktrdy[ep_num-1] = KAL_FALSE;

	/* if application callback function does not request to clear drv_running set by itself, clear running state here*/
	if(g_UsbDrvInfo.dma_callback_upd_run[ep_num-1] == KAL_FALSE)
		g_UsbDrvInfo.dma_running[ep_num-1] = KAL_FALSE;

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	if((g_UsbDrvInfo.dma_res_tx_ep==0)&&(g_UsbDrvInfo.fast_mode_tx_ep==0)&&(callback!=NULL))
	{
		callback();
	}
	else
	{
		//re-save callbcak function, wait until fast mode complete intr or the last pkt token done intr
		g_UsbDrvInfo.dma_callback[ep_num-1] = callback;	
	}
#else
	if(callback != NULL)
		callback();
#endif	
}

#ifdef USB_SUPPORT_MUTIPLE_APP
/* DMA callback for endpoint 2*/
static void USB_DMA_Callback_EP2(void)
{
	kal_uint32 ep_num = 2;
	usb_dma_callback callback = g_UsbDrvInfo.dma_callback[ep_num-1];

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	kal_uint32 		fm_dma_index;

	g_UsbDrvInfo.dma_tx_ep = 0;

	if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
		fm_dma_index = VUSB_FM_DMA_TX2;
	else
		fm_dma_index = VUSB_FM_DMA_RX2;

	/* disable DMA*/
	DRV_WriteReg8(USB_DMA_DIS, 1<<fm_dma_index);
#endif

	g_UsbDrvInfo.dma_callback[ep_num-1] = NULL;

	/* the last one pkt length not multiple of MAX_PKT_LEN, clear corresponding bits*/	
	if (g_UsbDrvInfo.dma_pktrdy[ep_num-1])
	{
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))	
		if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
	{
			/* tx, config the last one packet */
			/* tx, config the last one packet */
			WRITE_EPN_BDT_PID(ep_num, USB_BDT_TX, 
									(g_UsbDrvInfo.dma_pktlength[ep_num-1] << VUSB_BDT_BC_SHIFT) |
									(g_UsbDrvInfo.ep_in_data01[ep_num-1]<<VUSB_BDT_DATA01_SHIFT) |
									VUSB_BDT_DTS_BIT | VUSB_BDT_OWNS_BIT);
			g_UsbDrvInfo.ep_in_data01[ep_num-1]^=1;
		}
		else
		{
			/* rx, the last one already recevd*/
			/* nothing need to do */
		}
#else		
		if(g_UsbDrvInfo.dma_dir[ep_num-1] == USB_IN_EP_TYPE)
			USB_EP_Bulk_In_Ready(ep_num);
		else
			USB_EP_Bulk_Out_Ready(ep_num);
#endif		
	}

	g_UsbDrvInfo.dma_pktrdy[ep_num-1] = KAL_FALSE;

	/* if application callback function dose not request to clear drv_runnung set by itself, clear running state here*/
	if(g_UsbDrvInfo.dma_callback_upd_run[ep_num-1] == KAL_FALSE)
		g_UsbDrvInfo.dma_running[ep_num-1] = KAL_FALSE;

#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	if((g_UsbDrvInfo.dma_res_tx_ep==0)&&(g_UsbDrvInfo.fast_mode_tx_ep==0)&&(callback!=NULL))
	{
		callback();
	}
	else
	{
		//re-save callbcak function, wait until fast mode complete intr or the last pkt token done intr
		g_UsbDrvInfo.dma_callback[ep_num-1] = callback;	
	}
#else
	if(callback != NULL)
		callback();
#endif
}
#endif /* USB_SUPPORT_MUTIPLE_APP */


/* DMA setup function. 
The last one "callback_upd_run" parameter true => application decides to clear "driver dma running status" by itself*/
void USB_DMA_Setup(kal_uint8 ep_num, USB_EP_TYPE  type, kal_uint32 addr, kal_uint32 length, 
						usb_dma_callback callback, kal_bool callback_upd_run)
{
	DMA_INPUT		dma_input;
   	DMA_HWMENU	dma_menu;
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
	kal_uint32		fm_ep;
	kal_uint32		fm_pkt_num;
	kal_uint32		fm_dma_index;
#endif

   	if(ep_num>MAX_DMA_EP_NUM)
		EXT_ASSERT(0, ep_num, 0, 0);

	ASSERT(g_UsbDrvInfo.dma_running[ep_num - 1]==KAL_FALSE);
	g_UsbDrvInfo.dma_running[ep_num - 1] = KAL_TRUE;
	
	ASSERT(g_UsbDrvInfo.dma_port[ep_num - 1] !=0);

	g_UsbDrvInfo.dma_callback[ep_num - 1] = callback;
	g_UsbDrvInfo.dma_callback_upd_run[ep_num - 1] = callback_upd_run;
	g_UsbDrvInfo.dma_dir[ep_num - 1] = type;
   	
	/*DMA_CONFIG*/
	/* single mode */
	dma_menu.TMOD.burst_mode = 0;
	if (ep_num == 1)
	{
		if(type==USB_IN_EP_TYPE)
		{
			dma_menu.master = DMA_USB1TX; 
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
			fm_dma_index = VUSB_FM_DMA_TX1;
			g_UsbDrvInfo.fast_mode_tx_ep = 1;
			g_UsbDrvInfo.dma_res_tx_ep = 1;
			g_UsbDrvInfo.dma_tx_ep = 1;
#endif
		}
		else
		{
			dma_menu.master = DMA_USB1RX; 
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
			fm_dma_index = VUSB_FM_DMA_RX1;
#endif			
		}
		dma_input.callback = USB_DMA_Callback_EP1;
	}
#ifdef USB_SUPPORT_MUTIPLE_APP	
	else if (ep_num == 2)
	{
		if(type==USB_IN_EP_TYPE)
		{
			dma_menu.master = DMA_USB2TX; 
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
			fm_dma_index = VUSB_FM_DMA_TX2;
			g_UsbDrvInfo.fast_mode_tx_ep = 2;
			g_UsbDrvInfo.dma_res_tx_ep = 2;
			g_UsbDrvInfo.dma_tx_ep = 2;
#endif
		}
		else
		{
			dma_menu.master = DMA_USB2RX; 
#if ( defined(MT6228) || defined(MT6229) || defined(MT6230))
			fm_dma_index = VUSB_FM_DMA_RX2;
#endif			
		}
		dma_input.callback = USB_DMA_Callback_EP2;
	}
#endif /* USB_SUPPORT_MUTIPLE_APP*/	
	else
		EXT_ASSERT(0, ep_num, 0, 0);
	
	dma_menu.addr = (kal_uint32)addr;

	/* half channel */
	if(type==USB_IN_EP_TYPE)
		dma_input.type = DMA_HWTX;
	else
		dma_input.type = DMA_HWRX;
	dma_input.menu = &dma_menu;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?