blob: 3b1df60648ec6883b0cf4bc3c87464a37ba77b60 [file] [log] [blame]
/*******************************************************************************
* °æÈ¨ËùÓÐ (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");
}
/** @} */