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

📄 pxa25xpdd.cpp

📁 pxa25x library for windows ce
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        &g_pUDCBase->uddr9, 
        &g_pUDCBase->uddr10,
        &g_pUDCBase->uddr11,
        &g_pUDCBase->uddr12,
        &g_pUDCBase->uddr13,
        &g_pUDCBase->uddr14,
        &g_pUDCBase->uddr15,
    };
    DEBUGCHK(dim(sc_rglpulDataRegs) == ENDPOINT_COUNT);

    if (dwEndpoint < dim(sc_rglpulDataRegs)) {
        lpulDataReg = sc_rglpulDataRegs[dwEndpoint];
    }

    return lpulDataReg;
} // _GetDataRegister

/*++

Routine Description:

Return the FIFO byte count register of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

The FIFO byte count register of an endpoint.

--*/
static
volatile ULONG *
_GetByteCountRegister(
              DWORD        dwEndpoint    
              )
{
    volatile ULONG *lpulByteCountReg = NULL;

    DEBUGCHK(EP_VALID(dwEndpoint));

    // only inspect endpoints capable of OUT transactions
    switch (dwEndpoint) {
        case 2:  lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc2;  break;
        case 4:  lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc4;  break;
        case 7:  lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc7;  break;
        case 9:  lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc9;  break;
        case 12: lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc12; break;
        case 14: lpulByteCountReg = (LPULONG) &g_pUDCBase->ubc14; break;
        default:
            break;
    }

    return lpulByteCountReg;
}



/*++

Routine Description:

Enable the interrupt of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

None.

--*/
static
VOID
EnableEndpointInterrupt( PCTRLR_PDD_CONTEXT pPddContext,  DWORD  dwEndpoint )
{    
    SETFNAME();
    FUNCTION_ENTER_MSG();


    PREFAST_ASSERT(dwEndpoint <16 && pPddContext != NULL);
    DEBUGMSG(ZONE_USB_EVENTS,(TEXT("EnableEndpointInterrupt (%d)"),dwEndpoint));
    EnterCriticalSection(&pPddContext->csIsrCtrlAccess);
    if ( dwEndpoint < 8 ) {
        g_pUDCBase->uicr0 &= ~(1 << dwEndpoint);
        DEBUGMSG(ZONE_PIPE,
            (_T("%s endpoint %u interrupt enabled; ucir0 -> 0x%x \r\n"), 
            pszFname,
            dwEndpoint,
            g_pUDCBase->uicr0));
    }
    else if ( dwEndpoint < 16 ) {
        g_pUDCBase->uicr1 &= ~(1 << (dwEndpoint % 8));
        DEBUGMSG(ZONE_PIPE,
            (_T("%s endpoint %u interrupt enabled; uicr1 -> 0x%x \r\n"), 
            pszFname,
            dwEndpoint,
            g_pUDCBase->uicr1));
    }
    else {
        DEBUGCHK(FALSE);
    }
    LeaveCriticalSection(&pPddContext->csIsrCtrlAccess);

    FUNCTION_LEAVE_MSG();          
} // _EnableEpInterrupt


/*++

Routine Description:

Disable the interrupt of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

None.

--*/
static
VOID
DisableEndpointInterrupt(PCTRLR_PDD_CONTEXT pPddContext,DWORD dwEndpoint )
{    
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_ASSERT(dwEndpoint <16 && pPddContext != NULL);
    DEBUGMSG(ZONE_USB_EVENTS,(TEXT("DisableEndpointInterrupt (%d)"),dwEndpoint));
    EnterCriticalSection(&pPddContext->csIsrCtrlAccess);
    if ( dwEndpoint <8 )  {
        g_pUDCBase->uicr0 |= (1 << dwEndpoint);
        DEBUGMSG(ZONE_PIPE,
            (_T("%s EP %u  Off; ucir0 -> 0x%x \r\n"), 
            pszFname,
            dwEndpoint,
            g_pUDCBase->uicr0));
    }
    else if (dwEndpoint < 16)  {
        g_pUDCBase->uicr1 |= (1 << (dwEndpoint % 8));
        DEBUGMSG(ZONE_PIPE,
            (_T("%s EP %u  Off; uicr1 -> 0x%x \r\n"), 
            pszFname,
            dwEndpoint,
            g_pUDCBase->uicr1));
    }
    else {
        DEBUGCHK(FALSE);
    }
    LeaveCriticalSection(&pPddContext->csIsrCtrlAccess);
    FUNCTION_LEAVE_MSG();

    return;

} // DisableEndpointInterrupt


// Clear the HW bits for an endpoint
static
VOID
ClearEndpointRegBits(
                     const EP_STATUS *peps
                     )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGMSG(ZONE_FUNCTION,
        (_T("%s Clearing ALL EP Bits \r\n"), 
        pszFname));


    volatile ULONG *lpulStatusReg = peps->lpulUDCCSx;
    PREFAST_DEBUGCHK(lpulStatusReg != NULL);
    // Clear Unique Endpoint 0 bits.
    if(peps->dwEndPointNumber == 0){
        // Clear the Out Packet Ready
        *lpulStatusReg |=  (USB_UDCCS0_OPR |USB_UDCCS_FTF);

        // Clear Input Packet ready
        *lpulStatusReg &= ~USB_UDCCS0_IPR;

        // Clear Setup Active
        *lpulStatusReg &= ~USB_UDCCS0_SA;

        // Remaing bits will be handled below...
    }

    // Clear Stall (Sent and Force)  if not Isoch
    if (peps->dwTypeSupported !=  USB_ENDPOINT_TYPE_ISOCHRONOUS ) {
        *lpulStatusReg &= ~USB_UDCCS_FST;    // Clear Force Stall
        *lpulStatusReg |=   USB_UDCCS_SST;     //Clear Stall Sent
    }

    // Clear Remaining Endpoint Bits
    if((peps->dwTypeSupported ==  USB_ENDPOINT_TYPE_ISOCHRONOUS )||
        (peps->dwTypeSupported == USB_ENDPOINT_TYPE_BULK ) ||
        (peps->dwTypeSupported == USB_ENDPOINT_TYPE_INTERRUPT)){
            if (peps->dwDirectionSupported==USB_IN_TRANSFER) {

                //Clear Packet Complete and Transmit Fifo Underrun
                *lpulStatusReg |= (USB_UDCCS_TPC |USB_UDCCS_TUR |USB_UDCCS_FTF);

                // Clear Short Packet
                *lpulStatusReg &= ~USB_UDCCS_TSP; 
            }
            else{ // USB_OUT_TRANSFER

                //Clear Packet Complete
                *lpulStatusReg |= USB_UDCCS_RPC;

                if (peps->dwTypeSupported ==  USB_ENDPOINT_TYPE_ISOCHRONOUS ){
                    *lpulStatusReg |= USB_UDCCS_ROF;      // Clear Receive Overflow   
                }

                // Clear DMA Enable
                *lpulStatusReg &= ~USB_UDCCS_DME; 
            }
        }

        FUNCTION_LEAVE_MSG();
}
// Reset an endpoint
static
VOID
ResetEndpoint(
              PCTRLR_PDD_CONTEXT pContext,
              EP_STATUS *peps
              )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(IS_VALID_XSC1_CONTEXT(pContext));
    PREFAST_DEBUGCHK(peps);

    // Clear any outstanding Interrupts
    // Note that Endpoint 0 WILL NOT BE DISABLED
    if (peps->dwEndPointNumber!=0)
        DisableEndpointInterrupt(pContext,peps->dwEndPointNumber);

    ClearEndpointRegBits(peps);

    FUNCTION_LEAVE_MSG();
}



// Reset the (device and EP0).
static
VOID
ResetDevice(
            PCTRLR_PDD_CONTEXT pContext
            )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(IS_VALID_XSC1_CONTEXT(pContext));

    // Disable device interrupts - set Mask Registers
    UDCCR_REM_DISABLE(g_pUDCBase->udccr);
    g_pUDCBase->uicr0 = DISABLE_INTRS_0TO7;   // Disable 0-7
    g_pUDCBase->uicr1 = DISABLE_INTRS_0TO7;   // Disable 8-15
    g_pUDCBase->udccr |= USB_UDCCR_SRM;       // Mask Remote/Suspend

    // Clear outstanding device interrupts
    g_pUDCBase->udccr  |=(USB_UDCCR_RSTIR | USB_UDCCR_SUSIR | USB_UDCCR_RESIR);

    // Disable USB interface
    UDCCR_UDE_DISABLE(g_pUDCBase->udccr);

    // Reset USB configuration    
    // Nothing to do for xscale     

    // Disable auto-enumeration
    // Nothing to do for xscale
    // Reset all endpoints
    EP_STATUS * peps;
    for (DWORD dwEndpoint = 0; dwEndpoint < ENDPOINT_COUNT; ++dwEndpoint) {
        peps = GetEpStatus(pContext, dwEndpoint);
        ResetEndpoint(pContext, peps);
    }

    // Clear outstanding Endpoint  interrupts
    g_pUDCBase->uisr0 = CLEAR_INTRS_0TO7;    // Clear Enpoint Interrupts 0-7
    g_pUDCBase->uisr1 = CLEAR_INTRS_8TO15;  // Clear Enpoint Interrupts 8-15

    FUNCTION_LEAVE_MSG();
}

#ifdef DEBUG
static
VOID
ValidateTransferDirection(
                          PCTRLR_PDD_CONTEXT pContext,
                          PEP_STATUS peps,
                          PSTransfer pTransfer
                          )
{
    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);
    PREFAST_DEBUGCHK(pTransfer);

    if (peps->dwEndPointNumber != 0) {
        DEBUGCHK(peps->dwDirectionSupported == pTransfer->dwFlags);
    }
}
#else
#define ValidateTransferDirection(ptr1, ptr2, ptr3)
#endif

