📄 pdd.c
字号:
}
pPdd->ep[mapped_epNum]->pTransfer=NULL;
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
LOCK();
DEBUGMSG(0, (TEXT("IN %s Completed at ep %d\r\n"),
pTransfer->dwUsbError == UFN_NO_ERROR ? TEXT("Normal") : TEXT("Cancel"),
i));
}
}
else // (pTransfer&&pPdd->qhbuffer->qh[i*2+1].dtd.status!=0x80)
{
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));
}
} // else if (edptcomp.ETCE&(1<<i))
UNLOCK();
}
/*
* Function : USBControllerRun
*
* Description: This sets USB controller to either run or halted
*
* Input :
* BOOL bRunMode -- if TRUE, then set running, else set stopped
*
* Output:
* void
*
* Return:
* ERROR_SUCCESS - okay, mode set
* ERROR_GEN_FAILURE -- couldn't set the mode for some reason
*
*
* Function waits until controller is stopped or started.
*/
static DWORD USBControllerRun( CSP_USB_REGS *pRegs, BOOL bRunMode )
{
USB_USBCMD_T cmd;
USB_USBMODE_T mode;
DWORD *pTmpCmd = (DWORD*)&cmd;
DWORD *pTmpMode = (DWORD*)&mode;
*pTmpCmd = INREG32(&pRegs->OTG.USBCMD);
if ( bRunMode )
{
DEBUGMSG(1,(TEXT("Start USB controller (RS=%d -> RS=1)\r\n"), cmd.RS));
cmd.RS = 1;
}
else
{
DEBUGMSG(1,(TEXT("Stop USB controller (RS=%d -> RS=0)\r\n"), cmd.RS));
cmd.RS = 0;
}
OUTREG32(&pRegs->OTG.USBCMD,*pTmpCmd);
*pTmpMode = INREG32(&pRegs->OTG.USBMODE);
if ( mode.CM == 0x3 )
{
// in host mode, make sure HCH (halted) already, and that mode does change to halted (or not)
USB_USBSTS_T stat;
DWORD *pTmpStat = (DWORD*)&stat;
int iAttempts;
if ( bRunMode )
{
*pTmpStat = INREG32(&pRegs->OTG.USBSTS);
if ( stat.HCH == 0)
{
RETAILMSG(1,(TEXT("USBControllerRun(1): ERROR ############ HCH=0 (stat=0x%x)\r\n"),*pTmpStat));
return ERROR_GEN_FAILURE;
}
}
// wait for mode to change
iAttempts = 0;
do {
*pTmpStat = INREG32(&pRegs->OTG.USBSTS);
if ( (!bRunMode && stat.HCH) || (bRunMode && (stat.HCH == 0)) )
return ERROR_SUCCESS;
Sleep(1);
} while ( iAttempts++ < 50 );
RETAILMSG(1,(TEXT("USBControllerRun(%d): failed to set/clear RS\r\n"),bRunMode));
return ERROR_GEN_FAILURE;
}
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: InterruptThread
//
// This is interrupt thread. It controls responsed to hardware interrupt. To
// reduce code length it calls interrupt specific functions.
//
// Parameter:
//
// pPddContext - Pointer to USBFN_PDD
//
// Return:
//
// ERROR_SUCCESS
//
//--------------------------------------------------------------------------------
static DWORD WINAPI InterruptThread(VOID *pPddContext)
{
USBFN_PDD *pPdd = pPddContext;
CSP_USB_REGS* pUSBDRegs = pPdd->pUSBDRegs;
USB_USBSTS_T source;
DWORD *temp;
int i;
HANDLE hFunction, hXcvr;
ULONG WaitReturn;
TCHAR szUSBFunctionObjectName[30];
TCHAR szUSBXcvrObjectName[30];
DWORD timeout = IDLE_TIMEOUT; // 3 sec
DEBUGMSG(1, (TEXT("IsOTGSupport? %d\r\n"), pPdd->IsOTGSupport));
if (pPdd->IsOTGSupport)
{
lstrcpy(szUSBFunctionObjectName, USBFunctionObjectName);
lstrcat(szUSBFunctionObjectName, pPdd->szOTGGroup);
DEBUGMSG(1, (TEXT("USBFN: CreateEvent:%s\r\n"), szUSBFunctionObjectName));
hFunction = CreateEvent(NULL, FALSE, FALSE, szUSBFunctionObjectName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
DEBUGMSG(1, (TEXT("UFN: Opened an existing Func Event\r\n")));
else
DEBUGMSG(1, (TEXT("UFN: Created a new Func Event\r\n")));
if (hFunction == NULL)
DEBUGMSG(1, (TEXT("UFN: Create Event Failed for func!\r\n")));
lstrcpy(szUSBXcvrObjectName, USBXcvrObjectName);
lstrcat(szUSBXcvrObjectName, pPdd->szOTGGroup);
DEBUGMSG(1, (TEXT("USBFN: CreateEvent:%s\r\n"), szUSBXcvrObjectName));
hXcvr = CreateEvent(NULL, FALSE, FALSE, szUSBXcvrObjectName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
DEBUGMSG(1, (TEXT("UFN: Opened an existing XCVR Event\r\n")));
else
DEBUGMSG(1, (TEXT("UFN: Created a new XCVR Event\r\n")));
if (hXcvr == NULL)
DEBUGMSG(1, (TEXT("UFN: Create Event Failed for xcvr!\r\n")));
XCVR_SIG:
pPdd->bInUSBFN = FALSE;
DEBUGMSG(1, (TEXT("UFN: Waiting for signal from XCVR!!!\r\n")));
WaitReturn = WaitForSingleObject(hFunction, INFINITE);
pPdd->bInUSBFN = TRUE;
// RETAILMSG(1, (TEXT("UFN: Function Driver in charge now!!!\r\n")));
if(!InterruptInitialize(pPdd->sysIntr, pPdd->hIntrEvent, NULL, 0))
{
RETAILMSG(1, (L"ERROR: UfnPdd_Init: Interrupt initialization failed\r\n"));
return -1;
}
DEBUGMSG(1, (TEXT("UfnPdd_Start called\r\n")));
UfnPdd_Start(pPdd);
// Move this part to here so that it would only handle in case
// of OTG support
{
USB_OTGSC_T temp;
DWORD *t = (DWORD *)&temp;
*t = INREG32(&pUSBDRegs->OTG.OTGSC);
DEBUGMSG(1, (TEXT("OTGSC IDIE(0x%x), IDIS(0x%x), (0x%x)\r\n"), temp.IDIE, temp.IDIS, *t));
temp.IDIE = 1;
OUTREG32(&pUSBDRegs->OTG.OTGSC, *t);
}
DEBUGMSG(1, (TEXT("USBFNPDD SysIntr:0x%x, Irq:0x%x\r\n"), pPdd->sysIntr, pPdd->irq));
// Handling of device attach
temp=(DWORD *)&source;
*temp = INREG32(&pUSBDRegs->OTG.USBSTS);
// Clear source bit
{
do {
if (INREG32(&pUSBDRegs->OTG.ENDPTSETUPSTAT) & 1)
{
DEBUGMSG(1, (L".. SetupEvent \r\n"));
SetupEvent(pPdd);
}
if (INREG32(&pUSBDRegs->OTG.ENDPTCOMPLETE))
{
for (i=0;i<USBD_EP_COUNT;i++)
{
CheckEndpoint(pPdd, i );
}
}
} while (INREG32(&pUSBDRegs->OTG.ENDPTSETUPSTAT) ||INREG32(&pUSBDRegs->OTG.ENDPTCOMPLETE));
}
}
while (!pPdd->exitIntrThread)
{
DWORD dwErr = 0;
if (pPdd->IsOTGSupport)
timeout = INFINITE;
// Wait for interrupt from USB controller
dwErr = WaitForSingleObject(pPdd->hIntrEvent, timeout);
if (dwErr == WAIT_TIMEOUT)
{
// Now I am ready to put the transceiver into suspend mode.
// But be aware there is a device attach when boot up
USB_CTRL_T ctrl;
DWORD *temp3;
USB_PORTSC_T portsc;
DWORD *temp = (DWORD *)&portsc;
*temp = INREG32(&(pUSBDRegs)->OTG.PORTSC);
if ((portsc.SUSP == 0) && (pPdd->devState == 1))
{
// there is a device attached, don't do anything
timeout = INFINITE;
continue;
}
// If there is a device attached at this time
// Handling of device attach
// Even though it is pure client, still, we have no other way to isolate the
// host from the device, we need to use ID pin to detect.
if (portsc.SUSP == 0)
{
USB_OTGSC_T otgsc;
DWORD *temp4 = (DWORD *)&otgsc;
*temp4 = INREG32(&(pUSBDRegs)->OTG.OTGSC);
timeout = IDLE_TIMEOUT;
if (otgsc.ID != 0)
{
RETAILMSG(1, (TEXT("Port is not suspend and no A-device is detected\r\n")));
LOCK();
USBControllerRun(pUSBDRegs, FALSE);
HardwareInitialize(pUSBDRegs);
UfnPdd_Start(pPdd);
USBControllerRun(pUSBDRegs, TRUE);
UNLOCK();
goto PROCESS_INTERRUPT;
}
}
// Now the device is not attached
// Check and make sure all wakeup interrupt are enabled
temp3 = (DWORD *)&ctrl;
*temp3 = INREG32(&pUSBDRegs->USB_CTRL);
ctrl.OWIE = 1;
ctrl.OUIE = 1;
OUTREG32(&pUSBDRegs->USB_CTRL, *temp3);
// stop the controller before accessing the ULPI
LOCK();
USBControllerRun(pUSBDRegs, FALSE);
// May need to set ULPI here
// It is not waking up now ...must be something wrong
*temp = INREG32(&(pUSBDRegs)->OTG.PORTSC);
if (portsc.PHCD == 0)
SetULPIToClientMode(pUSBDRegs);
portsc.PHCD = 1;
OUTREG32(&(pUSBDRegs)->OTG.PORTSC, *temp);
//DEBUGMSG(1, (TEXT("Lower core voltage now with portsc(0x%x) usbctrl(0x%x)\r\n"), INREG32(&(pUSBDRegs)->OTG.PORTSC), INREG32(&pUSBDRegs->USB_CTRL)));
{
BOOL bTemp;
if (pPdd->bUSBPanicMode == TRUE)
{
#if 1 /*ERIC0907, need implemented?*/
bTemp = TRUE;
DEBUGMSG(TRUE, (TEXT("DDKClockDisablePanicMode : 7\r\n")));
#else
bTemp = DDKClockDisablePanicMode();
#endif
//RETAILMSG(1, (TEXT("DDKClockDisablePanicMode = 0x%x\r\n"), bTemp));
pPdd->bUSBPanicMode = FALSE;
}
}
if (pPdd->bUSBCoreClk == TRUE)
{
pPdd->bUSBCoreClk = FALSE;
USBClockDisable(TRUE);
}
UNLOCK();
// Now we can stop the USB clock
RETAILMSG(1, (TEXT("PDD - SUSPEND\r\n")));
timeout = INFINITE;
continue;
}
PROCESS_INTERRUPT:
LOCK();
if (pPdd->bUSBCoreClk == FALSE)
{
USBClockDisable(FALSE);
pPdd->bUSBCoreClk = TRUE;
}
if (pPdd->bUSBPanicMode == FALSE)
{
#if 1 /*ERIC0907, need implemented?*/
DEBUGMSG(TRUE, (TEXT("DDKClockEnablePanicMode : 8\r\n")));
#else
DDKClockEnablePanicMode();
#endif
pPdd->bUSBPanicMode = TRUE;
DEBUGMSG(1, (TEXT("DDKClockEnablePanicMode\r\n")));
DEBUGMSG(1, (TEXT("WakeUp - PORTSC: 0x%x\r\n"), INREG32(&pUSBDRegs->OTG.PORTSC[0])));
}
if (INREG32(&pUSBDRegs->OTG.PORTSC[0]) & 0x800000)
{
// Clear the PHCD
CLRREG32(&pUSBDRegs->OTG.PORTSC[0], INREG32(&pUSBDRegs->OTG.PORTSC[0]) & 0x800000); //PORTSC_PHCD 0x800000
// Force Resume bit
OUTREG32(&pUSBDRegs->OTG.PORTSC[0], INREG32(&pUSBDRegs->OTG.PORTSC[0]) | 0x40); //PORTSC_FPR 0x40
DEBUGMSG(1, (TEXT("Force resume\r\n")));
}
UNLOCK();
InterruptDone(pPdd->sysIntr);
CeLogMsg(_T("Intr:Signalled"));
{
USB_CTRL_T ctrl;
temp = (DWORD *)&ctrl;
*temp = INREG32(&pUSBDRegs->USB_CTRL);
if (ctrl.OWIR == 1)
{
*temp = 0;
ctrl.OWIE = 1;
CLRREG32(&pUSBDRegs->USB_CTRL, *temp);
// We move to here since only when we have wakeup should we
// set the Run bit of USB Controller again.
// Put 200 msec here i.e. it would make sure the controller is ready before we
// do any process.
Sleep(200);
USBControllerRun(pUSBDRegs, TRUE);
}
}
// Exit thread when we are asked so...
if (pPdd->exitIntrThread)
{
break;
}
if ( pPdd->bEnterTestMode )
{
LOCK();
SetDeviceTestMode( pPdd, pPdd->iTestMode );
/* clear whatever interrupt there was */
temp=(DWORD *)&source;
*temp = INREG32(&pUSBDRegs->OTG.USBSTS);
// Clear source bits
OUTREG32(&pUSBDRegs->OTG.USBSTS, *temp);
/*
* when device is in test mode, there is no longer any more normal operation and
* we could just busy-stall here, since exit from the mode is via power-off.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -