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

📄 sc2413pdd.cpp-ori

📁 支持三星原产的S3C2413开发板
💻 CPP-ORI
📖 第 1 页 / 共 5 页
字号:
	// it is best to clear all IN and OUT bits associated with endpoint. 
	DWORD dwEndpoint = peps->dwEndPointNumber;
	if(dwEndpoint == 0 ){
		// Clear all EP0 Status bits
		WriteIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET,
			(SERVICED_OUT_PKY_RDY | SERVICED_SETUP_END | DATA_END));		// 050827

	}
	else if(dwEndpoint < ENDPOINT_COUNT){

		// Clear the desired Endpoint - Clear both the In & Out Status bits
		BYTE bRegIn;
		BYTE bRegOut;
		if(peps->fInitialized){
			PREFAST_DEBUGCHK(peps->fInitialized); // Give prefast a clue.
			// First Read the CSR2 Reg bit so that it can be restored
			bRegIn = ReadIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET);
			bRegOut = ReadIndexedReg(pContext, dwEndpoint, OUT_CSR2_REG_OFFSET);
		}
		// Clear the in register - Must set the Mode_in to IN
		WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET,(SET_MODE_IN | IN_DMA_INT_DISABLE));
//		WriteIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET,(IN_CLR_DATA_TOGGLE));		// 050828-1
		WriteIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET, ( IN_CLR_DATA_TOGGLE | FLUSH_IN_FIFO));
//		while((ReadIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET) & FLUSH_IN_FIFO)!=0);

		// Clear the Out register  - Must set the Mode_in to OUT
//		WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, (IN_DMA_INT_DISABLE)); // 050828-1
		WriteIndexedReg(pContext, dwEndpoint, OUT_CSR1_REG_OFFSET, (FLUSH_OUT_FIFO | OUT_CLR_DATA_TOGGLE));
//		while((ReadIndexedReg(pContext, dwEndpoint, OUT_CSR1_REG_OFFSET) & FLUSH_OUT_FIFO)!=0);
		WriteIndexedReg(pContext, dwEndpoint,  OUT_CSR2_REG_OFFSET, OUT_DMA_INT_DISABLE);
#if 0	// 050828-1
		if(peps->fInitialized){
			// Set the Mode_In, ISO and other Modality type bits back to the way it was - this allows 
			// ResetEndpoint to be called without having to re-init the endpoint.
			WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, bRegIn);
			WriteIndexedReg(pContext, dwEndpoint, OUT_CSR2_REG_OFFSET, bRegOut);
		}
#endif		 
// hmseo.....
		// Clear and disable interrupt
//		WriteReg(pContext, EP_INT_REG_OFFSET, EpToIrqStatBit(peps->dwEndPointNumber));
		DisableEndpointInterrupt(pContext, peps->dwEndPointNumber);		// 050828-1
	}
	else {
		DEBUGCHK(FALSE);
	}

	// Clear any outstanding Interrupts
	// Note that Endpoint 0 WILL NOT BE DISABLED
//	DisableEndpointInterrupt(pContext, peps->dwEndPointNumber);		// 050828-1

	FUNCTION_LEAVE_MSG();
}



// Reset the device and EP0.
static
VOID
ResetDevice(
			PCTRLR_PDD_CONTEXT pContext
			)
{
	SETFNAME();
	FUNCTION_ENTER_MSG();

	DEBUGCHK(IS_VALID_SC2413_CONTEXT(pContext));

	// Disable Device  interrupts - write Zeros to Disable
	WriteReg(pContext, USB_INT_EN_REG_OFFSET, 0 );

	// Disable endpoint interrupts - write Zeros to Disable
	WriteReg(pContext, EP_INT_EN_REG_OFFSET, 0);

	// Clear any outstanding device & endpoint interrupts
	// USB Device Interrupt Status - Write a '1' to Clear 
	WriteReg(pContext, USB_INT_REG_OFFSET, 
		(USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
	// End point Interrupt Status - Write a '1' to Clear
	WriteReg(pContext, EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);

	// Reset all endpoints
	for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) {
		EP_STATUS *peps = GetEpStatus(pContext, dwEpIdx);
		ResetEndpoint(pContext, peps);
	}

	FUNCTION_LEAVE_MSG();
}


static
VOID
CompleteTransfer(
				 PCTRLR_PDD_CONTEXT pContext,
				 PEP_STATUS peps,
				 DWORD dwUsbError
				 )
{
	SETFNAME();
	FUNCTION_ENTER_MSG();

	PSTransfer pTransfer = peps->pTransfer;
	peps->pTransfer = NULL;

	pTransfer->dwUsbError = dwUsbError;
	pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_TRANSFER_COMPLETE, 
		(DWORD) pTransfer);

	FUNCTION_LEAVE_MSG();
}


#ifdef DEBUG
static
VOID
ValidateTransferDirection(
						  PCTRLR_PDD_CONTEXT pContext,
						  PEP_STATUS peps,
						  PSTransfer pTransfer
						  )
{
	DEBUGCHK(pContext);
	PREFAST_DEBUGCHK(peps);
	PREFAST_DEBUGCHK(pTransfer);

	if (peps->dwEndPointNumber != 0) {
		DEBUGCHK(peps->dwDirectionAssigned == pTransfer->dwFlags);
	}
}
#else
#define ValidateTransferDirection(ptr1, ptr2, ptr3)
#endif


// Read data from an endpoint.
static
VOID
HandleRx(
		 PCTRLR_PDD_CONTEXT	   pContext,
		 PEP_STATUS peps
		 )
{
	DWORD dwBytesRead = 0;
	BOOL fCompleted = FALSE;
	DWORD dwStatus = ERROR_GEN_FAILURE;
	DWORD dwEndpoint = peps->dwEndPointNumber;

	SETFNAME();

	PSTransfer pTransfer = peps->pTransfer;

	if (pTransfer) {
		FUNCTION_ENTER_MSG();

		DEBUGCHK(pTransfer->dwFlags == USB_OUT_TRANSFER);
		DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);

		ValidateTransferDirection(pContext, peps, pTransfer);

		DEBUGCHK(peps->fInitialized);

		DWORD cbToRead = 0;
		volatile ULONG *pulFifoReg = _GetDataRegister(dwEndpoint);
//		RETAILMSG(1,(TEXT("R:0x%x\n"),*pulFifoReg));	// charlie
		DEBUGCHK(pulFifoReg != NULL);

		DWORD dwCurrentPermissions = GetCurrentPermissions();
		SetProcPermissions(pTransfer->dwCallerPermissions);

		__try {
//			while(TRUE) {
				PBYTE  pbBuffer =  (PBYTE)pTransfer->pvBuffer + pTransfer->cbTransferred;
				PUSB_DEVICE_REQUEST udr = (PUSB_DEVICE_REQUEST) pbBuffer;

				DWORD  cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;
				DWORD  cbRead = 0;
				DWORD  cbFifo = ReadIndexedReg(pContext, dwEndpoint, OUT_FIFO_CNT1_REG_OFFSET);

				// Read From  the FIFO
				dwBytesRead = 0;
				cbToRead = min(cbFifo, cbBuffer);
				for (dwBytesRead = 0; dwBytesRead < cbToRead ; dwBytesRead++) {
					pbBuffer [dwBytesRead] = (UCHAR) *pulFifoReg;
				}
			
				if(dwBytesRead < peps->dwPacketSizeAssigned) {
					// This is a short packet check to signal end of transfer
					fCompleted = TRUE;
					dwStatus = UFN_NO_ERROR;
				}

				cbRead = dwBytesRead;
				DEBUGCHK(cbRead <= pTransfer->cbBuffer - pTransfer->cbTransferred);
				pTransfer->cbTransferred += cbRead;

				if (pTransfer->cbTransferred == pTransfer->cbBuffer) {		// fill buffer... buffer size(0x2000)
					fCompleted = TRUE;
					dwStatus = UFN_NO_ERROR;
				}

				if (dwEndpoint != 0) 
				{
					//Clear Receive Packet Complete - Allow next packet to come in.  
					BYTE bEpIrqStat = ReadIndexedReg(pContext, peps->dwEndPointNumber, OUT_CSR1_REG_OFFSET);
					if (bEpIrqStat & OUT_PACKET_READY) {
						SetClearIndexedReg(pContext, dwEndpoint, OUT_CSR1_REG_OFFSET, OUT_PACKET_READY, CLEAR);
					}
//					if ( fCompleted == TRUE ) break;
				}
#if RNDIS==1		// charlie, RNDIS							
				else
				{
					BYTE bEP0IrqStatus = ReadIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET);
					if (bEP0IrqStatus & EP0_OUT_PACKET_RDY) 
					{
						// 050827
						if (fCompleted) {
							SetClearIndexedReg(pContext,0,EP0_CSR_REG_OFFSET,
							   DATA_END | SERVICED_OUT_PKY_RDY, SET);
						}
						else
						{
					   		SetClearIndexedReg(pContext,0,EP0_CSR_REG_OFFSET,
								SERVICED_OUT_PKY_RDY, SET);
						}
					}
				}
#endif
				/*
				BYTE bEpIrqStat = ReadIndexedReg(pContext, peps->dwEndPointNumber, OUT_CSR1_REG_OFFSET);
				if (bEpIrqStat & OUT_PACKET_READY) 
				{
					continue;
				}
				else
				{
					break;
				}
				*/
//			}
		}
		__except(EXCEPTION_EXECUTE_HANDLER) {
			DEBUGMSG(ZONE_ERROR, (_T("%s Exception!\r\n"), pszFname));
			fCompleted = TRUE;
			dwStatus = UFN_CLIENT_BUFFER_ERROR;
		}

		SetProcPermissions(dwCurrentPermissions);
	}   
	else {
		goto EXIT;
	}
	
	DEBUGMSG(ZONE_RECEIVE, (_T("%s Rx Ep%x BufferSize=%u,Xfrd=%u \r\n"), 
		pszFname, dwEndpoint, pTransfer->cbBuffer, pTransfer->cbTransferred));

	if (fCompleted) {
		// Disable transfer interrupts until another transfer is issued.
#if 1	// 050827
		if (peps->dwEndPointNumber != 0) 
		{
//			RETAILMSG(1,(TEXT("RE ")));
			DisableEndpointInterrupt(pContext, peps->dwEndPointNumber);
			ClearEndpointInterrupt(pContext, peps->dwEndPointNumber);
		}
#endif
		CompleteTransfer(pContext, peps, dwStatus);

		DEBUGMSG(ZONE_RECEIVE, (_T("%s RxDone Ep%x BufferSize=%u,Xfrd=%u \r\n"), 
			pszFname, dwEndpoint,pTransfer->cbBuffer, pTransfer->cbTransferred));
	}

EXIT:
	FUNCTION_LEAVE_MSG();
}


// Write data to an endpoint.
static VOID
HandleTx(
		 PCTRLR_PDD_CONTEXT	   pContext,
		 PEP_STATUS peps,
		 BOOL fEnableInterrupts
		 )
{
	SETFNAME();
	DEBUGCHK(pContext);
	PREFAST_DEBUGCHK(peps);

	// This routine can be entered from both ISTMain and MDD/Client threads so
	// need critical section.

	FUNCTION_ENTER_MSG();

	BOOL fCompleted = FALSE;
	PSTransfer pTransfer = peps->pTransfer;
	DWORD dwStatus = ERROR_GEN_FAILURE;
	DEBUGCHK(peps->fInitialized);
	DWORD dwEndpoint = peps->dwEndPointNumber;

	if (pTransfer) {
		ValidateTransferDirection(pContext, peps, pTransfer);

		DEBUGCHK(pTransfer->dwFlags == USB_IN_TRANSFER);
		DEBUGCHK(pTransfer->dwUsbError == UFN_NOT_COMPLETE_ERROR);

		DWORD dwCurrentPermissions = GetCurrentPermissions();
		SetProcPermissions(pTransfer->dwCallerPermissions);

		// Transfer is ready
		__try {
			PBYTE pbBuffer = (PBYTE) pTransfer->pvBuffer + pTransfer->cbTransferred;
			DWORD cbBuffer = pTransfer->cbBuffer - pTransfer->cbTransferred;

			volatile ULONG *pulFifoReg = _GetDataRegister(dwEndpoint);
//			RETAILMSG(1,(TEXT("T:0x%x\n"),*pulFifoReg));	// charlie
			BYTE bValToWrite = 0;

			DWORD cbWritten = 0;

			// Min of input byte count and supported size
			DWORD cbToWrite = min(cbBuffer, peps->dwPacketSizeAssigned);
			BYTE bRegStatus = ReadIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET);

			if (dwEndpoint == 0) {
				for (cbWritten = 0; cbWritten < cbToWrite; cbWritten++) {
					*pulFifoReg = (ULONG)*pbBuffer++;
				}

				/* We can complete on a packet which is full. We need to wait till
				* next time and generate a zero length packet, so only complete
				* if we're at the end and it is not the max packet size.
				*/
				pTransfer->cbTransferred += cbWritten;
				if (pTransfer->cbTransferred == pTransfer->cbBuffer) {
					dwStatus = UFN_NO_ERROR;

					if(cbWritten != peps->dwPacketSizeAssigned){
						fCompleted = TRUE;
						peps->dwEpState = EP_STATE_IDLE;
						bValToWrite |= DATA_END;
						bValToWrite |= EP0_IN_PACKET_RDY;		// To confirm, 050827
					}

				}
				/* Update the register - Set the IPR bit and possibly data end*/
				if( (cbWritten >0) || (pTransfer->cbBuffer == 0) ) {
					bValToWrite |= EP0_IN_PACKET_RDY;
				}
				// Also set IPR if a 0 byte packet needs to go out.
				else if( (pTransfer->cbTransferred == pTransfer->cbBuffer) &&
						 (pTransfer->cbBuffer % peps->dwPacketSizeAssigned == 0) ) {
					bValToWrite |= EP0_IN_PACKET_RDY;
				}
				
				SetClearIndexedReg(pContext, dwEndpoint, EP0_CSR_REG_OFFSET, bValToWrite, SET);
			}
			else if (dwEndpoint < ENDPOINT_COUNT) {
				DEBUGMSG(ZONE_SEND, (_T("%s Tx on EP %u , Bytes = %u\r\n"), 
					pszFname, dwEndpoint,cbToWrite));

				// Enable Interrupts before writing to the FIFO. This insures
				// That any interrupts generated because of the write will be
				// "latched"
				if (fEnableInterrupts) 
					EnableEndpointInterrupt(pContext,dwEndpoint);

				// Write to the FIFO directly to send the bytes.
				for (cbWritten = 0; cbWritten < cbToWrite; cbWritten++) {
					*pulFifoReg = (ULONG) *pbBuffer++;
				}
#if 0			  
		   		pTransfer->cbTransferred += cbWritten;
				if (pTransfer->cbTransferred == pTransfer->cbBuffer) {
					dwStatus = UFN_NO_ERROR;

					if(cbWritten != peps->dwPacketSizeAssigned){
						fCompleted = TRUE;
						peps->dwEpState = EP_STATE_IDLE;
						bValToWrite |= DATA_END;
						bValToWrite |= IN_PACKET_READY;		// To confirm, 050827
					}

				}
				/* Update the register - Set the IPR bit and possibly data end*/
				if( (cbWritten >0) || (pTransfer->cbBuffer == 0) ) {
					bValToWrite |= IN_PACKET_READY;
				}
				// Also set IPR if a 0 byte packet needs to go out.
				else if( (pTransfer->cbTransferred == pTransfer->cbBuffer) &&
						 (pTransfer->cbBuffer % peps->dwPacketSizeAssigned == 0) ) {
					bValToWrite |= IN_PACKET_READY;
				}
				
				SetClearIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET, bValToWrite, SET);
				
#else
				// Update the Transfered Count
				pTransfer->cbTransferred += cbWritten;		// 050828-2

				// By Placing the check for packet complete here, before
				// cbTransferred is updated, there is a 1 interrupt cycle delay
				// That is complete is not declared until the data has actually
				// been ACKd (TPC set) by the host
				if ( (pTransfer->cbTransferred == pTransfer->cbBuffer) || (cbWritten == 0) ){
					fCompleted = TRUE;
					dwStatus = UFN_NO_ERROR;
//					RETAILMSG(1,(TEXT("C%d,%d "),cbWritten,pTransfer->cbTransferred));		// 050828-2
//					SetClearIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET, IN_PACKET_READY, SET);		// 050828-2
				}
//				if ( cbWritten != 0 )
				{
					/* Set In Packet Ready , this will Tells the HW the FIFO is 
					ready to be transitted to be sent
					*/
					SetClearIndexedReg(pContext, dwEndpoint, IN_CSR1_REG_OFFSET, IN_PACKET_READY, SET);
				}
#endif				
			}
		}
		__except(EXCEPTION_EXECUTE_HANDLER) {
			DEBUGMSG(ZONE_ERROR, (_T("%s Exception!\r\n"), pszFname));
			fCompleted = TRUE;
			dwStatus = UFN_CLIENT_BUFFER_ERROR;
		}

		SetProcPermissions(dwCurrentPermissions);
	}   
	else {
		// It is possible for an interrupt to come in while still in this 
		// function for first pass of transfer. If this happens it is possible
		// to complete the transfer and have that interrupt be unnecessary
		// so... just ignore it.
		goto EXIT;
	}
	
//	RETAILMSG(1, (_T("B:%d, %d"),pTransfer->cbBuffer, pTransfer->cbTransferred));
	
	if (fCompleted) {
		// Disable transfer interrupts until another transfer is issued.
//		RETAILMSG(1,(TEXT("TE ")));
#if 0	// 050827		, 050828
		if (peps->dwEndPointNumber != 0) {
			DisableEndpointInterrupt(pContext, peps->dwEndPointNumber);
			ClearEndpointInterrupt(pContext, peps->dwEndPointNumber);
		}
#endif
		CompleteTransfer(pContext, peps, dwStatus);
		DEBUGMSG(ZONE_SEND, (_T("%s Tx Done  Ep%x %u\r\n"), pszFname, 
			dwEndpoint, dwStatus));
	}
	else{
		DEBUGMSG(ZONE_SEND, (_T("%s Tx EP%x BufferSize=%u,Xfrd=%u \r\n"), 
			pszFname, dwEndpoint, pTransfer->cbBuffer, pTransfer->cbTransferred));
	}

EXIT:
	FUNCTION_LEAVE_MSG();
}


// Process an endpoint interrupt.  Call interrupt-specific handler.
static
VOID
HandleEndpointEvent(
					PCTRLR_PDD_CONTEXT pContext,
					DWORD			dwEndpoint,
					DWORD			epIrqStat

⌨️ 快捷键说明

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