static DWORD ReceiveData(PEP_STATUS peps, PBYTE pBuffer, DWORD dwLength)
{
    SETFNAME();
    DEBUGMSG(ZONE_FUNCTION, (_T("%s pBuffer=0x%x, dwLength= 0x%x\r\n"),pszFname,pBuffer,dwLength));
    PREFAST_ASSERT(pBuffer!=NULL);
    DWORD dwTotalRead = 0;
    while (dwLength && ((*(peps->lpulUDCCSx)) & USB_UDCCS0_RNE )!=0) {  // All endpoint RNE are the same bit.
        *pBuffer = (BYTE) *(peps->lpulUDDRx);
        pBuffer ++;
        dwLength --;
        dwTotalRead ++;
    }
    DEBUGMSG(ZONE_FUNCTION, (_T("%s Complete dwTotalRead = 0x%x\r\n"),pszFname,dwTotalRead));
    return dwTotalRead;
}
static DWORD XmitData(PEP_STATUS peps, PBYTE pBuffer, DWORD dwLength)
{
    SETFNAME();
    DEBUGMSG(ZONE_FUNCTION, (_T("%s pBuffer=0x%x, dwLength= 0x%x\r\n"),pszFname,pBuffer,dwLength));
    PREFAST_ASSERT(pBuffer!=NULL);
    DWORD dwTotalWrite = dwLength ;
    while ( dwLength != 0 ) {
        *(peps->lpulUDDRx) = *pBuffer ;
        pBuffer ++;
        dwLength --;
    }
    DEBUGMSG(ZONE_FUNCTION, (_T("%s Complete dwTotalWrite = 0x%x\r\n"),pszFname,dwTotalWrite));
    return dwTotalWrite;
}

static
VOID
CompleteTransfer(
                 PCTRLR_PDD_CONTEXT pContext,
                 PEP_STATUS peps,
                 DWORD dwUsbError
                 )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PSTransfer pTransfer = peps->pTransfer;
    DEBUGCHK(pTransfer);
    peps->pTransfer = NULL;

    DEBUGMSG(ZONE_TRANSFER, (_T("%s Complete Transfer Error = 0x%x\r\n"),pszFname,dwUsbError));
    pTransfer->dwUsbError = dwUsbError;
    pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_TRANSFER_COMPLETE, 
        (DWORD) pTransfer);
    
    FUNCTION_LEAVE_MSG();
}


// Read data from an endpoint.
static
VOID
HandleRx(
         PCTRLR_PDD_CONTEXT       pContext,
         PEP_STATUS peps
         )
{
    BOOL fCompleted = FALSE;

    SETFNAME();
    FUNCTION_ENTER_MSG();

    BOOL bContinue = TRUE;
    while (bContinue) {
        bContinue = FALSE;
        ULONG ulUdccs = *(peps->lpulUDCCSx);
        PSTransfer pTransfer = peps->pTransfer;
        DEBUGMSG(ZONE_USB_EVENTS || ZONE_PIPE, (_T("%s ulUdccs = %u \r\n"), pszFname, ulUdccs));
        if ((ulUdccs & USB_UDCCS_RFS)!=0 && pTransfer!=NULL && 
                pTransfer->cbTransferred < pTransfer ->cbBuffer) { // Handle Unload Packet.
            DWORD dwCurrentPermissions = GetCurrentPermissions();
            DWORD dwSize = (pTransfer->cbTransferred< pTransfer->cbBuffer? pTransfer->cbBuffer-pTransfer->cbTransferred: 0);
            dwSize = min(dwSize, peps->dwPacketSizeSupported );
            DWORD dwReturnSize = 0;
            DWORD dwError = UFN_NO_ERROR ; 
            SetProcPermissions(pTransfer->dwCallerPermissions);
            __try {
                dwReturnSize = ReceiveData(peps,(PBYTE)pTransfer->pvBuffer + pTransfer->cbTransferred , dwSize) ;
            }
            __except(EXCEPTION_EXECUTE_HANDLER) {
                dwReturnSize = 0;
                dwError =UFN_CLIENT_BUFFER_ERROR ;
            }
            SetProcPermissions(dwCurrentPermissions);
            pTransfer->cbTransferred += dwReturnSize;
            if (dwError == UFN_CLIENT_BUFFER_ERROR) { // We had error. Stall it.
                ulUdccs |= USB_UDCCS_FST;
                *(peps->lpulUDCCSx) = ulUdccs ;
                CompleteTransfer(pContext, peps, UFN_CLIENT_BUFFER_ERROR);
                continue;
            }
            bContinue = TRUE;
        }
        if (ulUdccs & USB_UDCCS_RPC ) {

⌨️ 快捷键说明

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