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

📄 xvc.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    lstrcat(szUSBHostObjectName, pXVC->szOTGGroup);
    //RETAILMSG(1, (TEXT("XVC: CreateEvent:%s\r\n"), szUSBHostObjectName));
    hHost = CreateEvent(NULL, FALSE, FALSE, szUSBHostObjectName);
    if(GetLastError()==ERROR_ALREADY_EXISTS)
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Opened an existing Host Event\r\n")));
    else
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Created a new Host Event\r\n")));
    if (hHost == NULL) {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Create Event Failed for host!\r\n")));
    }

    // Initializes of the Transceiver driver, configure as client all the time.
    USBControllerRun(pUSBRegs, FALSE);
    USBControllerReset(pUSBRegs);

    InitializeOTGTransceiver((PCSP_USB_REGS *)&pUSBRegs, FALSE);

    USBControllerRun(pUSBRegs, TRUE);
    Sleep(100);

    while (TRUE) {
        USB_USBSTS_T source;
        USB_PORTSC_T state;
        USB_CTRL_T ctrl;
        USB_OTGSC_T otgsc;
        DWORD *temp;
        DWORD *temp2;
        DWORD *temp3;
        DWORD *temp4;
        BOOL newIntrInit = FALSE;
        BOOL deviceDetected = FALSE;

        pXVC->bInXVC = TRUE;

        
        WaitReturn = WaitForSingleObject(pXVC->hIntrEvent, timeout);
        
        if (WaitReturn == 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_PORTSC_T portsc;
            DWORD *temp = (DWORD *)&portsc;
            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);

            // Lock Start
            EnterCriticalSection(&pXVC->csPhyLowMode);
            // 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);

            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;
        }

        EnterCriticalSection(&pXVC->csPhyLowMode);
        if (pXVC->bUSBCoreClk == FALSE)
        {
            InitClock();
            pXVC->bUSBCoreClk = TRUE;
        }

        USBControllerRun(pUSBRegs, TRUE);

        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);
        
        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));
                    
                    USBControllerRun(pUSBRegs, TRUE);

                    // 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;
            }
        }


        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) {
            // 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
    pszActiveKey = (LPCTSTR) dwContext;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -