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

📄 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 页
字号:
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------

 /*!
 *
 * @File: xvc.c
 *
 * Description:
 *          USB Transceiver Driver is a stream interface driver
 *          which exposes the stream interface functions. This driver
 *          detects the USB plug in type and accordingly activates the Host or
 *          Function controller driver. Upon unplug, the respective driver
 *          gives back the control to the transceiver driver.
 *
 */

#include <windows.h>
#include <nkintr.h>
#include <pm.h>
#include <ceddk.h>
#include <cebus.h>
#include <usbfntypes.h>
#include <usbfn.h>
#include <csp.h>
#include "xvc.h"
#include <mx27_usbname.h>
#include <mx27_usbcommon.h>

#ifdef USBXVR_INTERRUPT
#undef USBXVR_INTERRUPT
#endif
#define USBXVR_INTERRUPT 1

#ifdef DISABLE_DETACH_WAKEUP
#undef DISABLE_DETACH_WAKEUP
#endif
//------------------------------------------------------------------------------
//  Device registry parameters

//#define FREESCALE_DEBUG
static const DEVICE_REGISTRY_PARAM g_deviceRegParams[] = {
    {
        L"MemBase", PARAM_DWORD, TRUE, offset(USBXVC, memBase),
        fieldsize(USBXVC, memBase), NULL
    }, { 
        L"MemLen", PARAM_DWORD, TRUE, offset(USBXVC, memLen),
        fieldsize(USBXVC, memLen), NULL
    }, { 
        L"Irq", PARAM_DWORD, TRUE, offset(USBXVC, dwIrq),
        fieldsize(USBXVC, dwIrq), NULL
    },{ 
        L"OTGSupport", PARAM_DWORD, TRUE, offset(USBXVC, IsOTGSupport),
        fieldsize(USBXVC, IsOTGSupport), (void *)0
    },{
        L"OTGGroup", PARAM_STRING, TRUE, offset(USBXVC, szOTGGroup),
        fieldsize(USBXVC, szOTGGroup), NULL
    }
};

PUSBXVC pXVC;
BOOL    gfsvaim = FALSE;

extern void SetULPIToClientMode(CSP_USB_REGS *regs);
extern void SetULPIToHostMode(CSP_USB_REGS *regs);
extern void RegisterCallback(BSP_USB_CALLBACK_FNS *pfn);


static BOOL InitClock()
{
    BOOL rc = FALSE;

    //RETAILMSG(1, (TEXT("Start the USB clock\r\n")));
    rc  = USBClockDisable(FALSE);

    return rc;

}
static BOOL DeInitClock(void)
{
    BOOL rc = FALSE;

    //RETAILMSG(1, (TEXT("Stop the USB Clock\r\n")));
    rc = USBClockDisable(TRUE);

    return rc;
}

/*
 *     Function: DllEntry
 *
 *     This is the entry and exit point for the XVC module.  This
 *     function is called when processed and threads attach and detach from this
 *     module.
 *
 *     Parameters:
 *     hInstDll
 *           [in] The handle to this module.
 *
 *     dwReason
 *           [in] Specifies a flag indicating why the DLL entry-point function
 *           is being called.
 *
 *     lpvReserved
 *           [in] Specifies further aspects of DLL initialization and cleanup.
 *
 *    Returns:
 *           TRUE if the XVC is initialized; FALSE if an error occurred during
 *           initialization.
 *
 */
BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
        DEBUGMSG(ZONE_INIT, (TEXT("XVC_DllEntry: DLL_PROCESS_ATTACH\r\n")));
        break;

        case DLL_PROCESS_DETACH:
        DEBUGMSG(ZONE_INIT, (TEXT("XVC_DllEntry: DLL_PROCESS_DETACH\r\n")));
        break;
    }

    return TRUE;
}


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

