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

📄 pdd.c

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