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

📄 xvc.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 3 页
字号:
            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 + -