📄 usbd_func.c
字号:
/*
* Module for control of USB Device
* $Revision: 1.10 $ $Date: 2006/12/22 05:36:00 $
*/
/*=== Include =============================================================*/
#include "SPRDEF.h"
#include "SPRSTS.h"
#include "usb_descinfo.h"
#include "usbd_func.h"
#include "usbd_if.h"
#include "fifo_if.h"
#include "OSCall.h"
#include <string.h> /* memset,memcpy */
#include "led_if.h"
#include "PM_IF.h"
/*=== Define ==============================================================*/
/* USB Function */
#define MAX_ID (4) /* Maximum number for ID */
#define MAX_OPEN (6) /* Possible number for Open */
#define MAX_CBINF_LIST (24) /* Maximum number for registration of callback */
#define MAX_CBINF_LIST2 (24) /* Maximum number for registration of callback */
#define MAX_CBINF_LIST3 (1) /* Maximum number for registration of callback */
/* Endpoint */
#define MAX_ENDPOINT (USBD_IF_MAX_ENDPOINT) /* Maximum number for endpoint supported by Function */
/* Interface */
#define MAX_INTERFACE (6) /* Maximum number for interface supported by Function */
#define MAX_ALTERNATE (4) /* Maximum number for Alternate Setting */
/* Descriptor */
#define MAX_DESC_DEVICE (1) /* Index number for Device Descriptor (fixed to 1) */
#define MAX_DESC_CONFIG (1) /* Index number for Configuration Descriptor */
#define MAX_DESC_STRING (7) /* Index number for String Descriptor */
#define MAX_DESC_OTHER_CONFIG (1) /* Index number for Configuration Descriptor */
#define MAX_DESC_DEVICE_QUAL (1) /* Index number for Device Qualifier Descriptor(fixed to 1) */
#define TMOUT_VBUSCHECK (15) /* Value of timer for VBUS check (ms) */
#define TMOUT_REMOTEWAKEUPDIS (10) /* Forbidden periods of Remote Wakeup from the start of Suspend */
#define TMOUT_AUTOREMOTEWAKEUP (500) /* Time of Waiting Auto Remote Wakeup */
#define TMOUT_SE0CHECK (1) /* Time of check for waiting SE0's release */
#define TMOUT_REMOTEWAKEUP (2) /* Time of K sending on Remote Wakeup (ms) */
/*=== Macro ===============================================================*/
#define IFRET_TO_FUNCRET(value) (((value) == STATUS_INVALID_PARAMETER) ? STATUS_UNSUCCESSFUL : value)
#define IS_START() ((PrvStatusInfo.dwInternalStatus & PRV_IS_STARTED) != 0 ? TRUE : FALSE)
#define IS_EPX_DIRIN(epn) (((epn) & 0x80) == 0x80 ? TRUE : FALSE)
#define IS_EP0(epn) (((epn) & 0x7F) == 0x00 ? TRUE : FALSE)
#define IS_VALID_BITMASK(bit,chkbit) ((((bit) | (chkbit)) ^ (chkbit)) == 0x00 ? TRUE : FALSE)
#define CLR_BIT(bits,mask) ((bits) = ((bits) & ~(mask)))
#define SET_BIT(bits,mask) ((bits) = ((bits) | (mask)))
#define IS_BIT(bits,mask) (((bits) & (mask)) != 0x00 ? TRUE : FALSE)
/*=== Define ==============================================================*/
/* EP0 */
#define PRV_EP0 (0x00) /* EP0(IN/OUT) */
#define PRV_EP0_IN (0x80) /* EP0 IN */
#define PRV_EP0_OUT (0x00) /* EP0 OUT */
/* */
#define PRV_ID_NONE (0xFFFFU) /* Unused ID */
#define PRV_PORT_NONE (0xFFFFU) /* Unused PORT */
/* Callback */
#define PRV_CBINF_ATTACH (0x00) /* Attach Event Callback */
#define PRV_CBINF_DETACH (0x01) /* Detach Event Callback */
#define PRV_CBINF_RESET (0x02) /* Reset Event Callback */
#define PRV_CBINF_SUSPEND (0x03) /* Suspend Event Callback */
#define PRV_CBINF_RESUME (0x04) /* Resume Event Callback */
#define PRV_CBINF_EPXEVENT (0x05) /* EPx Packet Event Callback */
#define PRV_CBINF_USBADR (0x06) /* Change USB Address Event */
#define PRV_CBINF_TESTMODE (0x07) /* Enter Test Mode Callback */
#define PRV_CBINF_REMWAKE (0x08) /* Remote Wakeup Complete Callback */
#define PRV_CBINF_REQUEST (0x09) /* Request Received Event Callback */
#define PRV_CBINF_SSTAGECMP (0x0A) /* Status Stage Complete Callback */
#define PRV_CBINF_STRNCMP (0x0B) /* Simple Transfer Complete Callback */
#define PRV_CBINF_TRNREQ (0x0C) /* Transfer Request Callback */
#define PRV_CBINF_TRNCMP (0x0D) /* Transfer Complete Callback */
#define PRV_CBINF_REPDESC (0x0E) /* Repry Descriptor Complete Callback */
#define PRV_CBINF_VBUS (0x0F) /* VBUS Change Callback */
#define PRV_CBINF_WAKEUP (0x10) /* NonJ Event Callback */
#define PRV_CBINF_BULKONLY (0x11) /* BulkOnly Event Callback */
#define PRV_MAX_CBINF (18) /* Kind of callback */
#define PRV_CBINF_UNUSED (0xFFFFU)
#define PRV_ID_USED (1)
#define PRV_ID_UNUSED (0)
/* Internal Status */
#define PRV_IS_STARTED (0x8000) /* Flag for operation's start */
#define PRV_IS_REMOTEWAKEDIS (0x0200) /* Forbidden periods of Remote Wakeup */
#define PRV_IS_EP0TRNDIS (0x0100) /* Forbidden periods of Control transfer */
#define PRV_IS_VBUSCONNECTREQ (0x0080) /* Request of VBUS Connect Retry */
#define PRV_IS_TESTMODEREQ (0x0040) /* Request of Test Mode */
#define PRV_IS_REMOTEWAKEREQ (0x0020) /* Request of Remote Wakeup */
#define PRV_IS_SETADRREQ (0x0010) /* Request of Set Address */
#define PRV_IS_VBUSCHECK (0x0001) /* Request of VBUS check */
/* Internal Request */
#define PRV_IR_VBUS (0x0000)
#define PRV_IR_SUSPEND (0x0001)
#define PRV_IR_RESUME (0x0002)
#define PRV_IR_RESET (0x0003)
#define PRV_IR_CHIRPCMP (0x0004)
#define PRV_IR_RESUMECMP (0x0005)
#define PRV_IR_SOF (0x0006)
#define PRV_IR_EP0TRN (0x0007)
#define PRV_IR_EPXTRN (0x0008)
#define PRV_IR_SETUP (0x0009)
#define PRV_IR_SETADR (0x000A)
#define PRV_IR_REPDESC (0x000B)
#define PRV_MAX_INTERNAL_CBINF (12)
#define PRV_IR_PENDING (0x0001)
/* Information for Endpoint */
#define PRV_EPXINFO_USEDMA (0x0001) /* To show if this Endpoint is on DMA transferring */
#define PRV_EPXINFO_STRN (0x0002) /* Flag for USBD_FuncEPxPIOSimpleTransfer() on executing */
#define PRV_EPXINFO_TRN (0x0004) /* Flag for USBD_FuncEPxPIOTransfer() on executing */
#define PRV_EPXINFO_SSTAGE (0x0008) /* Flag for USBD_FuncStatusStageReadyA() on executing */
#define PRV_EPXINFO_FIRSTTIME (0x0010) /* Flag used when data transfer has not been done at all */
#define PRV_EPXINFO_PENDING (0x0020) /* Case of data transfer can't be done at upper layer */
#define PRV_EPXINFO_SHORTPKTDIS (0x0040) /* Mode of transfer for short packet */
#define PRV_EPXINFO_EP0IN (0x0001) /* Flag used when doing tranfer in direction of EP0 IN */
#define PRV_EPXINFO_USED (0x8000) /* To show if the Endpoint is on using */
#define PRV_EPXINFO_ENABLED (0x4000) /* To show if the Endpoint is enabled */
#define PRV_EPXINFO_TYPE_CONTROL (0x00) /* Control transfer */
#define PRV_EPXINFO_TYPE_ISOCHRONOUS (0x01) /* Isochronous transfer */
#define PRV_EPXINFO_TYPE_BULK (0x02) /* Bulk transfer */
#define PRV_EPXINFO_TYPE_INTERRUPT (0x03) /* Interrupt transfer */
/* Descriptor */
#define PRV_DESCINF_ADR (0x01) /* Entity of this Descriptor is not in Function layer */
#define PRV_DESCINF_REPLY (0x02) /* Use the Reply Descriptor */
/*=== Structure ===========================================================*/
/* Header */
typedef struct {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR wTotalLength[2];
} PRV_DESC_HEADER;
/* List of callback */
typedef struct prv_callbacklist {
USHORT type; /* Type of callback */
USHORT id; /* Identifier of upper layer */
USHORT port; /* Port number(Endpoint) */
CALLBACK_PROC pfnCallback; /* Pointer of callback function */
} PRV_CALLBACKLIST;
/* List of Endpoint */
typedef struct prv_endpointlist {
UCHAR bInterface;
UCHAR bAlternate;
UCHAR *endpoint;
} PRV_ENDPOINTLIST;
/* Status */
typedef struct prv_statusinfo {
ULONG dwBusEvent;
ULONG dwPktEvent;
ULONG dwBusStatus;
ULONG dwInternalStatus;
ULONG dwCommonExecStatus;
ULONG dwExecStatus[MAX_ID];
} PRV_STATUSINFO;
/* Information for Endpoint */
typedef struct prv_epxinfo {
UCHAR *ptr; /* Pointer of buffer */
ULONG totalXferSize; /* Total number of transfer */
ULONG actXferSize; /* Current number of transfer */
ULONG xferredSize; /* Number which has been transferred */
USHORT id; /* Identifier of upper layer */
USHORT flag; /* Flag */
USHORT trnflag; /* Flag for transfer */
USHORT epMaxSize; /* MaxPacketSize */
UCHAR epAddress; /* Address of Endpoint */
UCHAR epType; /* Type of Endpoint */
} PRV_EPXINFO;
/* EP0,x Event List */
typedef struct prv_ep0_eventlist {
UCHAR inEvent;
UCHAR inAutoDisable;
UCHAR inShortPkt;
UCHAR outEvent;
UCHAR outAutoDisable;
UCHAR outShortPkt;
} PRV_EP0_EVENTLIST;
typedef struct prv_epx_eventlist {
UCHAR endpoint_num;
UCHAR Event;
UCHAR autodisable;
UCHAR shortPkt;
USHORT id;
} PRV_EPX_EVENTLIST;
/* Descriptor Info */
typedef struct {
UCHAR *ptr;
USHORT replyOffset;
UCHAR flag;
} PRV_DESCINFO;
/* Configuration Descriptor Info */
typedef struct prv_config_info {
UCHAR selectConfig;
UCHAR interfaceNum;
UCHAR alternateNum[MAX_INTERFACE];
UCHAR alternateList[MAX_INTERFACE];
UCHAR endpointListNum;
PRV_ENDPOINTLIST endpointList[MAX_ENDPOINT * MAX_ALTERNATE];
} PRV_CONFIG_INFO;
/* Information for Descriptor Info */
typedef struct prv_descinfoptr {
UCHAR **ptr;
USHORT *offset;
UCHAR *flag;
} PRV_DESCINFOPTR;
/*=== Variable ============================================================*/
/* Number of Open */
/* Variable used for VBus check */
/* ID for timer */
static UCHAR PrvUsbAddress; /* Variable used for saving USB Address */
static UCHAR PrvTestMode; /* Variable used for saving Test Mode */
static UCHAR PrvIdTable[MAX_ID]; /* Table for ID */
static PRV_CALLBACKLIST PrvCallbackList[MAX_CBINF_LIST];
static PRV_CALLBACKLIST PrvXferCallbackList[MAX_CBINF_LIST2];
static PRV_CALLBACKLIST PrvBulkOnlyCallbackList[MAX_CBINF_LIST3];
/* Area for saving parameter */
static USBD_FUNC_POWER PrvPowerParam; /* Setting of power saving */
static USBD_FUNC_HWFEATURE PrvHwFeatureParam; /* Setting of H/W function */
static USBD_FUNC_SWFEATURE PrvSwFeatureParam; /* Setting of S/W function */
static USBD_FUNC_FIFOAREA PrvFifoAreaParam; /* Setting of FIFO area */
static USBD_FUNC_BULKONLY PrvBulkOnlyParam; /* Setting of BulkOnly function */
/* Area for saving Descriptor */
/* Device */
static PRV_DESCINFO PrvFsDevDesc[MAX_DESC_DEVICE];
static PRV_DESCINFO PrvHsDevDesc[MAX_DESC_DEVICE];
/* Configuration Descriptor */
static PRV_DESCINFO PrvFsConfDesc[MAX_DESC_CONFIG];
static PRV_DESCINFO PrvHsConfDesc[MAX_DESC_CONFIG];
/* String Descriptor */
static PRV_DESCINFO PrvFsStrDesc[MAX_DESC_STRING];
static PRV_DESCINFO PrvHsStrDesc[MAX_DESC_STRING];
/* Other Speed Configuration */
static PRV_DESCINFO PrvFsOtherConfDesc[MAX_DESC_OTHER_CONFIG];
static PRV_DESCINFO PrvHsOtherConfDesc[MAX_DESC_OTHER_CONFIG];
/* Device Qualifier */
static PRV_DESCINFO PrvFsDevQualDesc[MAX_DESC_DEVICE_QUAL];
static PRV_DESCINFO PrvHsDevQualDesc[MAX_DESC_DEVICE_QUAL];
/* Information for Configuration Descriptor */
static PRV_CONFIG_INFO PrvConfigInfo;
/* Information for Endpoint */
static PRV_EPXINFO PrvEPxInfo[MAX_ENDPOINT];
/* Event List */
static PRV_EP0_EVENTLIST PrvEP0EventList[MAX_ID];
static PRV_EPX_EVENTLIST PrvEPxEventList[MAX_ENDPOINT];
/* Status */
static PRV_STATUSINFO PrvStatusInfo;
static USHORT PrvEP0DataStageLength; /* Number of data stage in Control transfer */
static USHORT PrvEP0DataStageRemain; /* Number of remained transfer which is transferred by data stage of Control transfer */
/* debug */
#ifdef DEBUG_C
static UCHAR PrvSkipSetup;
//static ULONG PrvRcvSetupCnt;
static UCHAR PrvSimpleTransferExecute;
//static UCHAR BusLog[5];
#ifdef SETUPLOG
static UCHAR PrvSetupLog[32][8];
static UCHAR PrvSetupLogCount;
#endif
#endif
/*=== Function Prototype ==================================================*/
Inline UCHAR PrvEPAdrToEPx(UCHAR endpoint_num);
static LONG PrvGetDescriptorInfoAddress(UCHAR speed,UCHAR type,UCHAR index,PRV_DESCINFOPTR *pDescInfo);
static LONG PrvGetDescriptorSize(UCHAR *ptr,USHORT *size);
static LONG PrvInitVariables(void);
static LONG PrvRegisterIFAllCallbacks(void);
static LONG PrvUnregisterIFAllCallbacks(void);
static LONG PrvGetEPxEvent(USHORT id,UCHAR epn,UCHAR *bitmask,UCHAR *autodisable);
static LONG PrvSetEPxEvent(USHORT id,UCHAR epn,UCHAR bitmask,UCHAR autodisable);
static LONG PrvIsEPxShortPktEnable(USHORT id,UCHAR epn,UCHAR *result);
static LONG PrvSetEPxShortPkt(USHORT id,UCHAR epn,UCHAR shortpkt);
static LONG PrvUsbBusAttach(void);
static LONG PrvUsbBusDetach(void);
//static LONG PrvSendRemoteWakeup(void);
//static LONG PrvEndRemoteWakeup(UCHAR result);
//static LONG PrvRemoteWakeupTimeoutCallback(void);
static LONG PrvParseConfig(UCHAR *ptr,LONG size);
static LONG PrvParseInterface(UCHAR *ptr,ULONG size);
static LONG PrvParseEndpoint(UCHAR *ptr,ULONG size);
static LONG PrvSkipDescriptor(UCHAR *ptr,ULONG size);
static LONG PrvEnableEndpoints(void);
static LONG PrvDisableEndpoints(void);
static LONG PrvAddCallbackInf(USHORT type,USHORT id,USHORT port,CALLBACK_PROC pfnCallback);
static LONG PrvDelCallbackInf(USHORT type,USHORT id,USHORT port,CALLBACK_PROC pfnCallback);
static LONG PrvExecCallback(USHORT type,USHORT id,USHORT port,ULONG lParam0,ULONG lParam1,void *pParam);
//static LONG PrvCheckPollingEvent(void);
//static LONG PrvSetInternalRequest(USHORT type,ULONG lParam0,ULONG lParam1,void *pParam);
static LONG IsAlreadyRegisteredCallbackList(USHORT type,USHORT id,USHORT port,CALLBACK_PROC pfnCallback);
static LONG IsInvalidCallbackList(USHORT type,USHORT id,USHORT port,CALLBACK_PROC pfnCallback);
static LONG PrvSetUnuseInterfaceEndpoints(UCHAR interface);
static LONG PrvInitEndpoint(UCHAR epn);
static LONG PrvDisableAllEndpoints(void);
static LONG PrvUsbVbusCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvDPDMStateChangeCallback(ULONG lParam0,ULONG lParam1,void *pParam);
//static LONG PrvReceiveSOFCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvReceiveSETUPCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvEP0PacketXferStatusCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvEPxPacketXferStatusCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvReplyDescCmpCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvHWSetAddressCmpCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvBulkOnlyEventCallback(ULONG lParam0,ULONG lParam1,void *pParam);
//static LONG PrvRemoteWakeupEnableTimeoutCallback(void);
//static LONG PrvDisBusDetectEnableTimeoutCallback(void);
//static LONG PrvUsbVBusProcess(void);
static LONG PrvUsbBusSuspendCallback(void);
static LONG PrvUsbBusWakeupCallback(void);
static LONG PrvUsbBusResetCallback(void);
static LONG PrvUsbBusChirpCmpCallback(void);
static LONG PrvUsbBusResumeCmpCallback(void);
static LONG PrvFIFOFullEmptyCallback(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvEP0IntEvent(PUSBD_IF_ENDPOINT_STATUS ifepxstatus);
static LONG PrvEPxIntEvent(UCHAR epn,USBD_IF_ENDPOINT_STATUS *ifepxstatus);
static LONG PrvEP0StatusStage(UCHAR index,USBD_IF_ENDPOINT_STATUS *ifepxstatus);
static LONG PrvEP0PacketXferStatusProcess(ULONG lParam0,ULONG lParam1,void *pParam);
//static LONG PrvEPxPacketXferStatusProcess(ULONG lParam0,ULONG lParam1,void *pParam);
static LONG PrvIsAbortDataStage(USBD_IF_ENDPOINT_STATUS *ifepxstatus);
static LONG PrvEP0PIOSimpleTransfer(UCHAR index,UCHAR abort);
static LONG PrvEPxPIOSimpleTransfer(UCHAR index,UCHAR abort);
static LONG PrvSetupReplyDescriptor(void);
/* =============================================================================
// Function_Name: USBD_FuncReset
// description : Do reset of USB Function layer
// argument : None
// return : STATUS_SUCCESS Finished normally
// =============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -