?? s3c6410otgdevice.cpp
字號:
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
#if TEST_MODE_SUPPORT
volatile DWORD dwDCTL;
#endif
DWORD dwGintsts = ReadReg(GINTSTS);
DWORD dwDaint = ReadReg(DAINT);
DWORD dwDaintMsk = ReadReg(DAINTMSK);
if (dwGintsts & (INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND | INT_OTG))
{
HandleUSBBusIrq(pContext, dwGintsts);
}
if (dwGintsts & INT_OUT_EP)
{
if (dwDaint & EP0_OUT_INT)
{
volatile DWORD dwDoepint0 = ReadReg(DOEPINT0);
WriteReg(DOEPINT0, dwDoepint0);
if (dwDoepint0 & XFER_COMPLETE)
{
HandleEndpoint0Event(pContext);
}
if (dwDoepint0 & SETUP_PHASE_DONE)
{
HandleEndpoint0Event(pContext);
}
}
for(DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++ dwEndpoint)
{
DWORD dwEpBit = EpToIrqStatBit(dwEndpoint) << ENDPOINT_COUNT;
if (dwDaint & dwEpBit)
{
volatile DWORD dwDoepint = ReadEPSpecificReg(dwEndpoint, DOEPINT);
WriteEPSpecificReg(dwEndpoint, DOEPINT, dwDoepint);
if (dwDoepint & XFER_COMPLETE)
{
HandleOutEvent(pContext, dwEndpoint);
}
}
}
}
if (dwGintsts & INT_IN_EP)
{
if (dwDaint & EP0_IN_INT)
{
volatile DWORD dwDiepint0 = ReadReg(DIEPINT0);
WriteReg(DIEPINT0, dwDiepint0);
if (dwDiepint0 & XFER_COMPLETE)
{
HandleEndpoint0Event(pContext);
}
if (dwDiepint0 & TIMEOUT_CONDITION)
{
RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Time Out EP0\r\n")));
SetClearReg(DCTL, CLEAR_GNPINNAK, SET);
}
}
for(DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++ dwEndpoint)
{
DWORD dwEpBit = EpToIrqStatBit(dwEndpoint);
if ((dwDaint & dwEpBit) && (dwDaintMsk & (0x1<<dwEndpoint)))
{
volatile DWORD dwDiepint = ReadEPSpecificReg(dwEndpoint, DIEPINT);
WriteEPSpecificReg(dwEndpoint, DIEPINT, dwDiepint);
if (dwDiepint & IN_TKN_RECEIVED)
{
HandleInEvent(pContext, dwEndpoint);
}
if (dwDiepint & XFER_COMPLETE)
{
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
pContext->dwXmittingEP &= ~(1<<dwEndpoint);
peps->pTransfer->cbTransferred += peps->pTransfer->cbBuffer;
DisableEndpointInterrupt(pContext, peps->dwEndpointNumber, peps->dwDirectionAssigned);
CompleteTransfer(pContext, peps, UFN_NO_ERROR);
UNLOCK_ENDPOINT(peps);
}
if (dwDiepint & TIMEOUT_CONDITION)
{
RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Time Out EP%d\r\n"),dwEndpoint));
RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Transmit Ready Count : %d\r\n"), pContext->dwXmitReadyCnt));
RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD] Transmitting EP 0x%x : %d\r\n"), dwEndpoint, pContext->dwXmittingEP));
for(DWORD dwEndpoint = 0; dwEndpoint < ENDPOINT_COUNT; ++dwEndpoint)
{
if(pContext->dwInEPRunning[dwEndpoint])
{
RETAILMSG(UFN_ZONE_WARNING,(_T("[UFNPDD]EP%d is running\r\n"),dwEndpoint));
}
}
SetClearReg(DCTL, CLEAR_GNPINNAK, SET);
}
}
}
}
#if TEST_MODE_SUPPORT
dwDCTL = ReadReg( DCTL);
dwDCTL = dwDCTL & (TEST_MODE_MASK) | CLEAR_GOUTNAK;
WriteReg(DCTL, dwDCTL);
#endif
SetClearReg(DCTL, CLEAR_GNPINNAK, SET);
FUNCTION_LEAVE_MSG();
}
static
DWORD MapRegisterSet(
PCTRLR_PDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
DEBUGCHK(g_pUDCBase == NULL);
PBYTE pVMem = NULL;
DWORD dwRet = ERROR_SUCCESS;
PHYSICAL_ADDRESS ioPhysicalBase = {0,0};
//System Controller registers allocation
ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;
pContext->pSYSCONregs = (volatile S3C6410_SYSCON_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_SYSCON_REG), FALSE);
if (pContext->pSYSCONregs == NULL)
{
dwRet = GetLastError();
RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
goto CleanUp;
}
// OTG LINK registers.
ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_USBOTG_LINK;
pVMem = (PBYTE)MmMapIoSpace(ioPhysicalBase, OTG_LINK_REG_SIZE, FALSE);
if (pVMem == NULL)
{
dwRet = GetLastError();
RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
goto CleanUp;
}
g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;
DEBUGMSG(UFN_ZONE_INIT, (_T("%s MmMapIoSpace, pVMem:%x\r\n"), pszFname, pVMem));
ioPhysicalBase.LowPart = IMAGE_SHARE_ARGS_PA_START;
v_gBspArgs = (volatile BSP_ARGS *)MmMapIoSpace(ioPhysicalBase, sizeof(BSP_ARGS), FALSE);
if (v_gBspArgs == NULL)
{
dwRet = GetLastError();
RETAILMSG(UFN_ZONE_ERROR, (_T("%s MmMapIoSpace: FAILED\r\n"), pszFname));
goto CleanUp;
}
CleanUp:
if (dwRet != ERROR_SUCCESS)
{
if (pContext->pSYSCONregs)
{
MmUnmapIoSpace((PVOID)pContext->pSYSCONregs, sizeof(S3C6410_SYSCON_REG));
pContext->pSYSCONregs = NULL;
}
if (pVMem)
{
MmUnmapIoSpace((PVOID)pVMem, OTG_LINK_REG_SIZE);
pVMem = NULL;
}
if (v_gBspArgs)
{
MmUnmapIoSpace((PVOID) v_gBspArgs, sizeof(BSP_ARGS));
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)
{
MmUnmapIoSpace((PVOID)pContext->pSYSCONregs, sizeof(S3C6410_SYSCON_REG));
pContext->pSYSCONregs = NULL;
}
if (g_pUDCBase)
{
MmUnmapIoSpace((PVOID)(g_pUDCBase - BASE_REGISTER_OFFSET), OTG_LINK_REG_SIZE);
g_pUDCBase = NULL;
}
if (v_gBspArgs)
{
MmUnmapIoSpace((PVOID) v_gBspArgs, sizeof(BSP_ARGS));
v_gBspArgs = NULL;
}
}
// Interrupt thread 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(DAINTMSK, 0); // Disable All Endpoint
// Clear any outstanding device & endpoint interrupts
// USB Device Interrupt Status - Write a '1' to Clear
WriteReg(GINTSTS, INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND);
// Enable Device General interrupts
WriteReg(GINTMSK, INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND | INT_OTG);
// Enable Endpoint0 interrupt
EnableEndpointInterrupt(pContext, 0, USB_IN_TRANSFER);
EnableEndpointInterrupt(pContext, 0, USB_OUT_TRANSFER);
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(UFN_ZONE_INIT, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"), pszFname));
break;
}
}
// Notify Detach Event to MDD
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(GINTMSK, 0);
// Disable endpoint interrupts - write Zeros to Disable
WriteReg(DAINTMSK, 0);
}
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);
LOCK_ENDPOINT(peps);
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 (dwEndpoint == 0)
{
DWORD dwDIEPINT0 = ReadReg(DIEPINT0);
if (dwDIEPINT0 & XFERCOPMPL)
{
WriteReg(DIEPINT0, XFERCOPMPL);
}
memcpy( pContext->pVAddrEP[0][IN_EP] ,pTransfer->pvBuffer, pTransfer->cbBuffer);
WatiForTxFIFOEmpty(100);
WriteReg(DIEPDMA0, pContext->pPAddrEP[0][IN_EP]);
if(pTransfer->cbBuffer >= pContext->dwEp0MaxPktSize)
{
WriteReg(DIEPTSIZ0, 1<<PACKET_COUTNT_IDX | pContext->dwEp0MaxPktSize);
WriteReg(DIEPCTL0, EP_ENABLE | CLEAR_NAK | 1<<NEXT_EP_IDX | EP0_MAX_PK_SIZ);
}
else
{
WriteReg(DIEPTSIZ0, 1<<PACKET_COUTNT_IDX | pTransfer->cbBuffer);
WriteReg(DIEPCTL0, EP_ENABLE | CLEAR_NAK | 1<<NEXT_EP_IDX | EP0_MAX_PK_SIZ);
}
}
else
{
DWORD dwDIEPINT = ReadEPSpecificReg(dwEndpoint, DIEPINT);
if (dwDIEPINT & XFERCOPMPL)
{
WriteEPSpecificReg(dwEndpoint, DIEPINT, XFERCOPMPL);
}
memcpy(pContext->pVAddrEP[dwEndpoint][IN_EP] ,pTransfer->pvBuffer, pTransfer->cbBuffer);
WriteReg(DIEPMSK, IN_TKN_RECEIVED | TIMEOUT_CONDITION | XFER_COMPLETE);
EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
pContext->dwXmitReadyCnt++;
pContext->dwInEPRunning[dwEndpoint] = pContext->dwXmitReadyCnt;
}
}
else //USB_OUT_TRANSFER
{
if (dwEndpoint == 0)
{
WriteReg(DOEPDMA0, pContext->pPAddrEP[0][OUT_EP]);
WriteReg(DOEPTSIZ0, 1<<PACKET_COUTNT_IDX | pContext->dwEp0MaxPktSize);
WriteReg(DOEPCTL0, EP_ENABLE | CLEAR_NAK | EP0_MAX_PK_SIZ);
}
else
{
pContext->dwPipelinedEP = dwEndpoint;
EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
if( pContext->dwUSBClassInfo != USB_MSF)
{
if(pContext->bOutEPDMAStartFlag == FALSE)
{
pContext->dwPipelinedXferSize = pTransfer->cbBuffer;
pContext->dwPipelinedPktCnt = pContext->dwPipelinedXferSize / peps->dwPacketSizeAssigned;
pContext->bOutEPDMAStartFlag = TRUE;
EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
WriteEPSpecificReg(dwEndpoint, DOEPDMA, pContext->pPAddrEP[dwEndpoint][pContext->dwPipelinedStrIdx]);
WriteEPSpecificReg(dwEndpoint, DOEPTSIZ, pContext->dwPipelinedPktCnt<<PACKET_COUTNT_IDX | pContext->dwPipelinedXferSize);
WriteEPSpecificReg(dwEndpoint, DOEPCTL, EP_ENABLE | CLEAR_NAK | SET_TYPE_BULK | USB_ACT_EP | peps->dwPacketSizeAssigned);
}
if(pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx])
{
RETAILMSG(UFN_ZONE_WARNING,(TEXT("Ring buffer is buffering... Late processing!!!\r\n")));
memcpy(pTransfer->pvBuffer, \
pContext->pVAddrEP[dwEndpoint][pContext->dwPipelinedEndIdx] , \
pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx]);
pTransfer->cbTransferred += pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx];
pContext->dwPipelinedXfered[dwEndpoint][pContext->dwPipelinedEndIdx] = 0;
pContext->dwPipelinedEndIdx = GET_NEXT_PF_IDX(pContext->dwPipelinedEndIdx);
pContext->dwPipelinedEP = 0;
if(pContext->bRingBufferFull)
{
if(pContext->dwPipelinedStrIdx != GET_PREV_PF_IDX(pContext->dwPipelinedEndIdx))
{
RETAILMSG(UFN_ZONE_WARNING,(TEXT("ERROR : Ring State is not valud(Str : %d, End : %d)\r\n"), pContext->dwPipelinedStrIdx, GET_PREV_PF_IDX(pContext->dwPipelinedEndIdx)));
}
pContext->bRingBufferFull = FALSE;
EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -