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