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

📄 s3c6400otgdevice.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:

			// Unmak INT_RX_FIFO_NOT_EMPTY interrupt
			dwGINTMSK = dwGINTMSK | INT_RX_FIFO_NOT_EMPTY;
			WriteReg(pContext, GINTMSK, dwGINTMSK);
		}
	}

	WriteReg(pContext, DCTL, CLEAR_GOUTNAK);

	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 = NULL;
	DWORD dwRet = ERROR_SUCCESS;

	//System Controller registers allocation
	pContext->pSYSCONregs = (volatile S3C6400_SYSCON_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_SYSCON, sizeof(S3C6400_SYSCON_REG), FALSE);
	if (pContext->pSYSCONregs == NULL)
	{
		dwRet = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("%s DrvLib_MapIoSpace: FAILED\r\n"), pszFname));
		goto CleanUp;
	}

	//OTG Phy registers allocation
	pContext->pOTGPhyregs = (volatile OTG_PHY_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_USBOTG_PHY, sizeof(OTG_PHY_REG), FALSE);
	if (pContext->pOTGPhyregs == NULL)
	{
		dwRet = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("%s DrvLib_MapIoSpace: FAILED\r\n"), pszFname));
		goto CleanUp;
	}

	// OTG LINK registers.
	pVMem = (PBYTE)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_USBOTG_LINK, OTG_LINK_REG_SIZE, FALSE);
	if (pVMem == NULL)
	{
		dwRet = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("%s DrvLib_MapIoSpace: FAILED\r\n"), pszFname));
		goto CleanUp;
	}

	g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;
	DEBUGMSG(ZONE_INIT, (_T("%s DrvLib_MapIoSpace, pVMem:%x\r\n"), pszFname, pVMem));

	v_gBspArgs = (volatile BSP_ARGS *)DrvLib_MapIoSpace(IMAGE_SHARE_ARGS_PA_START, sizeof(BSP_ARGS), FALSE);
	if (v_gBspArgs == NULL)
	{
		dwRet = GetLastError();
		DEBUGMSG(ZONE_ERROR, (_T("%s DrvLib_MapIoSpace: FAILED\r\n"), pszFname));
		goto CleanUp;
	}

CleanUp:

	if (dwRet != ERROR_SUCCESS)
	{
		if (pContext->pSYSCONregs)
		{
			DrvLib_UnmapIoSpace((PVOID)pContext->pSYSCONregs);
			pContext->pSYSCONregs = NULL;
		}

		if (pContext->pOTGPhyregs)
		{
			DrvLib_UnmapIoSpace((PVOID)pContext->pOTGPhyregs);
			pContext->pOTGPhyregs = NULL;
		}

		if (pVMem)
		{
			DrvLib_UnmapIoSpace((PVOID)pVMem);
			pVMem = NULL;
		}
		
		if (v_gBspArgs)
    		{
			DrvLib_UnmapIoSpace((PVOID) v_gBspArgs);	
       		v_gBspArgs = NULL;
    		}
	}

	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 (pContext->pSYSCONregs)
	{
		DrvLib_UnmapIoSpace((PVOID)pContext->pSYSCONregs);
		pContext->pSYSCONregs = NULL;
	}

	if (pContext->pOTGPhyregs)
	{
		DrvLib_UnmapIoSpace((PVOID)pContext->pOTGPhyregs);
		pContext->pOTGPhyregs = NULL;
	}

	if (g_pUDCBase)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pUDCBase);
		g_pUDCBase = NULL;
	}	

	if (v_gBspArgs)
    	{
		DrvLib_UnmapIoSpace((PVOID) v_gBspArgs);	
       	v_gBspArgs = NULL;
    	}

}


// interrupt service routine.
static
DWORD
WINAPI
ISTMain(
	LPVOID lpParameter
	)
{
	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;

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

		// Enable Device General interrupts
		WriteReg(pContext, GINTSTS, INT_RESUME | INT_SDE | INT_RESET | INT_SUSPEND);	//G int pending clear
		WriteReg(pContext, GINTMSK, INT_RESUME | INT_IN_EP|INT_SDE|INT_RESET |INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY | INT_OTG);	//gint unmask

		// Enable Endpoint interrupt 0
		EnableEndpointInterrupt(pContext, 0, 0);
		EnableEndpointInterrupt(pContext, 0, 1);

		while (TRUE)
		{
			DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
			if (pContext->fExitIST || pContext->fRestartIST)
			{
				break;
			}

			if (dwWait == WAIT_OBJECT_0)
			{
 				HandleUSBEvent(pContext);
				InterruptDone(pContext->dwSysIntr);
			}
			else
			{
				DEBUGMSG(ZONE_INIT, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"), pszFname));
				break;
			}
		}

		// Send detach, moved code for reset interrupt +chandolp+
		pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
		pContext->fSpeedReported = FALSE;
		pContext->attachedState = UFN_DETACH;

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

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

		// Clear any outstanding device & endpoint interrupts
		// USB Device Interrupt Status - Write a '1' to Clear
		WriteReg(pContext, GINTSTS, INT_SDE|INT_RESET);
		// End point Interrupt Status - Write a '1' to Clear
	}

	FUNCTION_LEAVE_MSG();

	return 0;
}


static DWORD 
SDCARD_DetectIST(
	LPVOID lpParameter
	)
{
	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
	DWORD dwGOTGCTL;
       ValidateContext(pContext);

	while (1) 
	{
        	__try 
		{
            		WaitForSingleObject(v_gBspArgs->g_SDCardDetectEvent, INFINITE); 

			if(bSDMMCMSF)
	            	{
				RETAILMSG(0,(TEXT("[UFNPDD] CardState :%d, AttachState : %d\r\n"),v_gBspArgs->g_SDCardState,pContext->attachedState));

				dwGOTGCTL = ReadReg(pContext, GOTGCTL);

				if(dwGOTGCTL & (B_SESSION_VALID|A_SESSION_VALID))
				{								 
					if(v_gBspArgs->g_SDCardState== CARD_INSERTED)
					{
						RETAILMSG(1,(TEXT("[UFNPDD] SetEvent: PlugEvent(CARD_INSERTED)\r\n")));
						SetSoftDisconnect(pContext);								
						pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
						pContext->attachedState = UFN_DETACH;
						Sleep(3000);
						HW_USBClocks(pContext, D0);
					}
					else if(v_gBspArgs->g_SDCardState== CARD_REMOVED)
					{
						RETAILMSG(1,(TEXT("[UFNPDD] SetEvent: PlugEvent(CARD_REMOVED)\r\n")));
						SetSoftDisconnect(pContext);								
						pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
						pContext->attachedState = UFN_DETACH;
					}
					else
					{
						RETAILMSG(1,(TEXT("[UFNPDD] SetEvent: PlugEvent(else)\r\n")));
					}
				}
				else
				{
					RETAILMSG(1,(TEXT("[UFNPDD] SetEvent: PlugEvent_ Cable not Connected\r\n")));
				}
			}
			else
			{
				RETAILMSG(1,(TEXT("[UFNPDD] SetEvent: PlugEvent_ Not SDMMC\r\n")));	
			}
		}
		__except(EXCEPTION_EXECUTE_HANDLER) 
		{
            		RETAILMSG(1,(TEXT("[UFNPDD] !!! SDCARD_DetectTherad: 0x%X !!!\r\n"), GetExceptionCode() ));
		}
    	}
	return 0;
}


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

	DEBUGCHK(pContext);
	PREFAST_DEBUGCHK(peps);

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

	LOCK_ENDPOINT(peps);
	FUNCTION_ENTER_MSG();

	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;
	DWORD dwEndpoint = peps->dwEndpointNumber;

	if (pTransfer->dwFlags == USB_IN_TRANSFER)
	{
		if (peps->dwEndpointNumber == 0)
		{
			DWORD dwDIEPINT0 = ReadReg(pContext, DIEPINT0);
			if (dwDIEPINT0 & XFERCOPMPL)
			{
				WriteReg(pContext, DIEPINT0, XFERCOPMPL);
			}
			HandleTx(pContext, peps, 0);
		}
		else
		{
			DWORD dwDIEPINT = ReadEPSpecificReg(pContext, dwEndpoint, DIEPINT);

			if (dwDIEPINT & XFERCOPMPL)
			{
				WriteEPSpecificReg(pContext, dwEndpoint, DIEPINT, XFERCOPMPL);
			}
			if ((pTransfer->cbBuffer == 0) && (USBClassInfo == USB_RNDIS))
			{
				//RETAILMSG(1,(TEXT("ZERO\r\n")));
				//In RNDIS Class, Somtimes zero length packet should be send. 
				//But zero length packet don`t have to be send in Serial Class. It is cause of file trasfer hanging.
				WriteEPSpecificReg(pContext, peps->dwEndpointNumber, DIEPTSIZ, 1<<29|1<<19|0<<0);
				WriteEPSpecificReg(pContext, peps->dwEndpointNumber, DIEPCTL, 1<<31|1<<26|2<<18|1<<15|1<<11|peps->dwPacketSizeAssigned);
			}
			else
			{
				EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
			}
		}
	}
	else
	{
		if (peps->dwEndpointNumber == 0)
		{
			WriteReg(pContext, DOEPTSIZ0, 1<<19 | pContext->dwEp0MaxPktSize);
			WriteReg(pContext, DOEPCTL0, (1<<31)|(1<<26)|(0<<0));
		}
		else
		{
			WriteEPSpecificReg(pContext, dwEndpoint, DOEPTSIZ, 1<<19 | peps->dwPacketSizeAssigned);
			WriteEPSpecificReg(pContext, dwEndpoint, DOEPCTL, 1<<31|1<<26|2<<18|1<<15 |peps->dwPacketSizeAssigned);

			EnableEndpointInterrupt(pContext, peps->dwEndpointNumber, peps->dwDirectionAssigned);

			DWORD dwGintsts = ReadReg(pContext, GINTSTS);

			if (pContext->CntValue != 0)
			{
                    		HandleEndpointEvent(pContext, peps->dwEndpointNumber, 1);
			}
		}
	}

	FUNCTION_LEAVE_MSG();
	UNLOCK_ENDPOINT(peps);
}

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

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

	if (dwEndpoint == 0)
	{
		pContext->Ep0State = EP0_STATE_IDLE;
	}

	ResetEndpoint( pContext,peps);

	UNLOCK_ENDPOINT(peps);

	FUNCTION_LEAVE_MSG();

	return ERROR_SUCCESS;
}


BOOL HW_USBClocks(
	PCTRLR_PDD_CONTEXT      pContext,
	CEDEVICE_POWER_STATE    cpsNew)
{
	if (cpsNew == D0)
	{
		RETAILMSG(0,(TEXT("[UFNPDD] USB_POWER : D0\r\n")));
		ClearSoftDisconnect(pContext);
		pContext->pSYSCONregs->HCLK_GATE |= (1<<20); //OTG HClk enable
		ResetDevice(pContext);

		DWORD dwGOTGCTL = ReadReg(pContext, GOTGCTL);
		if(!(dwGOTGCTL & (B_SESSION_VALID)))
		{
			Delay(100);  //for OTG cable detahced state. 1000
//			Sleep(10);
		}
	}

	else if (cpsNew == D4)
	{
		RETAILMSG(0,(TEXT("[UFNPDD] USB_POWER : D4\r\n")));
		SetSoftDisconnect(pContext);		
		pContext->pOTGPhyregs->OPHYPWR = 0x3;  			// pll_powerdown, suspend mode	
		pContext->pSYSCONregs->HCLK_GATE &= ~(1<<20); 	//OTG HClk disable
	}
	return TRUE;
}

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

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

⌨️ 快捷键说明

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