📄 xvc.c
字号:
int i = 0;
do {
//RETAILMSG(1, (TEXT("SUSP waiting\r\n")));
*temp = INREG32(&(pUSBRegs)->OTG.PORTSC);
} while ((portsc.SUSP == 0) && (i++ < 100));
if (portsc.SUSP == 0)
{
RETAILMSG(1, (TEXT("Failure to suspend the port, there must be something happening\r\n")));
RETAILMSG(1,
(TEXT("Receive interrupt with OTGSC (0x%x) USBSTS (0x%x), PORTSC (0x%x), USBCTRL (0x%x)\r\n"),
INREG32(&pUSBRegs->OTG.OTGSC), INREG32(&pUSBRegs->OTG.USBSTS), INREG32(&pUSBRegs->OTG.PORTSC[0]),
INREG32(&pUSBRegs->USB_CTRL)));
DEBUGMSG(1, (TEXT("Forcing port suspend anyway\r\n")));
USBControllerRun(pUSBRegs, FALSE);
InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, FALSE);
USBControllerRun(pUSBRegs, TRUE);
// otherwise, just give up waiting for the port to suspend and try
// forcing everything off.
}
// Check and make sure all wakeup interrupt are enabled
temp3 = (DWORD *)&ctrl;
*temp3 = INREG32(&pUSBRegs->USB_CTRL);
ctrl.OWIE = 1;
ctrl.OUIE = 1;
SETREG32(&pUSBRegs->USB_CTRL, *temp3);
//RETAILMSG(1, (TEXT("Set USB Ctrl register\r\n")));
//DumpULPIRegs(pUSBRegs);
// Lock Start
EnterCriticalSection(&pXVC->csPhyLowMode);
//RETAILMSG(1, (TEXT("WaitTimeOut\r\n")));
//if (portsc.SUSP == 0)
// DumpULPIRegs(pUSBRegs);
// Config the ULPI again to make sure
*temp = INREG32(&(pUSBRegs)->OTG.PORTSC);
// stop the controller before accessing the ULPI
USBControllerRun(pUSBRegs, FALSE);
if (portsc.PHCD == 0)
{
SetULPIToClientMode(pUSBRegs);
DEBUGMSG(1, (TEXT("Set ULPI to client mode\r\n")));
}
if (pXVC->fnUsbXvr.pfnUSBSetPhyPowerMode)
pXVC->fnUsbXvr.pfnUSBSetPhyPowerMode(pUSBRegs, FALSE);
//RETAILMSG(1, (TEXT("Lower core voltage now\r\n")));
{
//BOOL bTemp;
if (pXVC->bPanicMode == TRUE)
{
//bTemp = DDKClockDisablePanicMode();
//RETAILMSG(1, (TEXT("DDKClockDisablePanicMode = 0x%x\r\n"), bTemp));
pXVC->bPanicMode = FALSE;
}
}
if (pXVC->bUSBCoreClk == TRUE)
{
pXVC->bUSBCoreClk = FALSE;
DeInitClock();
}
LeaveCriticalSection(&pXVC->csPhyLowMode);
// Now we can stop the USB clock
DEBUGMSG(1, (TEXT("XVC - SUSPEND\r\n")));
timeout = INFINITE;
continue;
}
//INTERRUPT_PROCESSING:
EnterCriticalSection(&pXVC->csPhyLowMode);
if (pXVC->bUSBCoreClk == FALSE)
{
InitClock();
pXVC->bUSBCoreClk = TRUE;
Sleep(200);
USBControllerRun(pUSBRegs, TRUE);
}
//RETAILMSG(1, (TEXT(" PORTSC return 0x%x\r\n"), INREG32(&pUSBRegs->OTG.PORTSC[0])));
//RETAILMSG(1, (TEXT(" USBSTS return 0x%x\r\n"), INREG32(&pUSBRegs->OTG.USBSTS)));
//RETAILMSG(1, (TEXT(" USBCTL return 0x%x\r\n"), INREG32(&pUSBRegs->USB_CTRL)));
if (pXVC->fnUsbXvr.pfnUSBSetPhyPowerMode)
pXVC->fnUsbXvr.pfnUSBSetPhyPowerMode(pUSBRegs, TRUE);
temp=(DWORD *)&source;
*temp = INREG32(&pUSBRegs->OTG.USBSTS);
temp2 = (DWORD *)&state;
*temp2 = INREG32(&pUSBRegs->OTG.PORTSC[0]);
temp3 = (DWORD *)&ctrl;
*temp3 = INREG32(&pUSBRegs->USB_CTRL);
temp4 = (DWORD *)&otgsc;
*temp4 = INREG32(&pUSBRegs->OTG.OTGSC);
temp5 = (DWORD *)&intr;
*temp5 = INREG32(&pUSBRegs->OTG.USBINTR);
#if 0
RETAILMSG(1, (TEXT("Receive interrupt with OTGSC (0x%x) USBSTS (0x%x), PORTSC (0x%x), USBCTRL (0x%x)\r\n"),
INREG32(&pUSBRegs->OTG.OTGSC), *temp, *temp2, *temp3));
DumpUSBRegs(pUSBRegs);
#endif
if (ctrl.OWIR == 1)
{
*temp3 = 0;
ctrl.OWIE = 1;
CLRREG32(&pUSBRegs->USB_CTRL, *temp3);
//RETAILMSG(1, (TEXT("Clear the wake up bit and continue\r\n")));
//DumpULPIRegs(pUSBRegs);
}
if (pXVC->bResume) {
//RETAILMSG(1, (TEXT("XVC:Resume again\r\n")));
pXVC->bResume = FALSE;
// We remove the controller stop, reset and run part, since when wakeup due to device attach
// the first interrupt would be just wakeup but not the device attached status. The transceiver needs
// some times to resume from suspend before processing the device status change interrupt.
// If we reset immediately, the transceiver would go into weird state.
//USBControllerRun(pUSBRegs, FALSE);
//InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, FALSE);
//USBControllerRun(pUSBRegs, TRUE);
pXVC->devState = 0;
deviceDetected = FALSE;
timeout = IDLE_TIMEOUT;
// remove continue and let it to do the work, if something plug in
//continue;
}
if ((source.PCI == 1) && (state.CCS == 1))
{
// We have a device attached
if (pXVC->devState == 0)
{
if (pXVC->bPanicMode == FALSE)
{
//DDKClockEnablePanicMode();
pXVC->bPanicMode = TRUE;
//RETAILMSG(1, (TEXT("DDKClockEnablePanicMode = %d\r\n"), gfsvaim));
}
#ifdef USBXVR_INTERRUPT
InterruptDisable (pXVC->dwSysIntr); // to disable the interrupt
#endif
// Don't clean up any interrupt, let the corresponding driver handle that
//Sleep(1500); // there is a delay for OTGSC to detect the value
//Sleep(1000);
//RETAILMSG(1, (TEXT("OTGSC = 0x%x\r\n"), INREG32(&pUSBRegs->OTG.OTGSC)));
if (INREG32(&pUSBRegs->OTG.OTGSC) & 0x100) // B-device
{
RETAILMSG(1, (TEXT("B-Device client\r\n")));
//RETAILMSG(1, (TEXT("Receive interrupt with USBSTS (0x%x), PORTSC (0x%x)\r\n"),
// *temp, *temp2));
#ifdef FREESCALE_DEBUG
DumpULPIRegs(pUSBRegs);
#endif
USBControllerRun(pUSBRegs, TRUE);
// turn the SLE back on, for the device controller
temp5 = (DWORD *)&intr;
*temp5 = 0;
intr.SLE = 1;
SETREG32(&pUSBRegs->OTG.USBINTR, *temp5);
// By default is client, no need to do any configuration
SetEvent(hFunction);
}
else
{
RETAILMSG(1, (TEXT("A-Device host\r\n")));
USBControllerRun(pUSBRegs, FALSE);
USBControllerReset(pUSBRegs );
// Configure the host
InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, TRUE);
SetEvent(hHost);
}
deviceDetected = TRUE;
} // pXVC->devState == 0
} // source.PCI==1 && state.CCS==1
else if ((pXVC->devState == 0) && (deviceDetected == FALSE))
{
DWORD temp = INREG32(&pUSBRegs->OTG.OTGSC);
if ((temp & 0x100) == 0x0)
{
if (pXVC->bPanicMode == FALSE)
{
//DDKClockEnablePanicMode();
pXVC->bPanicMode = TRUE;
//RETAILMSG(1, (TEXT("DDKClockEnablePanicMode for A-device\r\n"), gfsvaim));
}
#ifdef USBXVR_INTERRUPT
InterruptDisable (pXVC->dwSysIntr); // to disable the interrupt
#endif
RETAILMSG(1, (TEXT("A-device host from polling\r\n")));
//Configure the host
USBControllerRun(pUSBRegs, FALSE);
USBControllerReset(pUSBRegs );
InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, TRUE);
SetEvent(hHost);
deviceDetected = TRUE;
}
else
{
// Give a try
USBControllerRun(pUSBRegs, FALSE);
SetULPIToHostMode(pUSBRegs);
USBControllerRun(pUSBRegs, TRUE);
}
}
if ((pXVC->devState == 0) && (deviceDetected == TRUE))
{
pXVC->devState = 1;
pXVC->bInXVC = FALSE;
pXVC->bResume = FALSE;
#ifdef DISABLE_DETACH_WAKEUP
// Clear any wakeup interrupt as there would be a problem on host mode
*temp3 = 0;
ctrl.OWIE = 1;
ctrl.OUIE = 1;
CLRREG32(&pUSBRegs->USB_CTRL, *temp3);
// Disable wakeup
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pXVC->dwSysIntr, sizeof(pXVC->dwSysIntr), NULL, 0, NULL);
#endif
// Wait for detach occur
WaitReturn = WaitForSingleObject(hXcvr, INFINITE);
pXVC->bInXVC = TRUE;
DEBUGMSG(1, (TEXT("XVR In control again\r\n")));
// I think we need to do some charge, discharge ....
#ifdef USBXVR_INTERRUPT
newIntrInit = TRUE;
if (!(InterruptInitialize(pXVC->dwSysIntr, pXVC->hIntrEvent, NULL, 0))) {
newIntrInit = FALSE;
RETAILMSG(1, (TEXT("XVC_Init: Interrupt initialization failed!, ErrCode: 0x%x\r\n"), GetLastError()));
}
#endif
#ifdef DISABLE_DETACH_WAKEUP
// Enable wakeup
KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &pXVC->dwSysIntr, sizeof(pXVC->dwSysIntr), NULL, 0, NULL);
#endif
// Initializes of the Transceiver driver
USBControllerRun(pUSBRegs, FALSE);
USBControllerReset(pUSBRegs);
InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, FALSE);
USBControllerRun(pUSBRegs, TRUE);
pXVC->devState = 0;
deviceDetected = FALSE;
timeout = IDLE_TIMEOUT;
}
if (newIntrInit == FALSE) {
//
// don't want to detect device suspend when we're in transceiver
temp5 = (DWORD*)&intr;
*temp5 = 0;
intr.SLE = 1;
CLRREG32(&(pUSBRegs->OTG.USBINTR),*temp5);
// Clear source bit
OUTREG32(&pUSBRegs->OTG.USBSTS, *temp);
#ifdef USBXVR_INTERRUPT
InterruptDone(pXVC->dwSysIntr);
#endif
}
LeaveCriticalSection(&pXVC->csPhyLowMode);
timeout = IDLE_TIMEOUT;
} // While loop
// Never to enter this region
DEBUGMSG(ZONE_FUNCTION, (TEXT("XVC_ISTMain-\r\n")));
return 0;
}
/*
* Function: XVC_Init
*
* The Device Manager calls this function as a result of a call to the
* ActivateDevice() function. This function will retrieve the handle to the
* device context from the registry and then initialize the XVC module with
* interrupt initialisation.
*
* Parameters:
* dwContext
* [in] Pointer to a string containing the registry path to the
* active key for the stream interface driver.
*
* Returns:
* Returns a handle to the device context created if successful. Returns
* zero if not successful.
*/
DWORD XVC_Init(DWORD dwContext)
{
PHYSICAL_ADDRESS pa;
HANDLE hInterruptServiceThread;
DWORD len;
DWORD irq;
LPCTSTR pszActiveKey;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
pXVC = LocalAlloc(LPTR, sizeof(USBXVC));
if (pXVC == NULL)
{
RETAILMSG(1, (TEXT("XVC_Init: Cannot allocate memory\r\n")));
goto clean;
}
memset(pXVC, 0x00, sizeof(USBXVC));
// Read device parameters
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -