/******************************************************************************* | |
* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£ | |
* | |
* ÎļþÃû³Æ£º drv_usb3slave.c | |
* Îļþ±êʶ£º | |
* ÄÚÈÝÕªÒª£º | |
* ÆäËü˵Ã÷£º zx297520 project | |
* µ±Ç°°æ±¾£º 1.0 | |
* ×÷¡¡¡¡Õߣº tangjian | |
* Íê³ÉÈÕÆÚ£º | |
* | |
* | |
*******************************************************************************/ | |
/* | |
**================================================================== | |
** Include files | |
**================================================================== | |
*/ | |
#include <commond.h> | |
#include "drv_usb3slave.h" | |
#include "config.h" | |
#include <asm/string.h> | |
/*zloader±àÒëÑ¡ÏîΪnostdlib,ÆÁ±ÎµôÏÂÃæµÄÍ·Îļþ*/ | |
//#include <stdlib.h> | |
//#include <string.h> | |
/* | |
**================================================================== | |
** Global Variables | |
**================================================================== | |
*/ | |
/* Èí¼þÓÃÀ´¼Ç¼ËùÓÐdeviceÏà¹ØµÄÐÅÏ¢µÄÈ«¾Ö½á¹¹Ìå*/ | |
extern __align(4) dwc_device_descriptor_t Para_Section device_desc ; | |
extern __align(4) dwc_config_all_t Para_Section desc ; | |
extern __align(4) dwc_string_descriptor_t Para_Section * pStrDescIdx[] ; | |
extern __align(4) dwc_dev_qual_descriptor_t Para_Section dev_qual_desc ; | |
__align(EVENT_BUFFERS_SIZE*4) T_USB3Slave_EventBuf Para_Section *gp_USB3Slave_EventBuf; //EventBufÒÔEVENT_BUFFERS_SIZE*4×Ö½Ú¶ÔÆë | |
__align(16) T_USB3Slave_TRBToHW Para_Section USB3Slave_TRB ; //TRBÒÔ16×Ö½Ú¶ÔÆë | |
__align(16) T_USB3Slave_TRBToHW Para_Section USB3Slave_TRB_EP[4] ; //TRBÒÔ16×Ö½Ú¶ÔÆë | |
__align(16) T_USB3Slave_CtrlReq Para_Section pCtrlReq ; /**< ¿ØÖÆÇëÇó */ | |
T_USB3Slave_SlaveObj Para_Section g_USB3Slave={0}; | |
u8 g_needSetStall = 0; | |
u32 g_debugFaultVal = 0; | |
__align(EVENT_BUFFERS_SIZE*4) T_USB3Slave_EventBuf Para_Section USB3Slave_EventBuf; //EventBufÒÔEVENT_BUFFERS_SIZE*4×Ö½Ú¶ÔÆë | |
extern void usb_timeout_usdelay(u32 us); | |
#if 0 | |
static inline void delay(unsigned long loops) | |
{ | |
/* | |
__asm__ volatile ("1:\n" "subs %0, %1, #1\n" | |
"bne 1b":"=r" (loops):"0"(loops)); | |
*/ | |
} | |
static inline void udelay(unsigned long us) | |
{ | |
delay(us * 200); /* approximate */ | |
} | |
void usdelay(unsigned us) | |
{ | |
udelay(us); | |
} | |
#endif | |
static T_USB3Slave_Ep *USB3Slave_GetEpObj(T_USB3Slave_SlaveObj *ptUsb3Slave, u16 uwIndex_le) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udEpnum; | |
udEpnum = (uwIndex_le & USB_ENDPOINT_NUMBER_MASK) << 1; | |
if ( USB_DIR_IN == (uwIndex_le & USB_ENDPOINT_DIR_MASK)) | |
udEpnum |= 1; | |
ptDep = &(ptUsb3Slave->tEps[udEpnum]); | |
/*if (ptDep->udFlags & EP_ENABLED)*/ | |
return (T_USB3Slave_Ep*)ptDep; | |
//return (T_USB3Slave_Ep*)NULL; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief Ïò¶ËµãдÃüÁîµÄͨÓú¯Êý | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_SendDevEpCmd º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - Ïò¶ËµãдÃüÁîµÄͨÓú¯Êý | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: usb3 É豸½á¹¹Ìå | |
* - udEp: ¶ËµãºÅ | |
* - udCmd: ÃüÁî,ÊÇÓÉDEPCMD¼Ä´æÆ÷µÄCmdTypÓò·¢ÆðµÄ¡£ | |
* -00h: Reserved | |
* -01h: Set Endpoint Configuration | |
* -02h: Set Endpoint Resource Configuration | |
* -03h: Get Endpoint State | |
* -04h: Set Stall | |
* -05h: Clear Stall | |
* -06h: Start Transfer | |
* -07h: Update Transfer | |
* -08h: End Transfer | |
* -09h: Start New Configuration | |
* - ptParams: ÃüÁî²ÎÊý | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_SendDevEpCmd(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udEp, | |
u32 udCmd, T_USB3Slave_EpCmdPara *ptParams) | |
{ | |
volatile u32 udTimeout = 500; | |
u32 udRegValue; | |
REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR0(udEp)) = ptParams->Parameter0; | |
REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR1(udEp)) = ptParams->Parameter1; | |
REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR2(udEp)) = ptParams->Parameter2; | |
REG32(ptUsb3Slave->udRegs_base + DEPCMD(udEp)) = udCmd | USB3Slave_DEPCMD_CMDACT_1; | |
// Ïòcmd¼Ä´æÆ÷µÚ10λд1ºó(command active)£¬¿ØÖÆÆ÷»á×Ô¶¯°Ñ¸ÃλÖÃ0 | |
do | |
{ | |
udRegValue = REG32(ptUsb3Slave->udRegs_base + DEPCMD(udEp)); | |
if(!(udRegValue & USB3Slave_DEPCMD_CMDACT_1)) break; | |
udTimeout--; | |
if(!udTimeout) | |
{ | |
return ERR_FAIL; | |
} | |
} while(1); | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief TRB½á¹¹ÌåλÓòÐÎʽת»»³ÉTRBÕûÌå½á¹¹ÌåÐÎʽ£¬±ãÓÚ¶ÔTRBÕûÌå²Ù×÷¡£ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_TrbToHWº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - TRB½á¹¹ÌåλÓòÐÎʽת»»³ÉTRB½á¹¹ÌåÕûÌåÐÎʽ£¬±ãÓÚ¶ÔTRBÕûÌå²Ù×÷¡£ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptTrbBit: TRBλÓòÐÎʽ½á¹¹Ìå | |
* - ptTrbRaw: TRB ÕûÌå½á¹¹ÌåÐÎʽ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_TrbToHW(T_USB3Slave_TRB *ptTrbBit, T_USB3Slave_TRBToHW *ptTrbRaw) | |
{ | |
ptTrbRaw->udBpl = ptTrbBit->bplh & DATA_32BIT_MASK; | |
ptTrbRaw->udBph = 0; | |
ptTrbRaw->udSize = ptTrbBit->len_pcm.udVal; | |
/* HWO is written last */ | |
ptTrbRaw->udCtrl = ptTrbBit->control.udVal; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÔÚ¿ªÊ¼ÅäÖÃ֮ǰ£¬ÒªÏȸøep0дÃüÁî9:¿ªÊ¼ÐµÄÅäÖÃstart new configuration | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_StartCfg º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÔÚ¿ªÊ¼ÅäÖÃ֮ǰ£¬ÒªÏȸøep0дÃüÁî9£¬´ËÃüÁî²ÎÊýΪ0 | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: usb 3.0É豸½á¹¹Ìå | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_StartCfg(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep) | |
{ | |
T_USB3Slave_EpCmdPara tParams = {0}; | |
u32 udCmd; | |
/* ÏòDEPCMD дÃüÁî9 */ /*Ö´ÐÐCMD9£¬Ôڶ˵ã0ºÍ2µÄÇé¿ö£¬Ò»°ãÖ»Ôڶ˵ã0£¬¶Ëµã2ÓеãÑо¿*/ | |
if (0 == ptDep->udEpNum) | |
{ | |
udCmd = USB3Slave_DEPCMD_DEPSTARTCFG; | |
return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum, udCmd, &tParams); | |
} | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¶Ô¶Ëµã½øÐÐÅäÖà | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_SetEpCfgCmdº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¶Ô¶Ëµã½øÐÐÅäÖà | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_SetEpCfgCmd(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep) | |
{ | |
T_USB3Slave_EpCmdPara tParams = {0}; | |
if((0 == ptDep->udEpNum)||(1 == ptDep->udEpNum)) | |
ptDep->ucType = USB_ENDPOINT_XFER_CONTROL; //¼Ç¼¶ËµãµÄ´«ÊäÀàÐÍ | |
else | |
ptDep->ucType = USB_ENDPOINT_XFER_BULK; | |
tParams.Parameter0 = DEPCFG_EP_TYPE(ptDep->ucType & USB_ENDPOINT_XFERTYPE_MASK) \ | |
| DEPCFG_MAX_PACKET_SIZE(ptDep->udMaxPacket & 0xffff) | |
| DEPCFG_BURST_SIZE(ptDep->udMaxBurst); | |
/* | |
* We must use the lower 16 TX FIFOs even though | |
* HW might have more | |
*/ | |
if (ptDep->udDirection) | |
tParams.Parameter0 |= DEPCFG_FIFO_NUMBER(ptDep->udEpNum >> 1); | |
if((0 == ptDep->udEpNum)||(1 == ptDep->udEpNum)) | |
tParams.Parameter1 = DEPCFG_XFER_COMPLETE_EN | DEPCFG_XFER_NOT_READY_EN; | |
else | |
tParams.Parameter1 = DEPCFG_XFER_COMPLETE_EN; | |
/* | |
* We are doing 1:1 mapping for endpoints, meaning | |
* Physical Endpoints 2 maps to Logical Endpoint 2 and | |
* so on. We consider the direction bit as part of the physical | |
* endpoint number. So USB endpoint 0x81 is 0x03. | |
*/ | |
tParams.Parameter1 |= DEPCFG_EP_NUMBER(ptDep->udEpNum); | |
return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum, | |
USB3Slave_DEPCMD_SETEPCONFIG, &tParams); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief Ϊÿ¸ö¶ËµãÉèÖô«Êä×ÊÔ´¸öÊý | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_SetXferResourceº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - Ϊÿ¸ö¶ËµãÉèÖô«Êä×ÊÔ´¸öÊý | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_SetXferResource(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep) | |
{ | |
T_USB3Slave_EpCmdPara tParams; | |
memset(&tParams, 0x00, sizeof(tParams)); | |
tParams.Parameter0 = DEPXFERCFG_NUM_XFER_RES(1); | |
/* ÉèÖô«Êä×ÊÔ´*/ | |
return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum, | |
USB3Slave_DEPCMD_SETTRANSFRESOURCE, &tParams); | |
} | |
/** | |
* __dwc3_gadget_ep_enable - Initializes a HW endpoint | |
* @ptDep: endpoint to be initialized | |
* @ptDesc: USB Endpoint Descriptor | |
* | |
* Caller should take care of locking | |
*/ | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ³õʼ»¯Ò»¸öÓ²¼þ¶Ëµã£¬°üÀ¨¿ªÊ¼ÅäÖá¢Èý²ÎÅäÖᢴ«Êä×ÊÔ´ÅäÖã¬Èí¼þtrbÉèÖø³Öµµ½Ó²¼þÉ豸trbÖÐ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_CfgEpº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ʹÄÜÒ»¸öÓ²¼þ¶Ëµã£¬°üÀ¨¿ªÊ¼ÅäÖá¢Èý²ÎÅäÖᢴ«Êä×ÊÔ´ÅäÖã¬Èí¼þtrbÉèÖø³Öµµ½Ó²¼þÉ豸trbÖÐ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptDep: ³õʼ»¯¶Ëµã£¬¶ËµãÐÅÏ¢½á¹¹Ìå | |
* - ptDesc: USB ¶ËµãÃèÊö·û | |
* - ptComp_desc: ¶Ëµãcompanion ÃèÊö·û | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_CfgEp(T_USB3Slave_Ep *ptDep) | |
{ | |
T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave; | |
if (!(ptDep->udFlags & EP_ENABLED)) | |
{ | |
//step0:ep0¶ËµãÅäÖÿªÊ¼£¬Ö´ÐÐcmd=9£¬start new conguration | |
USB3Slave_StartCfg(pUSB3Slv, ptDep); | |
} | |
//step1:Ö´ÐÐcmd1£¬SET EP CONFIG | |
USB3Slave_SetEpCfgCmd(pUSB3Slv, ptDep); | |
//step2:Ö´ÐÐcmd2£¬Set Endpoint Transfer Resource Configuration £¬param0 = 1 | |
if (!(ptDep->udFlags & EP_ENABLED)) | |
{ | |
USB3Slave_SetXferResource(pUSB3Slv, ptDep); | |
ptDep->udFlags |= EP_ENABLED; | |
if(global.need_enum ==1) | |
{ | |
//step3:active ep ,0xc720 £¬Ò»¸ö¶Ëµã¶ÔÓÚÒ»¸öbit | |
REG32(pUSB3Slv->udRegs_base + DWC3_DALEPENA)|= (1u<<ptDep->udEpNum); | |
} | |
} | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ep0·¢ËÍÊý¾Ý | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0StartXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ep0·¢ËÍÊý¾Ý | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÀàÐÅÏ¢µÄ½á¹¹Ìå | |
* - ucEpnum: ¶ËµãºÅ | |
* - udBufAddr: ÊäÈëµØÖ· | |
* - udLen: ³¤¶È | |
* - udType: TRB¿ØÖÆÀàÐÍ | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ÀàÐÍÂë | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0StartXfer(T_USB3Slave_SlaveObj *ptUsb3Slave, u8 ucEpnum, u32 udBufAddr, | |
u32 udLen, u32 udType) | |
{ | |
T_USB3Slave_EpCmdPara tParams; | |
T_USB3Slave_TRBToHW *ptTrbRaw; | |
T_USB3Slave_TRB tTrbBit; | |
T_USB3Slave_Ep *ptDep; | |
ptDep = &(ptUsb3Slave->tEps[ucEpnum]); | |
ptUsb3Slave->ptEp0TRB = ptDep->ptTRB; | |
ptTrbRaw = ptUsb3Slave->ptEp0TRB; | |
memset(&tTrbBit, 0, sizeof(tTrbBit)); | |
tTrbBit.control.bit.TRBCTL = udType; | |
tTrbBit.bplh =udBufAddr ; | |
tTrbBit.len_pcm.bit.BUFSIZ = udLen; | |
tTrbBit.control.bit.HWO = 1; | |
tTrbBit.control.bit.LST = 1; | |
/*tTrbBit.control.bit.IOC = 1; | |
tTrbBit.control.bit.ISP_IMI = 1;*/ | |
USB3Slave_TrbToHW(&tTrbBit, ptTrbRaw); | |
memset(&tParams, 0, sizeof(tParams)); | |
tParams.Parameter0 = 0; /*tTrbBit¸ß32λµØÖ·£¬Ä¬ÈÏΪ0*/ | |
tParams.Parameter1 = (u32)((u32)(ptUsb3Slave->ptEp0TRB)& (u32)0xFFFFFFFF);/* ys */ | |
USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum, | |
USB3Slave_DEPCMD_STARTTRANSFER, &tParams); | |
ptDep->udFlags |= EP_BUSY; | |
//»ñµÃ´«Êä×ÊÔ´Ë÷Òý | |
ptDep->ucResTransIdx = (REG32(ptUsb3Slave->udRegs_base + ((u32)DEPCMD(ptDep->udEpNum)>>16))); | |
ptUsb3Slave->eEp0NextEvent = EP0_COMPLETE; | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ch 9.4.5,״̬½×¶Î·µ»ØµÄÊý¾Ý | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0HandleStatusº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ch 9.4.5,״̬½×¶Î·µ»ØµÄÊý¾Ý | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÀàÐÅÏ¢µÄ½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0HandleStatus(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udRetVal,udRecip; | |
u16 uwUsb_status = 0; | |
u16 *puwResponse_pkt; | |
u32 udDirection; | |
udRecip = ptCtrlReq->bmRequestType & USB_RECIP_MASK; | |
switch (udRecip) | |
{ | |
case USB_RECIP_DEVICE: | |
{ | |
/* | |
* We are self-powered. U1/U2/LTM will be set later | |
* once we handle this states. RemoteWakeup is 0 on SS | |
*/ | |
uwUsb_status |= ptUsb3Slave->udIsSelfPowered << USB_DEVICE_SELF_POWERED; | |
break; | |
} | |
case USB_RECIP_INTERFACE: | |
{ | |
/* | |
* Function Remote Wake Capable D0 | |
* Function Remote Wakeup D1 | |
*/ | |
break; | |
} | |
case USB_RECIP_ENDPOINT: | |
{ | |
ptDep = USB3Slave_GetEpObj(ptUsb3Slave, ptCtrlReq->wIndex); | |
if (!ptDep) | |
return ERR_INVPARAMS; | |
if (ptDep->udFlags & EP_STALL) | |
uwUsb_status = 1 << USB_ENDPOINT_HALT; | |
break; | |
} | |
default: | |
{ | |
return ERR_INVPARAMS; | |
} | |
}; | |
puwResponse_pkt = (u16 *) ptUsb3Slave->aucSetupBuf; | |
*puwResponse_pkt = uwUsb_status; | |
ptDep = &(ptUsb3Slave->tEps[0]); | |
udDirection = ptDep->udFlags & EP0_DIR_IN; | |
if (ptUsb3Slave->eEp0State != EP0_DATA_PHASE) //ÕâÀïµÈ´ýµÄ״̬¿ÉÄÜÓÐÎÊÌ⣬ÓдýÑо¿£¬pxp | |
{ | |
return 0; | |
} | |
udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection, | |
(u32)ptUsb3Slave->aucSetupBuf, sizeof(*puwResponse_pkt), | |
TRBCTL_CONTROL_DATA); | |
ptDep->udFlags &= ~(EP_PENDING_REQUEST | EP0_DIR_IN); | |
return udRetVal; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÉèÖÃhaltÌØÐÔ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EpSetHaltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÉèÖÃhaltÌØÐÔ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* - udValue: 0ʱÇå³ýstallÌØÐÔ£¬1ʱÉèÖÃstallÌØÐÔ | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_EpSetHalt(T_USB3Slave_Ep *ptDep, u32 udValue) | |
{ | |
T_USB3Slave_EpCmdPara tParams; | |
T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave; | |
u32 udRetVal; | |
memset(&tParams, 0x00, sizeof(tParams)); | |
if (udValue) | |
{ | |
if (0 == ptDep->udEpNum || 1 == ptDep->udEpNum) | |
{ | |
/* | |
* Whenever EP0 is stalled, we will restart | |
* the state machine, thus moving back to | |
* Setup Phase | |
*/ | |
pUSB3Slv->eEp0State = EP0_SETUP_PHASE; | |
} | |
printf("USB3Slave_EpSetHalt"); | |
// udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum, | |
// USB3Slave_DEPCMD_CLEARSTALL, &tParams); | |
if(((global.need_enum ==0) || (1 == g_USB3Slave.udUSBSate))&&g_needSetStall!=1) | |
{ | |
udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum, | |
USB3Slave_DEPCMD_CLEARSTALL, &tParams); | |
} | |
else | |
{ | |
g_needSetStall = 0; | |
pUSB3Slv->eEp0NextEvent = EP0_COMPLETE; | |
udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum, | |
USB3Slave_DEPCMD_SETSTALL, &tParams); | |
USB3Slave_Ep0StartXfer(pUSB3Slv, 0, (u32)(pUSB3Slv->tCtrlReq), 8, | |
TRBCTL_CONTROL_SETUP); | |
} | |
} | |
return udRetVal; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÉèÖÃep0ÌØÐÔ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0HandleFeatureº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÉèÖÃep0ÌØÐÔ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢µÄ½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* - udSet: 1ʱÉèÖÃÌØÐÔ£¬0ʱÇå³ýÌØÐÔ | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0HandleFeature(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udSet) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udRecip; | |
u32 udIndex; | |
u32 udRet; | |
udIndex = ptCtrlReq->wIndex; | |
udRecip = ptCtrlReq->bmRequestType & USB_RECIP_MASK; | |
switch (udRecip) | |
{ | |
case USB_RECIP_ENDPOINT: | |
{ | |
ptDep = USB3Slave_GetEpObj(ptUsb3Slave, udIndex); | |
if (!ptDep) | |
return ERR_INVPARAMS; | |
udRet = USB3Slave_EpSetHalt(ptDep, udSet); | |
if (udRet) | |
return ERR_INVPARAMS; | |
break; | |
} | |
default: | |
return ERR_INVPARAMS; | |
}; | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÉèÖÃep0µØÖ· | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0SetAddrº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÉèÖÃep0µØÖ· | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0SetAddr(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq) | |
{ | |
u32 udAddr; | |
u32 udRegVal; | |
udAddr = ptCtrlReq->wValue; | |
udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG); | |
udRegVal &= ~(DWC3_DCFG_DEVADDR_MASK); | |
udRegVal |= DWC3_DCFG_DEVADDR(udAddr); | |
REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG) = udRegVal; | |
if (udAddr) | |
ptUsb3Slave->eDevState = ADDRESS_STATE; | |
else | |
ptUsb3Slave->eDevState = DEFAULT_STATE; | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief »ñÈ¡É豸ÃèÊö·û£¬ÉèÖÃÃèÊö·ûÁôÓнӿڣ¬µ«Ôݲ»ÊµÏÖ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0HandleDescº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - »ñÈ¡É豸ÃèÊö·û£¬ÉèÖÃÃèÊö·ûÁôÓнӿڣ¬µ«Ôݲ»ÊµÏÖ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* - udIsSet: | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0HandleDesc(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udIsSet) | |
{ | |
u32 udLen = 0; | |
u32 udDirection = 0; | |
u16 uwValue = ptCtrlReq->wValue; | |
u8 ucIdx =(u8)(ptCtrlReq->wValue &0xff); | |
u32 udRetVal = 0; | |
T_USB3Slave_Ep * ptDep = &ptUsb3Slave->tEps[1]; | |
u16 temp = uwValue >> 8; | |
if( USB_DT_DEVICE == temp ) | |
{ | |
udDirection = 1; | |
udLen = MIN(sizeof(dwc_device_descriptor_t), ptCtrlReq->wLength); | |
udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection, | |
(u32)&device_desc, udLen, | |
TRBCTL_CONTROL_DATA); | |
ptUsb3Slave->eEp0State = EP0_DATA_PHASE; | |
} | |
else if( USB_DT_CONFIG == temp) | |
{ | |
udDirection = 1; | |
udLen = MIN(sizeof(dwc_config_all_t), ptCtrlReq->wLength); | |
udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection, | |
(u32)&desc, udLen, | |
TRBCTL_CONTROL_DATA); | |
ptUsb3Slave->eEp0State=EP0_DATA_PHASE; | |
} | |
else if( USB_DT_STRING == temp) | |
{ | |
udDirection = 1; | |
if(ucIdx > 5) | |
{ | |
USB3Slave_EpSetHalt(ptDep,1); | |
} | |
else | |
{ | |
udLen = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[ucIdx]))->bLength, ptCtrlReq->wLength); | |
udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection, | |
(u32)pStrDescIdx[ucIdx], udLen, | |
TRBCTL_CONTROL_DATA); | |
ptUsb3Slave->eEp0State=EP0_DATA_PHASE; | |
} | |
} | |
else if( USB_DT_DEVICE_QUALIFIER == temp) | |
{ | |
udDirection = 1; | |
udLen =MIN(sizeof(dwc_dev_qual_descriptor_t), ptCtrlReq->wLength); | |
udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection, | |
(u32)&dev_qual_desc, udLen, | |
TRBCTL_CONTROL_DATA); | |
ptUsb3Slave->eEp0State = EP0_DATA_PHASE; | |
} | |
else | |
{ | |
USB3Slave_EpSetHalt(ptDep,1); | |
} | |
return udRetVal; | |
} | |
/*¸Ãº¯Êý¾ßÌåʵÏÖÓдýÌÖÂÛ£¬pxp */ | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÉèÖÃep0ÅäÖÃ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0HandleCfgº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÉèÖÃep0ÅäÖÃ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* - udIsSet: | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0HandleCfg(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udIsSet) | |
{ | |
u32 udCfg; | |
udCfg = ptCtrlReq->wValue; | |
if (udIsSet && udCfg) | |
{ | |
ptUsb3Slave->eDevState = CONFIGURED_STATE; | |
REG32(ptUsb3Slave->udRegs_base + DWC3_DALEPENA) = 0x3f; | |
#if SIM_EN == EMULATION | |
REG32(ARM_PORTA)=0x30; | |
#endif | |
return SOK; | |
} | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ep0±ê×¼ÇëÇóÀàÐÍ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0Requestº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ep0±ê×¼ÇëÇóÀàÐÍ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý | |
* -bmRequestType: ¾ö¶¨Êý¾Ý´«Êä·½ÏòºÍ½ÓÊÕÕßÀàÐÍ¡£ | |
* -bRequest : ¾ßÌåÇëÇóÀàÐÍ¡£ | |
* -wValue : ×Ö³¤Óò,¸ù¾Ý²»Í¬µÄÇëÇóº¬Òå¸Ä±ä | |
* -wIndex : ×Ö³¤Óò,¸ù¾Ý²»Í¬µÄÇëÇóº¬Òå¸Ä±ä.µäÐÍÓÃÓÚ´«ËÍË÷Òý»òÆ«ÒÆ. | |
* -wLength : ÈçÓÐÊý¾Ý´«Ëͽ׶Î,´ËΪÊý¾Ý×Ö½ÚÊý. | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static u32 USB3Slave_Ep0Request(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq) | |
{ | |
u32 udRet = 0; | |
T_USB3Slave_Ep *ptDep0 = 0; | |
u8 temp = 0; | |
//tj Ôö¼ÓÅжÏbmRequestTypeÊÇ·ñΪ±ê×¼ÃüÁÈç¹û²»ÊÇ£¬Ö±½Ó»Østall | |
if(UT_GET_TYPE(ptCtrlReq->bmRequestType)!=UT_STANDARD) | |
{ | |
ptDep0 = USB3Slave_GetEpObj(ptUsb3Slave,ptCtrlReq->wIndex); | |
USB3Slave_EpSetHalt(ptDep0, 1); | |
printf"command err.\n"); | |
return 1; | |
} | |
temp = ptCtrlReq->bRequest; | |
if( USB_REQ_GET_STATUS == temp) | |
{ | |
printf("USB_REQ_GET_STATUS\n"); | |
udRet = USB3Slave_Ep0HandleStatus(ptUsb3Slave, ptCtrlReq); | |
} | |
else if(USB_REQ_CLEAR_FEATURE == temp) | |
{ | |
printf("USB_REQ_CLEAR_FEATURE\n"); | |
// udRet = USB3Slave_Ep0HandleFeature(ptUsb3Slave, ptCtrlReq, 0); | |
udRet = USB3Slave_Ep0HandleFeature(ptUsb3Slave, ptCtrlReq, 1); | |
} | |
else if( USB_REQ_SET_ADDRESS == temp) | |
{ | |
printf("USB_REQ_SET_ADDRESS\n"); | |
udRet = USB3Slave_Ep0SetAddr(ptUsb3Slave, ptCtrlReq); | |
} | |
else if( USB_REQ_GET_DESCRIPTOR == temp) | |
{ | |
printf("USB_REQ_GET_DESCRIPTOR\n"); | |
udRet = USB3Slave_Ep0HandleDesc(ptUsb3Slave, ptCtrlReq,0); | |
} | |
else if( USB_REQ_SET_CONFIGURATION == temp) | |
{ | |
printf("USB_REQ_SET_CONFIGURATION\n"); | |
udRet = USB3Slave_Ep0HandleCfg(ptUsb3Slave, ptCtrlReq,1); | |
} | |
else | |
{ | |
printf("USB3Slave_EpSetHalt\n"); | |
USB3Slave_EpSetHalt(ptDep0, 1); | |
} | |
return udRet; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ep0 setup ½×¶Î | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0InspectSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ep0 setup ½×¶Î | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0InspectSetup(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
u32 udRetVal = 0; | |
u16 uwLen = 0; | |
T_USB3Slave_CtrlReq *ptCtrlReq = (ptUsb3Slave->tCtrlReq); | |
uwLen = ptCtrlReq->wLength; | |
/*Èç¹ûÊý¾Ý³¤¶ÈΪ0£¬±íʾûÓÐÊý¾Ý½×¶Î,Á½¸ö½×¶Î£¬Èç¹ûÓÐÊý¾Ý½×¶Î£¬Èý¸ö½×¶Î*/ | |
if (!uwLen) | |
{ | |
ptUsb3Slave->udThreeStageSetup = FALSE; | |
ptUsb3Slave->udEp0ExpectIn = FALSE; | |
ptUsb3Slave->eEp0NextEvent = EP0_NRDY_STATUS; | |
} | |
else | |
{ | |
ptUsb3Slave->udThreeStageSetup = TRUE; | |
ptUsb3Slave->udEp0ExpectIn = !!(ptCtrlReq->bmRequestType & USB_DIR_IN); | |
ptUsb3Slave->eEp0NextEvent = EP0_NRDY_DATA; | |
} | |
printf("USB3Slave_Ep0Request\n"); | |
udRetVal = USB3Slave_Ep0Request(ptUsb3Slave,ptCtrlReq); | |
if (udRetVal == USB_GADGET_DELAYED_STATUS) | |
ptUsb3Slave->udDelayedStatus = TRUE; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ep0 data½×¶Î | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0CmpltDataº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ep0 data½×¶Î | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0CmpltData(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
/*bootÀïÃæÃ»ÓеȺò¶ÓÁУ¬ÕâÀïÔݲ»×öÈκδ¦Àí*/ | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ep0 status ½×¶Î£¬½áÊø±¾´Î¿ØÖÆ´«Ê䣬״̬»Ø¹é | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0CmpltRequestº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ep0 status ½×¶Î£¬½áÊø±¾´Î¿ØÖÆ´«Ê䣬״̬»Ø¹é | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0CmpltRequest(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
if(ptUsb3Slave->eDevState == CONFIGURED_STATE) | |
{ | |
ptUsb3Slave->udUSBSate = 1; | |
#if SIM_EN == EMULATION | |
REG32(ARM_PORTA)=0x31; | |
#endif | |
} | |
ptUsb3Slave->eEp0State = EP0_SETUP_PHASE; | |
USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8, | |
TRBCTL_CONTROL_SETUP); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ´¦Àíxfercompleteʼþ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0XferCmpltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ´¦Àíxfercompleteʼþ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
/*´¦Àíxfercompleteʼþ*/ | |
static void USB3Slave_Ep0XferCmplt(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
T_USB3Slave_Ep *ptDep = &(ptUsb3Slave->tEps[ptEpEvt->udEndpoint_number]); | |
ptDep->udFlags &= ~EP_BUSY; | |
ptUsb3Slave->udSetupPacketPending = 0; | |
switch (ptUsb3Slave->eEp0State) | |
{ | |
case EP0_SETUP_PHASE: | |
{ | |
USB3Slave_Ep0InspectSetup(ptUsb3Slave, ptEpEvt); | |
break; | |
} | |
case EP0_DATA_PHASE: | |
{ | |
USB3Slave_Ep0CmpltData(ptUsb3Slave, ptEpEvt); | |
break; | |
} | |
case EP0_STATUS_PHASE: | |
{ | |
USB3Slave_Ep0CmpltRequest(ptUsb3Slave, ptEpEvt); | |
break; | |
} | |
default: | |
{ | |
break; | |
} | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¿ªÊ¼´«Ê䣬¿ØÖƽ¨Á¢½×¶Î | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0OutStartº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¿ªÊ¼´«Ê䣬¿ØÖƽ¨Á¢½×¶ÎµÄͨÓÃ½Ó¿Ú | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0OutStart(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8, | |
TRBCTL_CONTROL_SETUP); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¿ØÖƽ¨Á¢½×¶ÎͨÓÃ½Ó¿Ú | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0DoCtrlSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¿ØÖƽ¨Á¢½×¶ÎͨÓÃ½Ó¿Ú | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0DoCtrlSetup(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
USB3Slave_Ep0OutStart(ptUsb3Slave); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¿ØÖÆ×´Ì¬½×¶Î£¬¿ªÊ¼´«Ê䣬ÕÙ»½¶Ëµã½á¹¹Ìå½øÐд¦Àí | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0DoCtrlStatusº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¿ØÖÆ×´Ì¬½×¶Î£¬¿ªÊ¼´«Ê䣬ÕÙ»½¶Ëµã½á¹¹Ìå½øÐд¦Àí | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - udEpnum: ¶ËµãºÅ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0DoCtrlStatus(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udEpnum) | |
{ | |
u32 udType; | |
T_USB3Slave_Ep *ptDep = &(ptUsb3Slave->tEps[udEpnum]); | |
/* È·¶¨¿ØÖÆ´«ÊäµÄ״̬ÀàÐÍ */ | |
udType = ptUsb3Slave->udThreeStageSetup ? TRBCTL_CONTROL_STATUS3 | |
: TRBCTL_CONTROL_STATUS2; | |
/* ·¢Æð¿ªÊ¼´«ÊäÃüÁµÈ´ýÖжϲúÉú */ | |
USB3Slave_Ep0StartXfer(ptUsb3Slave, ptDep->udEpNum, | |
(u32)(ptUsb3Slave->tCtrlReq), 0, udType); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¿ØÖÆÊý¾Ý½×¶Î | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0DoCtrlDataº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¿ØÖÆÊý¾Ý½×¶Î | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0DoCtrlData(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
if (ptEpEvt->udEndpoint_number) | |
ptUsb3Slave->tEps[ptEpEvt->udEndpoint_number].udFlags |= EP0_DIR_IN; | |
/* linuxÇý¶¯ÀﻹÊÇÈ¥ÅжÏÇëÇó¶ÓÁÐÊÇ·ñΪ¿Õ½øÐд¦Àí£¬ÂãÇýûÓÐÇëÇó¶ÓÁУ¬ÏÈ·Å×Å */ | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ´¦Àíxfernotreadyʼþ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0XferNotReadyº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ´¦Àíxfernotreadyʼþ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0XferNotReady(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
const T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
u8 usb3Event = 0; | |
T_USB3Slave_Ep * ptDep = &ptUsb3Slave->tEps[0]; | |
ptUsb3Slave->udSetupPacketPending = 1; | |
/* | |
* This part is very tricky: If we has just handled | |
* XferNotReady(Setup) and we're now expecting a | |
* XferComplete but, instead, we receive another | |
* XferNotReady(Setup), we should STALL and restart | |
* the state machine. | |
* | |
* In all other cases, we just continue waiting | |
* for the XferComplete event. | |
* | |
* We are a little bit unsafe here because we're | |
* not trying to ensure that last event was, indeed, | |
* XferNotReady(Setup). | |
* | |
* Still, we don't expect any condition where that | |
* should happen and, even if it does, it would be | |
* another error condition. | |
*/ | |
/* | |
if ((1 == ptUsb3Slave->udEventsequence) && (EP0_COMPLETE == ptUsb3Slave->eEp0NextEvent)) | |
{ | |
switch (ptEpEvt->EventStatus) | |
{ | |
case DEPEVT_STATUS_CONTROL_SETUP: | |
{ | |
IC_DBG(IC_DEBUG_INFO, "Unexpected XferNotReady(Setup)\n"); | |
break; | |
} | |
case DEPEVT_STATUS_CONTROL_DATA: | |
{ | |
IC_DBG(IC_DEBUG_INFO, "DEPEVT_STATUS_CONTROL_DATA: XferNotReady\n"); | |
break; | |
} | |
case DEPEVT_STATUS_CONTROL_STATUS: | |
break; | |
default: | |
IC_DBG(IC_DEBUG_INFO, "Uwaiting for XferComplete\n"); | |
} | |
return; | |
} | |
*/ | |
usb3Event = (u8)(ptEpEvt->EventStatus); | |
if (DEPEVT_STATUS_CONTROL_SETUP == usb3Event) | |
{ | |
printf("USB3Slave event DEPEVT_STATUS_CONTROL_SETUP\n"); | |
ptUsb3Slave->eEp0State = EP0_SETUP_PHASE; | |
USB3Slave_Ep0DoCtrlSetup(ptUsb3Slave, ptEpEvt); | |
} | |
else if (DEPEVT_STATUS_CONTROL_DATA == usb3Event) | |
{ | |
printf("USB3Slave event DEPEVT_STATUS_CONTROL_DATA\n"); | |
if ( ptUsb3Slave->eEp0NextEvent == EP0_COMPLETE) | |
{ | |
return; | |
} | |
ptUsb3Slave->eEp0State = EP0_DATA_PHASE; | |
USB3Slave_Ep0DoCtrlData(ptUsb3Slave, ptEpEvt); | |
} | |
else if (DEPEVT_STATUS_CONTROL_STATUS == usb3Event) | |
{ | |
printf("USB3Slave event DEPEVT_STATUS_CONTROL_STATUS\n"); | |
ptUsb3Slave->eEp0State = EP0_STATUS_PHASE; | |
USB3Slave_Ep0DoCtrlStatus(ptUsb3Slave, ptEpEvt->udEndpoint_number); | |
} | |
else if (DEPEVT_STATUS_STATUS_SETUP == usb3Event) | |
{ | |
printf("USB3Slave event DEPEVT_STATUS_STATUS_SETUP\n"); | |
g_needSetStall = 1; | |
USB3Slave_EpSetHalt(ptDep,1); | |
} | |
else | |
{ | |
g_debugFaultVal = ptEpEvt->EventStatus; | |
printf("USB3Slave event default\n"); | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ´¦Àíep0¿ØÖÆÖÐ¶Ï | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Ep0ISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ´¦Àí¿ØÖÆÖÐ¶Ï | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Ep0ISR(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
switch (ptEpEvt->udEndpoint_event) | |
{ | |
case DEPEVT_XFERCOMPLETE: | |
{ | |
USB3Slave_Ep0XferCmplt(ptUsb3Slave, ptEpEvt); | |
break; | |
} | |
case DEPEVT_XFERNOTREADY: | |
{ | |
USB3Slave_Ep0XferNotReady(ptUsb3Slave, ptEpEvt); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ָʾ´«ÊäÍê³É | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EpXferCmpltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ָʾ´«ÊäÍê³É | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* - udStart_new: | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_EpXferCmplt(T_USB3Slave_SlaveObj *ptUsb3Slave, | |
T_USB3Slave_Ep *ptDep, const T_USB3Slave_EpEvt *ptEpEvt,u32 udStart_new) | |
{ | |
u32 udXfercount; | |
T_USB3Slave_TRB *tTrbBit; | |
tTrbBit = (T_USB3Slave_TRB *)ptDep->ptTRB ; | |
udXfercount = ptDep->udLen - tTrbBit->len_pcm.bit.BUFSIZ; | |
if((0x0 == ptDep->udDirection) && (0x2 == ptDep->ucType)) | |
ptUsb3Slave->eDevState = BULKOUT_CMPL; | |
if((0x1 == ptDep->udDirection) && (0x2 == ptDep->ucType)) | |
ptUsb3Slave->eDevState = BULKIN_CMPL; | |
ptDep->udFlags &= ~EP_BUSY; | |
ptDep->ucResTransIdx = 0; | |
if(ptDep->fnUsbCb) | |
ptDep->fnUsbCb((u32)(ptDep->pPara), 0, udXfercount, ptDep->udLen); | |
} | |
static void USB3Slave_Init_TRB(T_USB3Slave_Ep *ptDep) | |
{ | |
T_USB3Slave_TRBToHW *ptTrbRaw; | |
T_USB3Slave_TRB tTrbBit; | |
ptTrbRaw = ptDep->ptTRB; | |
memset(&tTrbBit, 0, sizeof(tTrbBit)); | |
tTrbBit.control.bit.CHN = 0; | |
tTrbBit.control.bit.LST = 1; | |
tTrbBit.control.bit.TRBCTL = TRBCTL_NORMAL; | |
tTrbBit.control.bit.HWO = 1; | |
tTrbBit.len_pcm.bit.BUFSIZ = ptDep->udLen; | |
tTrbBit.bplh=(u64)(ptDep->pudAddrData); | |
USB3Slave_TrbToHW(&tTrbBit, ptTrbRaw); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EpStartXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå | |
* - uwCmd_param: ÃüÁî²ÎÊý | |
* - udStart_new: | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:INT | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
/*ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä*/ | |
static u32 USB3Slave_EpStartXfer(T_USB3Slave_Ep *ptDep, u16 uwCmd_param, | |
u32 udStart_new) | |
{ | |
T_USB3Slave_EpCmdPara tParams; | |
T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave; | |
u32 udCmd; | |
USB3Slave_Init_TRB(ptDep); //ÅäÖÃTRB | |
memset(&tParams, 0, sizeof(tParams)); | |
tParams.Parameter0 = 0; /*trb¸ß32λµØÖ·£¬Ä¬ÈÏΪ0*/ | |
tParams.Parameter1 = (u32)((u32)(ptDep->ptTRB)& (u32)0xFFFFFFFF);/* ys */ | |
if (udStart_new) | |
udCmd = USB3Slave_DEPCMD_STARTTRANSFER; | |
else | |
udCmd = USB3Slave_DEPCMD_UPDATETRANSFER; | |
udCmd |= USB2Slave_DEPCMD_PARAM(uwCmd_param); //0 | |
USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum, udCmd, &tParams); | |
return SOK; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¶ËµãÀàÐ͵ÄeventÖжϴ¦Àí³ÌÐò | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EpISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¶ËµãÀàÐ͵ÄeventÖжϴ¦Àí³ÌÐò | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEpEvt: ¶ËµãÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_EpISR(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_EpEvt *ptEpEvt) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u8 ucEpnum = ptEpEvt->udEndpoint_number; | |
ptDep = &(ptUsb3Slave->tEps[ucEpnum]); | |
if (0 == ucEpnum || 1 == ucEpnum) | |
{ | |
USB3Slave_Ep0ISR(ptUsb3Slave, ptEpEvt); | |
return; | |
} | |
switch (ptEpEvt->udEndpoint_event) | |
{ | |
case DEPEVT_XFERCOMPLETE: | |
{ | |
USB3Slave_EpXferCmplt(ptUsb3Slave, ptDep, ptEpEvt, 1); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief É豸¸´Î»Öжϴ¦Àí | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_ResetISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - É豸¸´Î»Öжϴ¦Àí | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_ResetISR(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
u32 udRegVal; | |
printf("R"); | |
//tangjian:±êÖ¾usbÁ¬½Ó | |
global.g_Connet = 1; | |
/* Reset device address to zero */ | |
udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG); | |
udRegVal &= ~(0x7f<<3); | |
REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG) = udRegVal; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief »ñÈ¡usb 3.0×ÜÏßʱÖÓ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_UpdateRamClkSelº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - »ñÈ¡usb 3.0×ÜÏßʱÖÓ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ucSpeed: ָʾÁ¬½ÓËÙ¶È | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_UpdateRamClkSel(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 ucSpeed) | |
{ | |
u32 udRegVal; | |
/* | |
* RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed | |
* each time on Connect Done. | |
*/ | |
/* ÅäÖÃGCTL¼Ä´æÆ÷,sel bus = 0*/ | |
udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_GCTL); | |
udRegVal &= ~(0x3<<6); | |
REG32(ptUsb3Slave->udRegs_base + DWC3_GCTL) = udRegVal; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief É豸Á¬½ÓÖжϴ¦Àí | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_ConnectdoneISR º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - É豸Á¬½ÓÖжϴ¦Àí | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÀàÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_ConnectdoneISR(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udRegVal; | |
u8 ucSpeed; | |
printf("D"); | |
udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DSTS); | |
ucSpeed = udRegVal&0x7; | |
ptUsb3Slave->ucSpeed = ucSpeed; | |
USB3Slave_UpdateRamClkSel(ptUsb3Slave, ucSpeed); | |
if(USB3_HIGHSPEED == ucSpeed) | |
{ | |
printf("2"); | |
ptUsb3Slave->tEps[2].udMaxPacket = 512; | |
ptUsb3Slave->tEps[3].udMaxPacket = 512; | |
ptUsb3Slave->tEps[4].udMaxPacket = 512; | |
ptUsb3Slave->tEps[5].udMaxPacket = 512; | |
ptUsb3Slave->eDeviceSpeedType = USB30_SPEED_HIGH; | |
desc.atTxEP[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE; | |
desc.atRxEP[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE; | |
desc.atTxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE; | |
desc.atRxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE; | |
} | |
else if(USB3_FULLSPEED == ucSpeed) | |
{ | |
printf("1"); | |
ptUsb3Slave->tEps[2].udMaxPacket = 64; | |
ptUsb3Slave->tEps[3].udMaxPacket = 64; | |
ptUsb3Slave->tEps[4].udMaxPacket = 64; | |
ptUsb3Slave->tEps[5].udMaxPacket = 64; | |
ptUsb3Slave->eDeviceSpeedType = USB30_SPEED_FULL; | |
desc.atTxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE; | |
desc.atRxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE; | |
desc.atTxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE; | |
desc.atRxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE; | |
} | |
//tangjian:ÉèÖÃep0µÄ¶ËµãÐÅÏ¢ | |
ptDep = &(ptUsb3Slave->tEps[0]); | |
USB3Slave_SetEpCfgCmd(ptUsb3Slave, ptDep); | |
ptDep = &(ptUsb3Slave->tEps[1]); | |
USB3Slave_SetEpCfgCmd(ptUsb3Slave, ptDep); | |
#if SIM_EN == EMULATION | |
REG32(REG_GPIO_OUT)=5; | |
// while(REG32(REG_GPIO_IN)!=0xFF); | |
usdelay(1); | |
REG32(REG_GPIO_OUT)=0; | |
REG32(REG_GPIO_OUT)=6; | |
// while(REG32(REG_GPIO_IN)!=0xFF); | |
usdelay(1); | |
REG32(REG_GPIO_OUT)=0; | |
REG32(REG_GPIO_OUT)=7; | |
// while(REG32(REG_GPIO_IN)!=0xFF); | |
usdelay(1); | |
REG32(REG_GPIO_OUT)=0; | |
REG32(REG_GPIO_OUT)=8; | |
// while(REG32(REG_GPIO_IN)!=0xFF); | |
usdelay(1); | |
REG32(REG_GPIO_OUT)=0; | |
#endif | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief É豸Öжϴ¦Àí(¶Ï¿ª¡¢¸´Î»¡¢Á¬½Ó¡¢»½ÐÑ¡¢Á¬½Ó״̬¸Ä±ä¡¢EOPF¡¢ÃüÁîÍê³É¡¢Òç³ö¡¢´íÎó) | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_DevISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - É豸Öжϴ¦Àí(¶Ï¿ª¡¢¸´Î»¡¢Á¬½Ó¡¢»½ÐÑ¡¢Á¬½Ó״̬¸Ä±ä¡¢EOPF¡¢ÃüÁîÍê³É¡¢Òç³ö¡¢´íÎó) | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptDevEvt: É豸ÀàÐÍʼþ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_DevISR(T_USB3Slave_SlaveObj *ptUsb3Slave, const T_USB3Slave_DevEvt *ptDevEvt) | |
{ | |
switch (ptDevEvt->udType) | |
{ | |
case DEVICE_EVENT_RESET: | |
{ | |
USB3Slave_ResetISR(ptUsb3Slave); | |
break; | |
} | |
case DEVICE_EVENT_CONNECT_DONE: | |
{ | |
USB3Slave_ConnectdoneISR(ptUsb3Slave); | |
break; | |
} | |
case DEVICE_EVENT_EOPF: | |
{ | |
printf("S"); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ´¦Àí²»Í¬µÄÖжϺ¯ÊýÈë¿Ú | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_ProcessEvtEntryº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ´¦Àí²»Í¬µÄÖжϺ¯ÊýÈë¿Ú | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - ptEvt: ±íʾevent buffer ÄÚÈÝ | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_ProcessEvtEntry(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Event *ptEvt) | |
{ | |
/* Endpoint IRQ, handle it and return early */ | |
/*0bit 0ÊÇÉ豸¶ËµãÖÐ¶Ï 1ÊÇÉ豸ÖжÏ*/ | |
if (0 == ptEvt->tType.udIs_devspec) | |
USB3Slave_EpISR(ptUsb3Slave, &ptEvt->tEpEvt); /* tDepevt */ | |
else | |
USB3Slave_DevISR(ptUsb3Slave, &ptEvt->tDevEvt); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ´¦Àíevent buffer ÖеÄevent,·Ö·¢²»Í¬event bufferÖмǼµÄÖжϣ¬ÔÙµ÷ÓÃÕæÕýµÄÖжÏÈë¿Ú³ÌÐò | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_ProcessEvtBufº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ´¦Àíevent buffer ÖеÄevent,·Ö·¢²»Í¬event bufferÖмǼµÄÖжϣ¬ÔÙµ÷ÓÃÕæÕýµÄÖжÏÈë¿Ú³ÌÐò | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* - udBufNum: ±íʾevent bufferÖÐij¸öevent | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_ProcessEvtBuf(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udBufNum) | |
{ | |
T_USB3Slave_EventBuf *ptevt; | |
T_USB3Slave_Event ptEvt; | |
u32 udLeft; | |
u32 udCount; | |
//step0:ÔÚÖжϴ¦Àíº¯ÊýÖлñÈ¡event count£¬À´ÅжÏÓм¸¸öʼþ£¬²¢×÷ÏàÓ¦µÄ´¦Àí | |
udCount = REG32((ptUsb3Slave->udRegs_base + GEVNTCOUNT(udBufNum))); | |
if(!udCount) | |
return; | |
ptevt = ptUsb3Slave->ptEvtBuffs; | |
udLeft = udCount; | |
ptUsb3Slave->udEventsequence = 1;/* ys */ | |
//step1:´¦ÀíÏàÓ¦µÄʼþ | |
while (udLeft > 0) | |
{ | |
ptEvt.udRaw = ptevt->EvtBuf[ptevt->udLpos]; | |
USB3Slave_ProcessEvtEntry(ptUsb3Slave, &ptEvt); | |
/* | |
* XXX we wrap around correctly to the next entry as almost all | |
* entries are 4 bytes in size. There is one entry which has 12 | |
* bytes which is a regular entry followed by 8 bytes data. ATM | |
* I don't know how things are organized if were get next to the | |
* a boundary so I worry about that once we try to handle that. | |
*/ | |
ptevt->udLpos = (ptevt->udLpos + 1) % EVENT_BUFFERS_SIZE; | |
udLeft -= 4; | |
ptUsb3Slave->udEventsequence++; | |
} | |
/*When read, returns the number of valid events in the Event Buffer (in bytes). | |
When written, hardware decrements the count by the value written. | |
The interrupt line remains high when count is not 0.*/ | |
REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udBufNum)) = udCount; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÖжÏÈë¿Úº¯Êý | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_ISRº¯ÊýÊôÓÚ½Ó¿Úº¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÖжÏÈë¿Úº¯Êý | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - udIntNo: ÖжϺŠ| |
* - udPara: ÖжϲÎÊý | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
void USB3Slave_ISR(u32 udIntNo,u32 udPara) | |
{ | |
T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave; | |
u32 udIndex ; | |
for (udIndex = 0; udIndex < pUSB3Slv->udNumEvtBufs; udIndex++) | |
{ | |
USB3Slave_ProcessEvtBuf(pUSB3Slv,udIndex); | |
} | |
} | |
/*³õʼ»¯ÓÃÓڼǼÉ豸ËùÓÐÐÅÏ¢µÄÈ«¾Ö½á¹¹Ìå*/ | |
/*Ò»´ÎÐÔд²»ÍêÕû£¬ ÔÚ´úÂë²¹³äµÄ¹ý³ÌÖÐÂýÂýÌí¼Ó*/ | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ³õʼ»¯È«¾Ö½á¹¹ÌåptUsb3Slave | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Initº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ³õʼ»¯½á¹¹ÌåÄÚÈ«¾Ö±äÁ¿ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_Init(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
T_USB3Slave_HWPARAMS *parms = &ptUsb3Slave->tHwParams; | |
gp_USB3Slave_EventBuf = &USB3Slave_EventBuf; | |
ptUsb3Slave->udRegs_base = SYS_USB_BASE; | |
ptUsb3Slave->eSpeedMode = USB3_HIGHSPEED; | |
parms->udHwparams0 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS0); | |
parms->udHwparams1 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS1); | |
parms->udHwparams2 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS2); | |
parms->udHwparams3 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS3); | |
parms->udHwparams4 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS4); | |
parms->udHwparams5 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS5); | |
parms->udHwparams6 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS6); | |
parms->udHwparams7 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS7); | |
parms->udHwparams8 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS8); | |
ptUsb3Slave->udNumEvtBufs = (parms->udHwparams1&(0x3f<<15))>>15; //»ñÈ¡event_int_num | |
// if(global.need_enum ==0) | |
{ | |
gp_USB3Slave_EventBuf->udLength = EVENT_BUFFERS_SIZE*4; | |
gp_USB3Slave_EventBuf->udLpos = 0; | |
} | |
ptUsb3Slave->ptEvtBuffs = gp_USB3Slave_EventBuf; | |
ptUsb3Slave->tCtrlReq = &pCtrlReq; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EvtBufSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:INT | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_EvtBufSetup(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
T_USB3Slave_EventBuf *ptevt; | |
u32 udIndex = 0; | |
u32 udTemp_data;/*ÓÃÀ´±£´æµØÖ·µÄ*/ | |
ptevt = ptUsb3Slave->ptEvtBuffs; | |
udTemp_data = (u32)&ptevt->EvtBuf; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex)) = udTemp_data; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTADRHI(udIndex)) = 0; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex)) = ptevt->udLength & 0xffff; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) = ptevt->udLpos; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_EvtBufSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:INT | |
* - ´íÎóÂë | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_EvtBufRestore(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
/*T_USB3Slave_EventBuf *ptevt; | |
u32 udIndex = 0; | |
u32 udTemp_data; | |
ptevt = ptUsb3Slave->ptEvtBuffs; | |
udTemp_data = (u32)&ptevt->EvtBuf; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex)) = udTemp_data; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTADRHI(udIndex)) = 0; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex)) = ptevt->udLength & 0xffff; | |
REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) = ptevt->udLpos;*/ | |
u32 udRegVal; | |
u8 ucSpeed; | |
T_USB3Slave_EventBuf *ptevt; | |
u32 udIndex = 0; | |
ptevt = ptUsb3Slave->ptEvtBuffs; | |
ptUsb3Slave->ptEvtBuffs = (T_USB3Slave_EventBuf *)(REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex))); | |
ptevt->udLength =REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex)); | |
// ptevt->udLpos = REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) ; | |
ptUsb3Slave->tCtrlReq = (T_USB3Slave_CtrlReq *)(*(u32 *)(*(u32 *)(0x0200c804))); | |
udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DSTS); | |
ucSpeed = udRegVal&0x7; | |
ptUsb3Slave->ucSpeed = ucSpeed; | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ÅäÖö˵ã0£¬¿ªÊ¼µÈ´ý½øÐпØÖÆ´«Êä | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_StartCtrlXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ÅäÖö˵ã0£¬¿ªÊ¼µÈ´ý½øÐпØÖÆ´«Êä | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_StartCtrlXfer(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udIndex; | |
for (udIndex=0; udIndex < 2; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/ | |
{ | |
ptDep = &(ptUsb3Slave->tEps[udIndex]); | |
ptDep->ptTRB= &USB3Slave_TRB; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem | |
ptDep->udEpNum = udIndex; | |
if(global.need_enum ==1) | |
{ | |
USB3Slave_CfgEp(ptDep); | |
} | |
} | |
ptUsb3Slave->eEp0State = EP0_SETUP_PHASE; | |
//Ö´ÐÐcmd6±íʾstart transfer¡£ | |
USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8, TRBCTL_CONTROL_SETUP); | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ³õʼ»¯¶Ëµã½á¹¹Ì壬ÒÔ¼°¶ÔÓ¦¼Ä´æÆ÷ÅäÖÃ(¶ËµãºÅ£¬¶Ëµã״̬£¬´«Êä·½Ïò£¬°ü´óС) | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_InitEpº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ³õʼ»¯¶Ëµã½á¹¹Ì壬ÒÔ¼°¶ÔÓ¦¼Ä´æÆ÷ÅäÖÃ(¶ËµãºÅ£¬¶Ëµã״̬£¬´«Êä·½Ïò£¬°ü´óС) | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå | |
* | |
* ·µ »Ø Öµ: ÎÞ | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
static void USB3Slave_InitEp(T_USB3Slave_SlaveObj *ptUsb3Slave) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 udIndex; | |
/* u32 udFifoNum = 0,udTxfram_space; */ | |
for (udIndex = 0; udIndex < ENDPOINTS_NUM; udIndex++) | |
{ | |
ptDep = &(ptUsb3Slave->tEps[udIndex]); | |
ptDep->udEpNum = udIndex; | |
ptDep->eEpState = EP_IDLE; | |
ptDep->udFlags = 0; //tj add ¶¨ÒåflagĬÈÏΪ0 | |
ptDep->udMaxBurst = 0; //tj add ÓÃÓÚburst size 0-15 : 1-16 | |
ptDep->udDirection = udIndex & 1;/*¶¨Òå´«Êä·½Ïò*/ | |
if (0 == udIndex|| 1 == udIndex) | |
{ | |
ptDep->udMaxPacket = EP0_PACKET_SIZE;/*ÐÒ鹿¶¨¿ØÖÆ´«Êä×î´ó°ü´óС512*/ | |
} | |
else | |
{ | |
ptDep->udMaxPacket = HS_MAX_PACKET_SIZE; | |
} | |
} | |
} | |
/**-------------------------------------------------------------------------------------------------------------------@n | |
* @brief ³õʼ»¯¼Ä´æÆ÷ | |
* | |
* ¹¦ÄÜÏêÊö: | |
* - USB3Slave_Init º¯ÊýÊôÓÚ½Ó¿Úº¯Êý, Æä¹¦ÄÜÊÇ: | |
* - ³õʼ»¯¼Ä´æÆ÷ | |
* | |
* ²ÎÊý¸ÅÊö: | |
* - eUSBSpeedType: USB É豸ËÙ¶ÈÀàÐÍ | |
* | |
* ·µ »Ø Öµ: ÀàÐÍ:u32 | |
* - ´íÎóÂë | |
* | |
* ÆäËû˵Ã÷: | |
* - | |
* | |
*--------------------------------------------------------------------------------------------------------------------*/ | |
u32 USB3Slave_Ctrl_Init(void) | |
{ | |
u32 udRegValue, i = 0; | |
T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave; | |
//step0: ¶Ô½á¹¹Ìåg_USB3Slave½øÐи³Öµ | |
USB3Slave_Init(pUSB3Slv); | |
//step1:DCTL£¬¶Ô¿ØÖÆÆ÷½øÐÐÈí¸´Î» | |
if(global.need_enum ==1) | |
{ | |
REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) |= DWC3_DCTL_CSFTRST; | |
while(1) | |
{ | |
i++; | |
usdelay(10); | |
udRegValue =REG32(pUSB3Slv->udRegs_base + DWC3_DCTL); | |
if ((!(udRegValue & DWC3_DCTL_CSFTRST))||(i>0x1000))/*¸´Î»Íê±Ïºó¸Ãλ×Ô¶¯ÇåÁã*/ | |
break; | |
} | |
} | |
//step2:ÅäÖÃUSB2 PHY */ //0x0007a510 | |
/*bit3: 0:8bit 1:16bit | |
bit4: 0:utmi 1:ulpi | |
bit[13:10] 5:16bit utmi 9:8bit utim/ulpi*/ | |
if(global.need_enum ==1) | |
{ | |
#if(SIM_EN == FPGA) | |
#if (USB_PHY == ULPI) | |
udRegValue = 0x7a510|(1<<9); //0xf<<15+0x9<<10+0x1<<4+0x0<<3; | |
#elif (USB_PHY == UTMI) | |
udRegValue = 0x00001408|(1<<9);//0x0<<15|0x5<<10|0x0<<4+0x1<<3; | |
#endif | |
#elif ((SIM_EN == ASIC) || (SIM_EN == EMULATION)) | |
udRegValue = 0x00002400|(1<<9);//0x0<<15|0x9<<10|0x0<<4+0x0<<3; | |
#endif | |
REG32(pUSB3Slv->udRegs_base + DWC3_GUSB2PHYCFG(0)) = udRegValue; | |
//step3:DCTL£¬¶Ô¿ØÖÆÆ÷ÔٴνøÐÐÈí¸´Î» | |
REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) |= DWC3_DCTL_CSFTRST; | |
while(1) | |
{ | |
i++; | |
usdelay(10); | |
udRegValue =REG32(pUSB3Slv->udRegs_base + DWC3_DCTL); | |
if ((!(udRegValue & DWC3_DCTL_CSFTRST))||(i>0x1000))/*¸´Î»Íê±Ïºó¸Ãλ×Ô¶¯ÇåÁã*/ | |
break; | |
} | |
} | |
//step4:´Óparams1ÖлñÈ¡eventnum£¬Ó²¼þĬÈÏΪ1,ÅäÖÃevent_buffer | |
if(global.need_enum ==1) | |
{ | |
USB3Slave_EvtBufSetup(pUSB3Slv); | |
} | |
else | |
{ | |
USB3Slave_EvtBufRestore(pUSB3Slv); | |
} | |
//step5: ÅäÖüĴæÆ÷c110£¬°üº¬ÅäÖÃdev mode,ÅäÖÃc700,°üº¬high speed | |
if(global.need_enum ==1) | |
{ | |
udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_GCTL); | |
udRegValue = (udRegValue & 0xffff0000) | 0x200c;//ÔÀ´ÊÇ0x2008 scaledown | |
udRegValue = udRegValue & (~(1<<17)); // In the real hardware, this bit must be set to 1'b0 | |
udRegValue = udRegValue & (~(1<<16));//2012.11.9,never attempts three more times to connect at SS | |
#if SIM_EN == EMULATION | |
udRegValue = (udRegValue & 0xffff0000) | 0x2008; | |
udRegValue = udRegValue|(0x3<<4); //lanxiang scaledown | |
udRegValue = udRegValue|(1<<16); | |
#endif | |
REG32(pUSB3Slv->udRegs_base + DWC3_GCTL) = udRegValue; | |
udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DCFG); | |
udRegValue &= ~(DWC3_DCFG_SPEED_MASK); //0Ϊhigh speed | |
udRegValue &= (~(0x1f<<17)); | |
udRegValue |= pUSB3Slv->eSpeedMode | (1<<17) ; /*1×óÒÆ17ΪÀ´×ÔÑéÖ¤ÂãÇý£¬Óдý·ÖÎö£¬pxp*/ | |
REG32(pUSB3Slv->udRegs_base + DWC3_DCFG)= udRegValue; | |
} | |
pUSB3Slv->eDeviceSpeedType = USB30_SPEED_UNKNOWN; | |
//step6:³õʼ»¯EP¶Ëµã£¬bootÖÐÖ»Óõ½0£¬1£¬2£¬3£¬4£¬5£¬ÆäËüµÄ¿ÉÒÔ¿¼ÂDz»Òª¡£ | |
USB3Slave_InitEp(pUSB3Slv); | |
//step7:ÅäÖÃÖжÏ(reset , connect done)ʹÄÜ£¬ÈíÁ¬½Ó£¬µÚ31bitÅäÖÃΪrun | |
if(global.need_enum ==1) | |
{ | |
udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DEVTEN); | |
udRegValue = udRegValue | (DWC3_DEVTEN_CONNECTDONEEN | DWC3_DEVTEN_USBRSTEN|DWC3_DEVTEN_USBSUSPENDEN); | |
//udRegValue = udRegValue & (~(1<<6)) & (~(1<<7)); | |
REG32(pUSB3Slv->udRegs_base + DWC3_DEVTEN) = udRegValue; | |
} | |
//step8:start control tranfer | |
USB3Slave_StartCtrlXfer(pUSB3Slv); | |
if(global.need_enum ==1) | |
{ | |
//step9:run softconnect | |
udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DCTL); | |
udRegValue |= (1U<<31); //tj add 31bit for run or stop,correspond to softdisconnect | |
REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) = udRegValue; | |
#if SIM_EN == EMULATION | |
//for hsic | |
REG32(REG_GPIO_OUT)=2; | |
// while(REG32(REG_GPIO_IN)!=0xFF); | |
usdelay(1); | |
REG32(REG_GPIO_OUT)=0; | |
#endif | |
} | |
return SOK; | |
} | |
u32 USB3_RecvOutData(u32 dwEPNo, u8 *pchBuf, u32 dwLen, F_USB_CB fnUsbCb, void *pPara) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave; | |
ptDep = &(ptUsb3Slave->tEps[dwEPNo]); | |
ptDep->pudAddrData =(u32*)pchBuf; | |
ptDep->udLen = dwLen; | |
ptDep->fnUsbCb = fnUsbCb; | |
ptDep->pPara = pPara; | |
USB3Slave_EpStartXfer(ptDep, 0, 1); | |
#if SIM_EN == EMULATION | |
REG32(ARM_PORTA)=0x80; | |
#endif | |
return SOK; | |
} | |
u32 USB3_SendInData(u32 dwEPNo, u8 *pchBuf, u32 dwLen, F_USB_CB fnUsbCb, void *pPara) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave; | |
ptDep = &(ptUsb3Slave->tEps[dwEPNo]); | |
ptDep->pudAddrData = (u32*)pchBuf; | |
ptDep->udLen = dwLen; | |
ptDep->fnUsbCb = fnUsbCb; | |
ptDep->pPara = pPara; | |
USB3Slave_EpStartXfer(ptDep, 0, 1); | |
#if SIM_EN == EMULATION | |
REG32(ARM_PORTA)=0x82; | |
#endif | |
return SOK; | |
} | |
u32 USB3Slave_IsNeedZero(u32 dwLen) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave; | |
u32 udMaxPacket; | |
if (ptUsb3Slave->ucSpeed == USB3_HIGHSPEED) | |
{ | |
udMaxPacket = HS_MAX_PACKET_SIZE; | |
} | |
else if (ptUsb3Slave->ucSpeed == USB3_FULLSPEED) | |
{ | |
udMaxPacket = FS_MAX_PACKET_SIZE; | |
} | |
if (dwLen%udMaxPacket == 0) | |
{ | |
return TRUE; | |
} | |
else | |
{ | |
return FALSE; | |
} | |
} | |
/*ö¾Ùº¯Êý*/ | |
u32 USB3Slave_CDC_Enum(void) | |
{ | |
T_USB3Slave_Ep *ptDep; | |
u32 dwCount=0; | |
u32 dwCount1=0; | |
u32 udIndex; | |
global.g_Connet = 0; | |
USB3Slave_Ctrl_Init(); | |
if(global.need_enum ==0) | |
{ | |
for (udIndex=2; udIndex < 6; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/ | |
{ | |
ptDep = &(g_USB3Slave.tEps[udIndex]); | |
ptDep->ptTRB= &USB3Slave_TRB_EP[udIndex-2]; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem | |
ptDep->udEpNum = udIndex; | |
//USB3Slave_CfgEp(ptDep); | |
} | |
} | |
if(global.need_enum ==1) | |
{ | |
while(1) | |
{ | |
USB3Slave_ISR(0,0); | |
if(0 == global.g_Connet) | |
{ | |
dwCount++; | |
usb_timeout_usdelay(50000); | |
if(dwCount>(4000*global.g_USB_TIMEOUT)) | |
return 1; | |
} | |
else if(1 == g_USB3Slave.udUSBSate) | |
{ | |
for (udIndex=2; udIndex < 6; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/ | |
{ | |
ptDep = &(g_USB3Slave.tEps[udIndex]); | |
ptDep->ptTRB= &USB3Slave_TRB_EP[udIndex-2]; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem | |
ptDep->udEpNum = udIndex; | |
USB3Slave_CfgEp(ptDep); | |
} | |
break; | |
} | |
else | |
{ | |
dwCount1++; | |
usb_timeout_usdelay(50000); | |
if(dwCount1>(200000*global.g_USB_TIMEOUT)) | |
{ | |
return 1; | |
} | |
} | |
} | |
} | |
return 0; | |
} | |
extern void USB_Boot(void); | |
extern void USB_Pll_Clk_Rst_InitEnv(void); | |
void USB3Slave_boot(void) | |
{ | |
u32 dwConnect; | |
global.g_USB_MODE = 0; | |
global.need_enum = 0; | |
// 1:config clock | |
if(global.need_enum ==1) | |
{ | |
USB_Pll_Clk_Rst_InitEnv(); | |
} | |
// 2:USB30_CDC_Enum | |
dwConnect = USB3Slave_CDC_Enum(); | |
if(1==dwConnect) | |
{ | |
printf("NOLINK\n"); | |
return ; | |
} | |
#if 0//SIM_EN == EMULATION | |
REG32(ARM_PORTA)=0x32; | |
#endif | |
printf("FAILED\n"); | |
} | |
/** @} */ | |