📄 xvc.c
字号:
//------------------------------------------------------------------------------
//
// 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 + -