| /******************************************************************************* | |
| * °æÈ¨ËùÓÐ (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"); | |
| } | |
| /** @} */ | |