📄 s3c6400otgdevice.cpp
字号:
// 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 + -