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

📄 pxa255_ufnpdd.cpp

📁 老外的一个开源项目
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
        // Device Event
        if (ulUdccr) {
            if ( (ulUdccr & ( USB_UDCCR_SUSIR | USB_UDCCR_RESIR))!= NULL) // Suspend Resume.
			{
/*
                if (pContext->attachedState == UFN_DETACH && HWCheckCableAttached())
				{
                    pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
                    pContext->attachedState = UFN_ATTACH;
					HWCableAttach(TRUE);
					SetRequestInfo(&pContext->ep0Request, EP0Setup);
                }
                else if (pContext->attachedState == UFN_ATTACH && !HWCheckCableAttached())
				{
                    pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
                    pContext->attachedState = UFN_DETACH;
					HWCableAttach(FALSE);
					SetRequestInfo(&pContext->ep0Request, EP0Setup);
                }
*/
			}
            if ((ulUdccr & USB_UDCCR_RSTIR)!=0 && !pContext->fIgnoreReset)
			{
                DEBUGCHK(pContext->fRunning);
                // Disable Double Buffering on Endpoints 1 and 2
                g_pUDCRegs->RSVD0[0] &= ~(0x06);
                // Reset Has been report multiple time . Ignore following one.
                pContext->fIgnoreReset = TRUE;
                DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Reset\r\n"), pszFname));

                // If the cable was connected to a host at boot, the attach interrupt
                // will be missed. Generate it here.
                if ((pContext->attachedState != UFN_ATTACH)){
                    pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
                    pContext->attachedState = UFN_ATTACH;
					HWCableAttach(TRUE);
                }
                pContext->fSpeedReported = FALSE;

                pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
                SetRequestInfo(&pContext->ep0Request, EP0Setup);

            }
        }
        if(ulIsr0 & USB_UISR0_IR0) {
            ServiceEP0(pContext);
        }
        // inspect each interrupt/status register for a pending interrupt
        if (ulIsr0) {
            for (ulI = 1; ulI < 8; ulI += 1) {
                if (ulIsr0 & (1 << ulI)){
                    // an interrupt is pending, notify the function driver
                    HandleEndpointEvent(pContext, ulI);
                }
            }
        }

        if (ulIsr1) {
            for (ulI = 0; ulI < 8; ulI += 1) {
                // an interrupt is pending, notify the function driver
                if (ulIsr1 & (1 << ulI)) {
                    HandleEndpointEvent(pContext, (8 + ulI) );
                }
            }
        }

    }
    FUNCTION_LEAVE_MSG();
}



//  interrupt service routine.
static
DWORD
WINAPI
ISTMain(
        LPVOID lpParameter
        )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
    ValidateContext(pContext);

    CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);

    // Enable Acking 

    while (!pContext->fExitIST) {
        pContext->fRestartIST = FALSE;
        pContext->fEndpoint0AckNeeded = FALSE;

		// Start clock
		g_pCLKRegs->CKEN |= CKEN_USB;


        // Disable USB interface
        UDCCR_UDE_DISABLE(g_pUDCRegs->UDCCR);//g_pUDCRegs->udccr &= ~USB_UDCCR_UDE

        // We are currently disconnected. Make sure that we have been 
        // disconnected long enough for the host to notice.
        Sleep(1); // USB spec 7.1.7 says disconnect requires >= 2.5 us

        // Disable All endpoint Interrupt.
        g_pUDCRegs->UICR0 = DISABLE_INTRS_0TO7;   //  Endpoints 0-7
        g_pUDCRegs->UICR1 = DISABLE_INTRS_0TO7;   // Endpoints 8-15
        // Clear any outstanding endpoint interrupts
        g_pUDCRegs->UISR0 = CLEAR_INTRS_0TO7;    // Clear Enpoint Interrupts 0-7
        g_pUDCRegs->UISR1 = CLEAR_INTRS_8TO15;  // Clear Enpoint Interrupts 8-15

        // Enable USB interface , Enable Reset Interrupt, Enable Suspen/Resume Interrupt
        // Clear any outstanding device interrupts
        g_pUDCRegs->UDCCR = USB_UDCCR_UDE |USB_UDCCR_RSM| (USB_UDCCR_RSTIR | USB_UDCCR_SUSIR | USB_UDCCR_RESIR);

        // Enable (UnMask) Endpoint 0 interrupts
        EnableEndpointInterrupt( pContext,  0 );

        SetRequestInfo(&pContext->ep0Request, EP0Setup);

        //g_pUDCRegs->rsvd0[1] |= 0x04;
        //g_pUDCRegs->rsvd0[1] &= ~0x80;
        pContext->fIgnoreReset = FALSE;

//DV		// initial cable check
		if (HWCheckCableAttached())
		{
			HWCableAttach(TRUE);
			pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
		}

        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 {
                DEBUGMSG(ZONE_ERROR, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"), 
                    pszFname));
                pContext->fExitIST = TRUE;
                break;
            }
        }

        // Disable USB interface
        UDCCR_UDE_DISABLE(g_pUDCRegs->UDCCR);//g_pUDCRegs->udccr &= ~USB_UDCCR_UDE

        // Disable Bus Reset interrupts
        UDCCR_REM_DISABLE(g_pUDCRegs->UDCCR);//g_pUDCRegs->udccr &= ~USB_UDCCR_REM

        // Disable (Mask) Endpoint 0 interrupts
        g_pUDCRegs->UICR0 |= USB_UICR0_IM0;

		// Stop clock
		g_pCLKRegs->CKEN &= ~CKEN_USB;

        // Send detach
        pContext->pfnNotify(pContext->pvMddContext, 
            UFN_MSG_BUS_EVENTS, UFN_DETACH);

        pContext->attachedState = UFN_DETACH;
        pContext->fSpeedReported = FALSE;
    }

    FUNCTION_LEAVE_MSG();

    return 0;
}



/*++

Routine Description:

Deallocate register space.

Arguments:

None.

Return Value:

None.

--*/
static
VOID UnmapRegisterSet(void)
{
	if (g_pGPIORegs)
	{
		VirtualFree((PVOID) g_pGPIORegs, 0, MEM_RELEASE);
		g_pGPIORegs = NULL;
	}
	if (g_pCLKRegs)
	{
		VirtualFree((PVOID) g_pCLKRegs, 0, MEM_RELEASE);
		g_pCLKRegs = NULL;
	}
    if (g_pUDCRegs) {
        VirtualFree((PVOID) g_pUDCRegs, 0, MEM_RELEASE);
        g_pUDCRegs = NULL;
    }
}


/*++

Routine Description:

Map the base I/O address of the XScale UDC to virtual memory.

Arguments:

None.

Return Value:

Success.

--*/
static
DWORD MapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(pContext);

    DEBUGCHK(g_pUDCRegs == NULL);
    DEBUGCHK(g_pGPIORegs == NULL);
    DEBUGCHK(g_pCLKRegs == NULL);

    DWORD   dwRet = ERROR_SUCCESS;

	PHYSICAL_ADDRESS	RegPA;

	
    if (g_pUDCRegs == NULL)
    {
        RegPA.QuadPart = pContext->dwIOBase;
        g_pUDCRegs = (volatile UDC_REG_T *) MmMapIoSpace(RegPA, pContext->dwIOLen, FALSE);
    }
	
    if (g_pGPIORegs == NULL)
    {
        RegPA.QuadPart = PXA255_BASE_REG_PA_GPIO;
        g_pGPIORegs = (volatile GPIO_REG_T *) MmMapIoSpace(RegPA, sizeof(GPIO_REG_T), FALSE);
    }

    if (g_pCLKRegs == NULL)
    {
        RegPA.QuadPart = PXA255_BASE_REG_PA_CLK;
        g_pCLKRegs = (volatile CLK_REG_T *) MmMapIoSpace(RegPA, sizeof(CLK_REG_T), FALSE);
    }

    if (!g_pUDCRegs || !g_pGPIORegs || !g_pCLKRegs)
	
	{
        dwRet = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s Virtual Alloc: FAILED\r\n"), pszFname));
		UnmapRegisterSet();
    }

    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}


static
VOID
StartTransfer(
              PCTRLR_PDD_CONTEXT pContext,
              PEP_STATUS peps,
              PSTransfer pTransfer
              )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);

    DEBUGCHK(!peps->pTransfer);
    ValidateTransferDirection(pContext, peps, pTransfer);

    DEBUGMSG(ZONE_TRANSFER, (_T("%s Xfer ep %u for %u bytes\r\n"),
        pszFname, peps->dwEndPointNumber, pTransfer->cbBuffer));

    // Enable transfer interrupts.
    peps->pTransfer = pTransfer;
    // Enable transfer interrupts.


    if (peps->dwEndPointNumber == 0) {
        peps->fZeroPacketNeeded = TRUE;
        if ((pTransfer->dwFlags & USB_IN_TRANSFER) != 0) {
            DEBUGCHK(pContext->ep0Request.eDir == EP0In);
        }
        else {
            DEBUGCHK(pContext->ep0Request.eDir == EP0Out);
        }
        if (!peps->fInIST) {
            ServiceSetup(pContext,peps);
        }
    }
    else {
        EnableEndpointInterrupt(pContext,peps->dwEndPointNumber);
        peps->fZeroPacketNeeded = ((pTransfer->cbBuffer== 0 || pTransfer->pvBuffer== 0) && (pTransfer->dwFlags & USB_IN_TRANSFER) != 0) ;
        // Note For the Xscale 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
        if(!peps->fInIST) {
            if ((pTransfer->dwFlags & USB_IN_TRANSFER) != 0) {
                pContext->numInPacketsSent = 0;
                HandleTx(pContext,peps);
            }
            else{
                HandleRx(pContext,peps);
            }
        }
    }
    FUNCTION_LEAVE_MSG();
}


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->dwUsbError == UFN_NOT_COMPLETE_ERROR);
    DEBUGCHK(pTransfer->cbTransferred == 0);

    DWORD dwRet = ERROR_SUCCESS;

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

    if (peps->dwEndPointNumber == 0) {
        if ((pTransfer->dwFlags & USB_IN_TRANSFER)!= 0 ) {
            if (pContext->ep0Request.eDir != EP0In) {
                DEBUGMSG(ZONE_WARNING, (_T("%s EP0 is not in IN state. State = %u\r\n"), 
                    pszFname, pContext->ep0Request.eDir));
                dwRet = ERROR_NOT_READY;    
                goto EXIT;
            }
        }
        else {
            if (pContext->ep0Request.eDir != EP0Out) {
                DEBUGMSG(ZONE_WARNING, (_T("%s EP0 is not in OUT state. State = %u\r\n"), 
                    pszFname, pContext->ep0Request.eDir));
                dwRet = ERROR_NOT_READY;
                goto EXIT;
            }
        }
    }
    
    StartTransfer(pContext, peps, pTransfer);

EXIT:
    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);

    ValidateTransferDirection(pContext, peps, pTransfer);

    DEBUGCHK(pTransfer == peps->pTransfer);

    if (dwEndpoint == 0) {
        pContext->fEndpoint0AckNeeded = FALSE;
    }
    
    ResetEndpoint(pContext, peps);
    CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);

    UNLOCK_ENDPOINT(peps);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;

⌨️ 快捷键说明

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