📄 sc2443pdd.cpp
字号:
HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
nStop = TRUE;
}
if(nStop) break;
}
}
}
FUNCTION_LEAVE_MSG();
}
/****************************************************************
@doc INTERNAL
@func VOID | SerUSB_InternalMapRegisterAddresses |
This routine maps the ASIC registers.
It's an artifact of this
implementation.
@rdesc None.
****************************************************************/
DWORD MapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(g_pUDCBase == NULL);
PBYTE pVMem;
DWORD dwRet = ERROR_SUCCESS;
// Map CSR registers.
pVMem = (PBYTE)VirtualAlloc(0, PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (pVMem) {
BOOL fSuccess = VirtualCopy(pVMem, (LPVOID)pContext->dwIOBase,
pContext->dwIOLen, PAGE_READWRITE | PAGE_NOCACHE);
if (!fSuccess) {
VirtualFree(pVMem, 0, MEM_RELEASE);
dwRet = GetLastError();
RETAILMSG(DBG, (_T("%s Virtual Copy: FAILED\r\n"), pszFname));
}
else {
g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;
RETAILMSG(DBG, (_T("%s VirtualCopy Succeeded, pVMem:%x\r\n"),
pszFname, pVMem));
}
}
else {
dwRet = GetLastError();
RETAILMSG(DBG, (_T("%s Virtual Alloc: FAILED\r\n"), pszFname));
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
/*++
Routine Description:
Deallocate register space.
Arguments:
None.
Return Value:
None.
--*/
static
VOID
UnmapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
// Unmap any memory areas that we may have mapped.
if (g_pUDCBase) {
VirtualFree((PVOID) g_pUDCBase, 0, MEM_RELEASE);
g_pUDCBase = NULL;
}
}
// interrupt service routine.
DWORD
WINAPI
ISTMain(
LPVOID lpParameter
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
ValidateContext(pContext);
CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);
while (!pContext->fExitIST) {
pContext->fRestartIST = FALSE;
// Disable All Endpoint interrupts
WriteReg(pContext, EIER, 0); // Disable All
//Resume signal is occured when cable is not connected
//So, MFRM is setted by '0'
// Enable Device interrupts
// SetClearReg(pContext, SCR, (RRDE | HRESE | HSUSPE | MFRM), SET);
SetClearReg(pContext, SCR, (RRDE|HRESE|HSUSPE), SET);
SetClearReg(pContext, SSR, (HFRES | HFSUSP | HFRM), SET);
// Enable Endpoint interrupt 0
EnableEndpointInterrupt(pContext, 0);
while (TRUE) {
DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
if (pContext->fExitIST || pContext->fRestartIST) {
break;
}
if (dwWait == WAIT_OBJECT_0) {
HandleUSBEvent(pContext);
InterruptDone(pContext->dwSysIntr);
}
else {
RETAILMSG(DBG, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"),
pszFname));
break;
}
}
// Send detach
pContext->pfnNotify(pContext->pvMddContext,
UFN_MSG_BUS_EVENTS, UFN_DETACH);
pContext->fSpeedReported = FALSE;
pContext->attachedState = UFN_DETACH;
// Disable Device interrupts - write Zeros to Disable
SetClearReg(pContext, SCR, (HRESE | HSUSPE | MFRM), CLEAR);
// Disable endpoint interrupts - write Zeros to Disable
WriteReg(pContext, EIER, 0);
// Clear any outstanding device & endpoint interrupts
// USB Device Interrupt Status - Write a '1' to Clear
SetClearReg(pContext, SSR, (HFRES | HFSUSP | HFRM), SET);
// End point Interrupt Status - Write a '1' to Clear
WriteReg(pContext, EIR, CLEAR_ALL_EP_INTRS);
}
FUNCTION_LEAVE_MSG();
return 0;
}
// EINT2 Test Code by woo
static DWORD
PLUG_IST(LPVOID lpParameter)
{
//DWORD i;
#if 1
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
ValidateContext(pContext);
while (1) {
__try {
WaitForSingleObject(g_PlugEvent, INFINITE);
if ( pIOPregs->GPFDAT & (1<<2) )
{
#if 1
// Set the Normal mode
pIOPregs->GPHCON = (pIOPregs->GPHCON & ~(0x3<<28)) | (0x1<<28);
pIOPregs->GPHUDP = (pIOPregs->GPHUDP & ~(0x3<<28));
pIOPregs->GPHDAT = (pIOPregs->GPHDAT & ~(0x1<<14)) | (0x1<<14);
// Enable the PHY Power
pCLKPWR->PWRCFG |= (1<<4);
// First USB PHY has to be reset, and after 10us, func and host has to be reset.
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(1<<0);
Sleep(1);
pCLKPWR->USB_RSTCON = (1<<2)|(0<<1)|(0<<0);
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(0<<0);
#endif
RETAILMSG(1,(TEXT("+USB Cable Plug in\r\n")));
}
else
{
#if 1
// Set the Normal mode
pIOPregs->GPHCON = (pIOPregs->GPHCON & ~(0x3<<28)) | (0x1<<28);
pIOPregs->GPHUDP = (pIOPregs->GPHUDP & ~(0x3<<28)) | (0x2<<28);
pIOPregs->GPHDAT = (pIOPregs->GPHDAT & ~(0x1<<14));
//Disable the PHY Power
pCLKPWR->PWRCFG = (pCLKPWR->PWRCFG & ~(0x1<<4));
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
pContext->attachedState = UFN_DETACH;
#endif
RETAILMSG(1,(TEXT("-USB Cable Plug out\r\n")));
}
InterruptDone(g_PlugSysIntr);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
RETAILMSG(1,(TEXT("!!! PLUG_IST EXCEPTION: 0x%X !!!\r\n"), GetExceptionCode() ));
}
}
#endif
return 0;
}
// end woo
static
VOID
StartTransfer(
PCTRLR_PDD_CONTEXT pContext,
PEP_STATUS peps,
PSTransfer pTransfer
)
{
SETFNAME();
DEBUGCHK(pContext);
PREFAST_DEBUGCHK(peps);
DEBUGCHK(!peps->pTransfer);
ValidateTransferDirection(pContext, peps, pTransfer);
LOCK_ENDPOINT(peps);
FUNCTION_ENTER_MSG();
RETAILMSG(DBG, (_T("%s Setting up %s transfer on ep %u for %u bytes\r\n"),
pszFname, (pTransfer->dwFlags == USB_IN_TRANSFER) ? _T("in") : _T("out"),
peps->dwEndpointNumber, pTransfer->cbBuffer));
// Enable transfer interrupts.
peps->pTransfer = pTransfer;
DWORD dwEndpoint = peps->dwEndpointNumber;
if (pTransfer->dwFlags == USB_IN_TRANSFER) {
if (peps->dwEndpointNumber == 0) {
WORD bEp0ESR = ReadReg(pContext, EP0SR);
if (bEp0ESR & EP0TST) WriteReg(pContext, EP0SR, bEp0ESR);
HandleTx(pContext, peps, 0);
}
else {
WORD bEpESR = ReadIndexedReg(pContext, dwEndpoint, ESR);
if (bEpESR & TPS) {
WriteIndexedReg(pContext, dwEndpoint, ESR, bEpESR);
}
HandleTx(pContext, peps, 1);
}
}
else {
if (peps->dwEndpointNumber == 0) {
}
else {
EnableEndpointInterrupt(pContext, peps->dwEndpointNumber);
// There may be a packet available. If so process it...
WORD bEpIrqStat = ReadIndexedReg(pContext, peps->dwEndpointNumber, ESR);
if (bEpIrqStat & RPS) {
BOOL fCompleted;
DWORD dwStatus;
HandleRx(pContext, peps, &fCompleted, &dwStatus);
if (fCompleted) {
// Disable transfer interrupts until another transfer is issued.
DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
}
if (fCompleted) {
CompleteTransfer(pContext, peps, dwStatus);
}
}
}
}
FUNCTION_LEAVE_MSG();
UNLOCK_ENDPOINT(peps);
}
DWORD
WINAPI
UfnPdd_IssueTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->fInitialized);
DEBUGCHK(pTransfer->cbTransferred == 0);
DWORD dwRet = ERROR_SUCCESS;
RETAILMSG(DBG, (_T("%s UfnPdd_IssueTransfer\r\n"),
pszFname));
// Note For the HW NAKs IN requests and DOES NOT let SW
// know that the Host is trying to send a request. SO... Start the Transfer
// In Now!
// Start the Transfer
DEBUGCHK(peps->pTransfer == NULL);
StartTransfer(pContext, peps, pTransfer);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnPdd_AbortTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pTransfer);
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->fInitialized);
RETAILMSG(DBG, (_T("%s UfnPdd_AbortTransfer\r\n"),
pszFname));
ValidateTransferDirection(pContext, peps, pTransfer);
DEBUGCHK(pTransfer == peps->pTransfer);
CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);
if (dwEndpoint == 0) {
pContext->Ep0State = EP0_STATE_IDLE;
}
ResetEndpoint( pContext,peps);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
BOOL HW_USBClocks(CEDEVICE_POWER_STATE cpsNew)
{
if (cpsNew == D0)
{
RETAILMSG(0, (TEXT("HW_USBClocks::D0 \r\n")));
// Set the Normal mode
pIOPregs->GPHCON = (pIOPregs->GPHCON & ~(0x3<<28)) | (0x1<<28);
pIOPregs->GPHUDP = (pIOPregs->GPHUDP & ~(0x3<<28));
pIOPregs->GPHDAT = (pIOPregs->GPHDAT & ~(0x1<<14)) | (0x1<<14);
pIOPregs->MISCCR &= ~(1<<12);
// Enable the PHY Power
pCLKPWR->PWRCFG |= (1<<4);
// First USB PHY has to be reset, and after 10us, func and host has to be reset.
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(1<<0);
Sleep(1);
pCLKPWR->USB_RSTCON = (1<<2)|(0<<1)|(0<<0);
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(0<<0);
// Set USB PHY Control
// Ref. Clock (48MHz), Clock (X-tal), Host Clock (Ext. X-tal), D-stream (Device Mode)
pCLKPWR->USB_PHYCTRL = (0<<3)|(1<<2)|(0<<1)|(0<<0);
// Set USB PHY Power
// 48Mhz clock on ,PHY2.0 analog block power on,XO block power on,
// XO block power in suspend mode,PHY 2.0 Pll power on ,suspend signal for save mode disable
pCLKPWR->USB_PHYPWR = (0<<31)|(3<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
// Set USB Clock Control
// Vbus detect enable and D+ Pull up, USB2.0 Function clock Enable,
// USB1.1 HOST disable,USB2.0 PHY test enable
pCLKPWR->USB_CLKCON = (1<<31)|(1<<2)|(0<<1)|(0<<0);
}
// Should be implemented
else if (cpsNew == D4)
{
RETAILMSG(DBG, (TEXT("HW_USBClocks::D4 \r\n")));
// Set the Normal mode
pIOPregs->GPHCON = (pIOPregs->GPHCON & ~(0x3<<28)) | (0x1<<28);
pIOPregs->GPHUDP = (pIOPregs->GPHUDP & ~(0x3<<28)) | (0x2<<28);
pIOPregs->GPHDAT = (pIOPregs->GPHDAT & ~(0x1<<14));
pIOPregs->MISCCR |= (1<<12);
// Enable the PHY Power
pCLKPWR->PWRCFG |= (1<<4);
// First USB PHY has to be reset, and after 10us, func and host has to be reset.
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(1<<0);
Sleep(1);
pCLKPWR->USB_RSTCON = (1<<2)|(0<<1)|(0<<0);
pCLKPWR->USB_RSTCON = (0<<2)|(0<<1)|(0<<0);
// Set USB PHY Control
// Ref. Clock (48MHz), Clock (X-tal), Host Clock (Ext. X-tal), D-stream (Device Mode)
pCLKPWR->USB_PHYCTRL = (0<<3)|(1<<2)|(0<<1)|(0<<0);
// Set USB PHY Power
// 48Mhz clock on ,PHY2.0 analog block power on,XO block power on,
// XO block power in suspend mode,PHY 2.0 Pll power on ,suspend signal for save mode disable
pCLKPWR->USB_PHYPWR = (0<<31)|(1<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
// Set USB Clock Control
// Vbus detect enable and D+ Pull up, USB2.0 Function clock Enable,
// USB1.1 HOST disable,USB2.0 PHY test enable
pCLKPWR->USB_CLKCON = (1<<31)|(1<<2)|(0<<1)|(0<<0);
}
return TRUE;
}
// This does not do much because there is not any way to control
// power on this controller.
static
CEDEVICE_POWER_STATE
SetPowerState(
PCTRLR_PDD_CONTEXT pContext,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -