⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd_if.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * H/W I/F process for USB Device control
 * $Revision: 1.8 $ $Date: 2006/08/10 08:11:29 $
 */

/*=== Include =============================================================*/
/* #include "sprsts.h" */
#include "SPRSTS.h"
#include "usbd_if.h"
#include "Reg72V05.h"
#include "OSCall.h"

/*=== Define ==============================================================*/
/* Open */
#define MAX_OPEN				(1)		/* Times that Open can be done */

/* Endpoint */
#define	MAX_ENDPOINT			(4)		/* Endpoint number related to S1R72V05 */
#define	MAX_EPX				(3)		/* Endpoint number except for EP0 */

/* Endpoint FIFO Size */
#define	MAX_FIFOSIZE			(0x1200)	/* FIFO Size */

/*=== Define ==============================================================*/
/* Callbacks */
#define   CBINF_VBUS			(0x00)	/* Notification for VBUS change */
#define	CBINF_DPDM			(0x01)	/* Notification for Reset,Suspend,Resume,ChirpCmp,ResumeCmp */
#define	CBINF_RCVSOF		(0x02)	/* Notification for SOF's receiving */
#define	CBINF_RCVSETUP		(0x03)	/* Notification for Request's receiving */
#define	CBINF_EP0XFER		(0x04)	/* Notification for EP0 Handshake */
#define	CBINF_EPXXFER		(0x05)	/* Notification for EPR Handshake */
#define	CBINF_REPLYDESC		(0x06)	/* Notification for completion of Reply Descriptor */
#define	CBINF_SETADR		(0x07)	/* Notification for completion of Set Address */
#define   CBINF_BULKONLY		(0x08)	/* Notification for BulkOnly CBW,CSW */
#define	MAX_CALLBACK		   (9)	/* Number of callback */

/* Interrupt Status */
#define IS_DEVICE_INT_STAT	(0x00)	/* Position to save interrupt status */
#define	IS_EPR_INT_STAT		(0x01)	/* Position to save interrupt status */
#define	IS_SIE_INT_STAT		(0x02)	/* Position to save interrupt status */
#define	IS_FIFO_INT_STAT	(0x03)	/* Position to save interrupt status */
#define IS_BULK_INT_STAT	(0x04)	/* Position to save interrupt status */
#define	IS_EP0_INT_STAT		(0x05)	/* Position to save interrupt status */
#define	IS_EPA_INT_STAT		(0x06)	/* Position to save interrupt status */
#define	IS_EPB_INT_STAT		(0x07)	/* Position to save interrupt status */
#define	IS_EPC_INT_STAT		(0x08)	/* Position to save interrupt status */
#define MAX_IS					(9)	/* Number of interrupt status */

/* Main Int Stat Mask */
#define MASK_MAIN_INT_STAT		(0x80)
#define MASK_DEVICE_INT_STAT	(0xBF)	/* VBUS_Changed,D_SIE_IntStat,D_BulkIntStat,RcvEP0SETUP,D_FIFO_IntStat,D_EP0IntStat,D_EPrIntStat */
#define MASK_SIE_INT_STAT		(0x7F)	/* NonJ	RcvSOF,DetectRESET,DetectSUSPEND,ChirpCmp,RestoreCmp,SetAddressCmp */
#define	MASK_FIFO_INT_STAT		(0x80)	/* DescriptorCmp */

/* Main Int Stat Mask */
#define GRP_EP0_INT		(BIT_OUT_ShortACK | BIT_IN_TranACK | BIT_OUT_TranACK | BIT_IN_TranNAK | BIT_OUT_TranNAK | BIT_IN_TranErr | BIT_OUT_TranErr)
#define GRP_BO_INT		(BIT_CBW_Cmp | BIT_CBW_LengthErr | BIT_CBW_Err | BIT_CSW_Cmp | BIT_CSW_Err)

#define R8_ALLZERO				(0x00)
#define R8_INT_ALLZERO			(0xFF)
#define R16_ALLZERO				(0x0000)
#define R16_INT_ALLZERO			(0xFFFF)

/* EPx Handshake */
#define	INT_OUTSHORTACK			(0x40)	/* EPx OUT Short ACK */
#define INT_INACK				(0x20)	/* EPx IN ACK */
#define	INT_OUTACK				(0x10)	/* EPx OUT ACK */
#define	INT_INNAK				(0x08)	/* EPx IN NAK */
#define	INT_OUTNAK				(0x04)	/* EPx OUT NAK */
#define	INT_INSTALL				(0x02)	/* EPx IN STALL */
#define	INT_OUTSTALL			(0x01)	/* EPx OUT STALL */

/* Transfer Type */
#define	EPX_CAP_CONTROL			(0x01)		/* Support for Control transfer */
#define	EPX_CAP_BULK			(0x02)		/* Support for Bulk transfer */
#define	EPX_CAP_INT				(0x04)		/* Support for Interrupt transfer */
#define	EPX_CAP_ISO				(0x08)		/* Support for Isochronous transfer */
#define	EPX_CAP_DMA				(0x10)		/* Support for DMA transfer */

/*=== Structure ===========================================================*/
/* Information of transfer type which can be set for EP */
typedef struct epx_capabirity {
	UCHAR	type;							/* Transfer type */
} EPX_CAPABIRITY;

/* FIFO Area Map */
typedef struct fifo_map {
	USHORT	ep0Start;						/* Start address of EP0 area */
	USHORT	ep0Size;						/* Size of EP0 area */
	USHORT	replyStart;						/* Start address of Reply Descriptor area */
	USHORT	replySize;						/* Size of Reply Descriptor area */
	USHORT	cbwStart;						/* Start address of CBW area */
	USHORT	cbwSize;						/* Size of CBW area */
	USHORT	cswStart;						/* Start address of CSW area */
	USHORT	cswSize;						/* Size of CSW area */
	USHORT	epxStart[MAX_EPX];				/* Start address of EPx area */
	USHORT	epxSize[MAX_EPX];				/* Size of EPx area */
} FIFO_MAP;

/*=== Macro ===============================================================*/
#define IS_EPX_DIRIN(epn)				(((epn) & 0x80) == 0x80 ? TRUE : FALSE)
#define	IS_BIT(bits,mask)				(((bits) & (mask)) != 0x00 ? TRUE : FALSE)
#define	CLR_BIT(bits,mask)				((bits) = ((bits) & ~(mask)))
#define	SET_BIT(bits,mask)				((bits) = ((bits) | (mask)))

/*=== Variable ============================================================*/

/* Area to save interrupt status */
static volatile UCHAR IntStat[MAX_IS];


/* Map of FIFO area */
static FIFO_MAP			FifoMap;

/* USBD_IFGetFeatureMode(),USBD_IFSetFeatureMode() */
static USBD_IF_FEATURE_MODE	FeatureMode;

/* Tabel of callback function */
static CALLBACK_PROC	CallbackTable[MAX_CALLBACK];

/* Information of Endpoint that means whether it can be set */
static EPX_CAPABIRITY	EPxCapabirity[MAX_ENDPOINT]
={
{EPX_CAP_CONTROL | EPX_CAP_DMA}			  ,	/* EP0 */
{EPX_CAP_BULK | EPX_CAP_INT | EPX_CAP_DMA},	/* EPa */
{EPX_CAP_BULK | EPX_CAP_INT | EPX_CAP_DMA},	/* EPb */
{EPX_CAP_BULK | EPX_CAP_INT | EPX_CAP_DMA},	/* EPc */
};

/* Test Packet Data */
UCHAR TestPacket[]= {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
0xAA,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
0xEE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xBF,0xDF,
0xEF,0xF7,0xFB,0xFD,0xFC,0x7E,0xBF,0xDF,
0xEF,0xF7,0xFB,0xFD,0x7E};

static volatile UCHAR tempMainIntStat,tempDeviceIntStat,tempD_SIE_IntStat,tempD_EPrIntStat,tempD_FIFO_IntStat,tempD_EP0IntStat,tempD_BulkIntStat;
static volatile UCHAR tempD_EPxIntStat[MAX_EPX];

#ifdef DEBUG_C
#define	INTLOGCNT	(256)
#ifdef INTLOG
static volatile UCHAR	IntStatLog[INTLOGCNT][0x10];
static volatile USHORT	IntStatLogCnt;
static volatile UCHAR	USBD_IntProcIn;
#endif
#endif


/*=== Function Prototype ==================================================*/
static LONG InitIc(void);
static LONG InitVariables(void);
void InterruptProc(void);
static void USBD_IFISRProcess(void);

/* =============================================================================
// Function_Name: USBD_IFReset
// description	: Reset USBD I/F
// argument		: None
// return		: STATUS_SUCCESS	Finished normally
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFReset(void)
{
	LONG retValue;
#ifdef DEBUG_C
#ifdef INTLOG
	USHORT i,j;
#endif
#endif
	retValue = STATUS_SUCCESS;  

	do { /* Don't loop */
		/* Initialize IC */
		retValue = InitIc();
		if (retValue != STATUS_SUCCESS) {
			break;
		}
		/* Initialize variables */

		retValue = InitVariables();
		if (retValue != STATUS_SUCCESS) {
			break; 
		}
#ifdef DEBUG_C
#ifdef INTLOG
IntStatLogCnt = 0;
for (i = 0;i < INTLOGCNT;i++) {
	for (j = 0;j < 0x10;j++) {
		IntStatLog[i][j] = 0;
	}
}
USBD_IntProcIn = 0;

#endif
#endif

	} while (0);

	return retValue;
}

/* =============================================================================
// Function_Name: USBD_IFAttach
// description	: Do process for Attach
// argument		: None
// return		: STATUS_SUCCESS			Finished normally
//				  STATUS_NOT_OPENED			Not be opened yet
// memo 		: Don't set detection of Suspend & Reset to Enable here
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFAttach(void)
{
	LONG retValue;

	retValue = STATUS_SUCCESS;

	do { /* Don't loop */

		/* Case of connecting VBUS */
		CLR_BIT(IntStat[IS_DEVICE_INT_STAT],BIT_VBUS_Changed);
		
		/* D_USB_Status.FSxHS = 1 */
		RegSet(REG08_D_USB_Status,BIT_FSxHS_FSmode);	/* set FSxHS to 1 */

		/* Enable the USB, forbid detection of Reset and Suspend */
		RegWrite(REG08_D_NegoControl,BIT_ActiveUSB | BIT_DisBusDetect);

		/*
		 * Because if SETUP packet has been received before receiving USB reset after Power ON,
		 * it must be ignored, so set OpMode to 02h.
		 * Set value of OpMode to 00h after USB Reset has been processed.
		 */
		RegWrite(REG08_D_XcvrControl,BIT_D_TermSelect_FS | BIT_D_XcvrSelect_FS | BIT_D_OpMode_DisableBitStuffing);

	} while (0);
#ifdef DEBUG_C
#ifdef INTLOG
IntStatLogCnt = 0x00;
#endif
#endif

	return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFDetach
// description	: Do process for Detach
// argument		: None
// return		: STATUS_SUCCESS			Finished normally
//				  STATUS_NOT_OPENED			Not be opened yet
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFDetach(void)
{
	LONG retValue;
	UCHAR i;

	retValue = STATUS_SUCCESS;

	do { /* Don't loop */

		RegModify(REG08_D_XcvrControl,MASK_D_OpMode,BIT_D_OpMode_NonDriving);		/* Non Drive */
		RegClear(REG08_D_NegoControl,BIT_EnAutoNego);								/* AutoNego */

		/* Clear GoChirp,RestoreUSB,InSUSPEND */
		RegWrite(REG08_D_NegoControl,R8_ALLZERO);	/* D_NegoControl = 0x00 */

		/* D_XcvrControl = 0x41 */
		RegWrite(REG08_D_XcvrControl,BIT_D_XcvrSelect_FS | BIT_D_OpMode_NonDriving);
		RegWrite(REG08_D_USB_Address,R8_ALLZERO);								/* USB Address 0 */
		RegWrite(REG08_D_USB_Test,R8_ALLZERO);									/* Clear all bits of USBTest */

		/* Clear variables */
		RegWrite(REG08_D_SIE_IntStat,R8_INT_ALLZERO);
		CLR_BIT(IntStat[IS_DEVICE_INT_STAT],R8_ALLZERO);
		IntStat[IS_SIE_INT_STAT] = R8_ALLZERO;
		IntStat[IS_EPR_INT_STAT] = R8_ALLZERO;
		IntStat[IS_EP0_INT_STAT] = R8_ALLZERO;
		for (i = 0;i < MAX_EPX;i++) {
			IntStat[IS_EPA_INT_STAT + i] = R8_ALLZERO;
		}
	} while (0);

	return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFEnableBusDetect
// description	: Enable the detection of Suspend & Reset
// argument		: None
// return		: STATUS_SUCCESS
//				  STATUS_NOT_OPENED			Not be opened yet
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFEnableBusDetect(void)
{
	LONG retValue;

	retValue = STATUS_SUCCESS;

	do { /* Don't loop */

		RegSet(REG08_D_SIE_IntEnb,(MASK_EnDetectRESET | MASK_EnDetectSUSPEND | MASK_EnChirpCmp | MASK_EnRestoreCmp));

		if ((RegRead(REG08_D_NegoControl) & MASK_EnAutoNego) != BIT_EnAutoNego) {

			RegClear(REG08_D_NegoControl,BIT_DisBusDetect);		/* Enable the detection of Reset and Suspend */
			if (FeatureMode.DisableHS == 0) {
				/* When HS Mode is enabled */
				RegClear(REG08_D_NegoControl,BIT_DisableHS);
			} else {
				/* When HS Mode is disabled */
				RegSet(REG08_D_NegoControl,BIT_DisableHS);
			}
			if (FeatureMode.AutoNego == 1) {
				/* Enable AutoNego here */
				RegSet(REG08_D_NegoControl,BIT_EnAutoNego);
			}
		}
	} while (0);

	return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFRemoteWakeup
// description	: Send K of Remote Wakeup and stop
// argument		: USBD_IF_SIGNAL_K			Send K
//				  USBD_IF_SIGNAL_STOP_K		Stop sending of K
// return		: STATUS_SUCCESS			Finished normally
//				  STATUS_NOT_OPENED			Not be opened yet
//				  STATUS_INVALID_PARAMETER	Parameter error
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFRemoteWakeup(UCHAR SignalState)
{
	LONG retValue;

	retValue = STATUS_SUCCESS;

	do { /* Don't loop */

		if (SignalState == USBD_IF_SIGNAL_K) {
			RegClear(REG08_D_SIE_IntEnb,BIT_EnNonJ);	/* Disable the Non_J interrupt */
			RegSet(REG08_D_NegoControl,BIT_SendWakeup);
		} else if (SignalState == USBD_IF_SIGNAL_STOP_K) {
			RegClear(REG08_D_NegoControl,BIT_SendWakeup);
			RegSet(REG08_D_SIE_IntEnb,BIT_EnNonJ);		/* Enable the Non_J interrupt */
		} else {
			retValue = STATUS_INVALID_PARAMETER;
		}

	} while (0);

	return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFResetProcess
// description	: Do process for detecting Reset
// argument		: None
// return		: STATUS_SUCCESS			Finished normally
//				  STATUS_NOT_OPENED			Not be opened yet
// flag			:
// global		:
// =============================================================================
*/
LONG USBD_IFResetProcess(void)
{
	LONG retValue;
	UCHAR i;

	retValue = STATUS_SUCCESS;

	do { /* Don't loop */

		/* D_NegoControl.EnAutoNego == 0 */
		if ((RegRead(REG08_D_NegoControl) & MASK_EnAutoNego) != BIT_EnAutoNego) {
			/* When AutoNego is not used */
			RegClear(REG08_D_NegoControl,BIT_DisBusDetect);		/* Detection function of Suspend and Reset -> Disable */
			/* Start Chirp */
			RegSet(REG08_D_NegoControl,BIT_GoChirp);
		}

		/* Stop Repry Descriptor */
		RegSet(REG08_D_EP0ControlOUT,BIT_AutoForceNAK);
		RegClear(REG08_D_EP0Control,BIT_ReplyDescriptor_Go);

		/* Clear interrupt status */
		RegWrite(REG08_DeviceIntStat,BIT_RcvEP0SETUP);			/* Clear RcvEP0Setup */
		CLR_BIT(IntStat[IS_DEVICE_INT_STAT],BIT_D_BulkIntStat | BIT_RcvEP0SETUP | BIT_D_FIFO_IntStat | BIT_D_EP0IntStat | BIT_D_EPrIntStat);
		CLR_BIT(IntStat[IS_SIE_INT_STAT],BIT_NonJ | BIT_RcvSOF | BIT_DetectRESET | BIT_DetectSUSPEND | BIT_RestoreCmp | BIT_SetAddressCmp);		/* Clear others except except fot ChirpCmp */
		CLR_BIT(IntStat[IS_EPR_INT_STAT],0xFF);
		CLR_BIT(IntStat[IS_FIFO_INT_STAT],MASK_FIFO_INT_STAT);
		CLR_BIT(IntStat[IS_EP0_INT_STAT],0xFF);
		for (i = 0;i < MAX_EPX;i++) {
			IntStat[IS_EPA_INT_STAT + i] = R8_ALLZERO;
		}
	} while (0);

	return retValue;
}
/* =============================================================================
// Function_Name: USBD_IFSuspendProcess
// description	: Do process for detecting Suspend
// argument		: None
// return		: STATUS_SUCCESS			Finished normally
//				  STATUS_NOT_OPENED			Not be opened yet
// flag			:
// global		:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -