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

📄 sc2413pdd.cpp-ori

📁 支持三星原产的S3C2413开发板
💻 CPP-ORI
📖 第 1 页 / 共 5 页
字号:
			{
//				HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
			}
			else
			{
				ClearEndpointInterrupt(pContext, dwEndpoint);
//				break;
			}
#else
			ClearEndpointInterrupt(pContext, dwEndpoint);
			HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
#endif
		}
	}
	
	FUNCTION_LEAVE_MSG();
}


/****************************************************************
@doc INTERNAL

@func VOID | SerUSB_InternalMapRegisterAddresses |
This routine maps the ASIC registers. 
It's an artifact of this
implementation.

@rdesc None.
****************************************************************/
static
DWORD MapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
	SETFNAME();
	FUNCTION_ENTER_MSG();

	PREFAST_DEBUGCHK(pContext);

	DEBUGCHK(g_pUDCBase == NULL);

	PBYTE   pVMem;
	DWORD   dwRet = ERROR_SUCCESS;

	// Map CSR registers.
	pVMem = (PBYTE)VirtualAlloc(0, PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);

	if (pVMem) {
		BOOL fSuccess = VirtualCopy(pVMem, (LPVOID)pContext->dwIOBase,
			pContext->dwIOLen, PAGE_READWRITE | PAGE_NOCACHE);
		if (!fSuccess) {
			VirtualFree(pVMem, 0, MEM_RELEASE);
			dwRet = GetLastError();
			DEBUGMSG(ZONE_ERROR, (_T("%s Virtual Copy: FAILED\r\n"), pszFname));
		}
		else {
			g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;

			DEBUGMSG(ZONE_INIT, (_T("%s VirtualCopy Succeeded, pVMem:%x\r\n"), 
				pszFname, pVMem));
		}
	} 
	else {
		dwRet = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("%s Virtual Alloc: FAILED\r\n"), pszFname));
	}

	FUNCTION_LEAVE_MSG();
	
	return dwRet;
}

/*++

Routine Description:

Deallocate register space.

Arguments:

None.

Return Value:

None.

--*/
static
VOID
UnmapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
	// Unmap any memory areas that we may have mapped.
	if (g_pUDCBase) {
		VirtualFree((PVOID) g_pUDCBase, 0, MEM_RELEASE);
		g_pUDCBase = NULL;
	}
}


// interrupt service routine.
static
DWORD
WINAPI
ISTMain(
		LPVOID lpParameter
		)
{
	static WORD  wcnt = 0;
	static DWORD dwtimeout;
	SETFNAME();
	FUNCTION_ENTER_MSG();

	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
	ValidateContext(pContext);

	CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);

	while (!pContext->fExitIST) {
		pContext->fRestartIST = FALSE;

		// Enable Suspend Mode in the Power Register
		SetClearReg(pContext, PWR_REG_OFFSET, SUSPEND_MODE_ENABLE_CTRL, SET);

		// Disable All Endpoint interrupts
		WriteReg(pContext, EP_INT_EN_REG_OFFSET, 0); // Disable All

		// Enable Device interrupts
		WriteReg(pContext, USB_INT_EN_REG_OFFSET, (USB_RESET_INTR | USB_SUSPEND_INTR));

		// Enable Endpoint interrupt 0
		BYTE irqEnBit = EpToIrqStatBit(0);
		SetClearReg(pContext, EP_INT_EN_REG_OFFSET, irqEnBit, SET);
		
		// Initialize Index, 050827
//		WriteReg(pContext, IDXADDR_REG_OFFSET, (BYTE) 0);	
		
		dwtimeout = INFINITE;
//		dwtimeout = 1000;
		while (TRUE) {
			DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, dwtimeout);
			if (pContext->fExitIST || pContext->fRestartIST) {
				break;
			}
#if 0
			// hmseo
			if (dwWait == WAIT_OBJECT_0) {
				wcnt = 0;
			}
			else
			{
				wcnt ++;
			}

			if ( wcnt >= 100 )
				dwtimeout = 1000;
//				dwtimeout = INFINITE;
			else
				dwtimeout = 10;
#endif
			HandleUSBEvent(pContext);
			InterruptDone(pContext->dwSysIntr);
		}

		// 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);

		// Send detach
		pContext->pfnNotify(pContext->pvMddContext, 
			UFN_MSG_BUS_EVENTS, UFN_DETACH);

		pContext->fSpeedReported = FALSE;
		pContext->attachedState = UFN_DETACH;
	}

	FUNCTION_LEAVE_MSG();

	return 0;
}


static
VOID
StartTransfer(
			  PCTRLR_PDD_CONTEXT pContext,
			  PEP_STATUS peps,
			  PSTransfer pTransfer
			  )
{
	SETFNAME();
	FUNCTION_ENTER_MSG();

	DEBUGCHK(pContext);
	PREFAST_DEBUGCHK(peps);

	DEBUGCHK(!peps->pTransfer);
	ValidateTransferDirection(pContext, peps, pTransfer);

	DEBUGMSG(ZONE_TRANSFER, (_T("%s Setting up %s transfer on ep %u for %u bytes\r\n"),
		pszFname, (pTransfer->dwFlags == USB_IN_TRANSFER) ? _T("in") : _T("out"),
		peps->dwEndPointNumber, pTransfer->cbBuffer));

	// Enable transfer interrupts.
	peps->pTransfer = pTransfer;

	if (pTransfer->dwFlags == USB_IN_TRANSFER) {
		// Must Clear both Send and Sent Stall - the HW is setting this bit 
		// during the Endpoint initialization process. It must be cleared here 
		// to insure proper operation.
		SetClearIndexedReg(pContext, peps->dwEndPointNumber, IN_CSR1_REG_OFFSET, (IN_SEND_STALL | IN_SENT_STALL), CLEAR);
		HandleTx(pContext, peps, 1);
	}
	else {
		// Set the Max Packet Size Register
		BYTE maxPacketBits = (BYTE) (peps->dwPacketSizeAssigned >> 3);
		WriteIndexedReg(pContext, peps->dwEndPointNumber, MAX_PKT_SIZE_REG_OFFSET, maxPacketBits); 

		EnableEndpointInterrupt(pContext,peps->dwEndPointNumber);

		// There may be a packet available.  If so process it...
		BYTE bEpIrqStat = ReadIndexedReg(pContext, peps->dwEndPointNumber, OUT_CSR1_REG_OFFSET);
		if  (bEpIrqStat & OUT_PACKET_READY) {
			HandleRx(pContext, peps);
		}
	}
	
	FUNCTION_LEAVE_MSG();
}


DWORD
WINAPI
UfnPdd_IssueTransfer(
	PVOID  pvPddContext,
	DWORD  dwEndpoint,
	PSTransfer pTransfer
	)
{
//	return 1;		// 050828
	SETFNAME();
	FUNCTION_ENTER_MSG();

	DEBUGCHK(EP_VALID(dwEndpoint));

	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
	ValidateContext(pContext);

//	RETAILMSG(1,(TEXT("\nPDD ")));	// 050828
	
	PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
	LOCK_ENDPOINT(peps);
	DEBUGCHK(peps->fInitialized);
	DEBUGCHK(pTransfer->cbTransferred == 0);

	DWORD dwRet = ERROR_SUCCESS;

	// Note For the HW NAKs IN requests and DOES NOT let SW
	// know that the Host is trying to send a request. SO... Start the Transfer 
	// In Now!
	// Start the Transfer
	DEBUGCHK(peps->pTransfer == NULL);
	StartTransfer(pContext, peps, pTransfer);

	UNLOCK_ENDPOINT(peps);

	FUNCTION_LEAVE_MSG();

	return dwRet;
}


DWORD
WINAPI
UfnPdd_AbortTransfer(
	PVOID		   pvPddContext,
	DWORD		   dwEndpoint,
	PSTransfer	  pTransfer
	)
{
	SETFNAME();
	FUNCTION_ENTER_MSG();

	PREFAST_DEBUGCHK(pTransfer);
	DEBUGCHK(EP_VALID(dwEndpoint));

	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
	ValidateContext(pContext);

	PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
	LOCK_ENDPOINT(peps);
	DEBUGCHK(peps->fInitialized);

	ValidateTransferDirection(pContext, peps, pTransfer);

	DEBUGCHK(pTransfer == peps->pTransfer);
	CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);

	peps->dwEpState = EP_STATE_IDLE;
	ResetEndpoint( pContext,peps);

	UNLOCK_ENDPOINT(peps);

	FUNCTION_LEAVE_MSG();

	return ERROR_SUCCESS;
}

#define CLKCON_USBD (1<<7)

volatile S3C2413_CLKPWR_REG *pCLKPWR	= NULL;		// Clock power registers (needed to enable I2S and SPI clocks)
volatile S3C2413_IOPORT_REG *pIOPregs	= NULL;

BOOL HW_USBClocks(CEDEVICE_POWER_STATE    cpsNew)
{

	pCLKPWR = (volatile S3C2413_CLKPWR_REG*)VirtualAlloc(0, sizeof(S3C2413_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!pCLKPWR)
	{
		DEBUGMSG(1, (TEXT("pCLKPWR: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if (!VirtualCopy((PVOID)pCLKPWR, (PVOID)(S3C2413_BASE_REG_PA_CLOCK_POWER >> 8), sizeof(S3C2413_CLKPWR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
	{
		DEBUGMSG(1, (TEXT("pCLKPWR: VirtualCopy failed!\r\n")));
		return(FALSE);
	}

	pIOPregs = (volatile S3C2413_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2413_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(!pIOPregs) {
		DEBUGMSG(1, (TEXT("pIOPregs: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if(!VirtualCopy((PVOID)pIOPregs, (PVOID)(S3C2413_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2413_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) 
	{
		DEBUGMSG(1, (TEXT("pIOPregs: VirtualCopy failed!\r\n")));
		return(FALSE);
	}

	if (cpsNew == D0)
	{
		//RETAILMSG(1, (TEXT("HW_USBClocks::D0 \r\n")));
		// Enable the USB Clocks
		pCLKPWR->CLKCON |= (CLKCON_USBD);
		// MISCCR: USBD Pads, Normal mode
		pIOPregs->MISCCR &= ~((1<<13)|(1<<3));	// SUSPND1 : normal mode, Use USBPAD as Device.
		// Enable USB_PULLUP on GPIO PIN (tied to USB D+) & set high
		pIOPregs->GPFCON &= ~(3<<4);	// clear GPF2
		pIOPregs->GPFCON |=  (1<<4);	// config as output
		pIOPregs->GPFDN  |=  (1<<2);	// pulldown disabled
		pIOPregs->GPFDAT |=  (1<<2);	// set high
		
	}
	else if (cpsNew == D4) 
	{
		//RETAILMSG(1, (TEXT("HW_USBClocks::D4 \r\n")));
		// Disable the USB Clocks
		pCLKPWR->CLKCON &= ~(CLKCON_USBD);
		// MISCCR: USBD Pads, Suspend mode
		pIOPregs->MISCCR |= (3<<12);
		// Disable USB_PULLUP to remove us from the bus
		pIOPregs->GPFCON &= ~(3<<4);	// clear GPF2
		pIOPregs->GPFCON |=  (1<<4);	// config as output
		pIOPregs->GPFDN  |=  (1<<2);	// pulldown disabled
		pIOPregs->GPFDAT &= ~(1<<2);	// set low
	}
	if (pIOPregs)
    {
        VirtualFree((PVOID)pIOPregs, 0, MEM_RELEASE);
        pIOPregs = NULL;
    }
    if (pCLKPWR)
    {   
        VirtualFree((PVOID)pCLKPWR, 0), MEM_RELEASE);
        pCLKPWR = NULL;
    } 
	return TRUE;
}
/////////////////////////////// jassi ////////////////////////////////


// This does not do much because there is not any way to control
// power on this controller.
static
CEDEVICE_POWER_STATE
SetPowerState(
	PCTRLR_PDD_CONTEXT	  pContext,
	CEDEVICE_POWER_STATE	cpsNew
	)
{
	SETFNAME();
	
	PREFAST_DEBUGCHK(pContext);
	DEBUGCHK(VALID_DX(cpsNew));
	ValidateContext(pContext);

	// RETAILMSG(1, (TEXT("SetPowerState.")));

	// Adjust cpsNew.
	if (cpsNew != pContext->cpsCurrent) {
		if (cpsNew == D1 || cpsNew == D2) {
			// D1 and D2 are not supported.
			cpsNew = D0;
		}
		else if (pContext->cpsCurrent == D4) {
			// D4 can only go to D0.
			//cpsNew = D0;
		}
	}

	if (cpsNew != pContext->cpsCurrent) {
		DEBUGMSG(ZONE_POWER, (_T("%s Going from D%u to D%u\r\n"),
			pszFname, pContext->cpsCurrent, cpsNew));
		
		if ( (cpsNew < pContext->cpsCurrent) && pContext->hBusAccess ) {
			SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
		}

		switch (cpsNew) {
		case D0:
			HW_USBClocks(D0);
			KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr,  
				sizeof(pContext->dwSysIntr), NULL, 0, NULL);

			if (pContext->fRunning) {
				// Cause the IST to restart.
				pContext->fRestartIST = TRUE;

				//RETAILMSG(1, (TEXT("USB::SetInterruptEvent \r\n")));
				SetInterruptEvent(pContext->dwSysIntr);
			}		   
			break;

		case D3:
			KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &pContext->dwSysIntr,  
				sizeof(pContext->dwSysIntr), NULL, 0, NULL);
			break;

		case D4:
			HW_USBClocks(D4);
			KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr,  
				sizeof(pContext->dwSysIntr), NULL, 0, NULL);
			break;
		}

		if ( (cpsNew > pContext->cpsCurrent) && pContext->hBusAccess ) {
			SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
		}

		pContext->cpsCurrent = cpsNew;
	}

	return pContext->cpsCurrent;
}


static
VOID
FreeCtrlrContext(
	PCTRLR_PDD_CONTEXT pContext
	)
{
	PREFAST_DEBUGCHK(pContext);

⌨️ 快捷键说明

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