static DWORD USBControllerReset( CSP_USB_REGS *pRegs )
{
        USB_USBCMD_T cmd;
        USB_USBMODE_T mode;
        DWORD *pTmpCmd = (DWORD*)&cmd;
        DWORD *pTmpMode = (DWORD*)&mode;
        int iAttempts;

        *pTmpMode = INREG32(&pRegs->OTG.USBMODE);

        if ( mode.CM == 0x03 )
        {
            USB_USBSTS_T stat;
            DWORD *pTmpStat = (DWORD*)&stat;

            *pTmpStat = INREG32(&pRegs->OTG.USBSTS);
            if ( stat.HCH == 0)
            {
                RETAILMSG(1,(TEXT("USBControllerReset: ########### HCH=0 (stat=0x%x)\r\n"),*pTmpStat));
                return ERROR_GEN_FAILURE;
            }
        }

        *pTmpCmd = INREG32(&pRegs->OTG.USBCMD);
        cmd.RST = 1;
        OUTREG32(&pRegs->OTG.USBCMD,*pTmpCmd);
        iAttempts = 0;
        do {
            Sleep(0);
            *pTmpCmd = INREG32(&pRegs->OTG.USBCMD);
            if ( cmd.RST == 0 )
                return ERROR_SUCCESS;

        } while ( iAttempts++ < 1000 );

        RETAILMSG(1,(TEXT("USBControllerReset: ######### Failed to reset controller\r\n")));
        return ERROR_GEN_FAILURE;
}


/*
 *      Function : XVC_ISTMain
 *
 *      Description: This thread activates the Function or Host depending on the
 *                   plug inserted.
 *
 *      Input :
 *            LPVOID lpParameter
 *
 *       Output:
 *            void
 */
#define IDLE_TIMEOUT    1000
DWORD WINAPI XVC_ISTMain(LPVOID lpParameter)
{    
    HANDLE hFunction, hXcvr, hHost;
    ULONG WaitReturn;    
    CSP_USB_REGS *pUSBRegs = pXVC->pUSBRegs;
    TCHAR szUSBFunctionObjectName[30];
    TCHAR szUSBXcvrObjectName[30];
    TCHAR szUSBHostObjectName[30];
    DWORD timeout = IDLE_TIMEOUT;
    

    DEBUGMSG(ZONE_FUNCTION, (TEXT("XVC_ISTMain+\r\n")));

    // Event created for Function
    lstrcpy(szUSBFunctionObjectName, USBFunctionObjectName);
    lstrcat(szUSBFunctionObjectName, pXVC->szOTGGroup);
    //RETAILMSG(1, (TEXT("XVC: CreateEvent:%s\r\n"), szUSBFunctionObjectName));
    hFunction = CreateEvent(NULL, FALSE, FALSE, szUSBFunctionObjectName);
    if (GetLastError() == ERROR_ALREADY_EXISTS)
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Opened an existing Func Event\r\n")));
    else
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Created a new Func Event\r\n")));
    if (hFunction == NULL)
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Create Event Failed for func!\r\n")));

    // Event created for Transceiver
    lstrcpy(szUSBXcvrObjectName, USBXcvrObjectName);
    lstrcat(szUSBXcvrObjectName, pXVC->szOTGGroup);
    //RETAILMSG(1, (TEXT("XVC: CreateEvent:%s\r\n"), szUSBXcvrObjectName));
    hXcvr = CreateEvent(NULL, FALSE, FALSE, szUSBXcvrObjectName);
    if (GetLastError() == ERROR_ALREADY_EXISTS)
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Opened an existing XCVR Event\r\n")));
    else
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Created a new XCVR Event\r\n")));
    if (hXcvr == NULL)
        DEBUGMSG(ZONE_FUNCTION, (TEXT("XCVR: Create Event Failed for XCVR!\r\n")));

    // Event created for Host
    lstrcpy(szUSBHostObjectName, USBHostObjectName);
    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);

    //DumpUSBRegs(pUSBRegs);
    //DumpULPIRegs(pUSBRegs);
    while (TRUE) {
        USB_USBSTS_T source;
        USB_PORTSC_T state;
        USB_CTRL_T ctrl;
        USB_OTGSC_T otgsc;
        USB_USBINTR_T intr;
        DWORD *temp;
        DWORD *temp2;
        DWORD *temp3;
        DWORD *temp4;
        DWORD *temp5;
        BOOL newIntrInit = FALSE;
        BOOL deviceDetected = FALSE;

        pXVC->bInXVC = TRUE;

        //RETAILMSG(1, (TEXT("Before 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)));
        
        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;

⌨️ 快捷键说明

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