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

📄 pxa25xpdd.cpp

📁 pxa25x library for windows ce
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: 

pxa25xpdd.CPP

Abstract:

pxa25x (XScale) CPU USB Function Platform-Dependent Driver.

--*/

#include "pxa25xpdd.h"
#include <ddkreg.h>

#define ZONE_POWER           DEBUGZONE(8)

UFN_GENERATE_DPCURSETTINGS(UFN_DEFAULT_DPCURSETTINGS_NAME, 
    _T("Power"), _T(""), _T(""), _T(""), 
    DBG_ERROR | DBG_INIT);


#define UDC_REG_PRIORITY_VAL    _T("Priority256")
#define UDC_DEFAULT_PRIORITY    100


typedef struct EP_STATUS {
    DWORD                   dwEndPointNumber;
    DWORD                   dwTypeSupported;
    DWORD                   dwDirectionSupported;
    DWORD                   dwPacketSizeSupported;
    BOOL                    fInitialized;
    BOOL                    fZeroPacketNeeded;
    BOOL                    fInIST;
    PSTransfer              pTransfer;
    volatile ULONG         *lpulUDCCSx;
    volatile ULONG         *lpulUDDRx;
    volatile ULONG         *lpulUBCRx;
    CRITICAL_SECTION        cs;
} *PEP_STATUS;

#define LOCK_ENDPOINT(peps)     EnterCriticalSection(&peps->cs)
#define UNLOCK_ENDPOINT(peps)   LeaveCriticalSection(&peps->cs)


// endpoint packet sizes
#define EP0_PACKET_SIZE     16
#define EP1_PACKET_SIZE     64
#define EP2_PACKET_SIZE     64
#define EP3_PACKET_SIZE     256
#define EP4_PACKET_SIZE     256
#define EP5_PACKET_SIZE     8
#define EP6_PACKET_SIZE     64
#define EP7_PACKET_SIZE     64
#define EP8_PACKET_SIZE     256
#define EP9_PACKET_SIZE     256
#define EPA_PACKET_SIZE     8
#define EPB_PACKET_SIZE     64
#define EPC_PACKET_SIZE     64
#define EPD_PACKET_SIZE     256
#define EPE_PACKET_SIZE     256
#define EPF_PACKET_SIZE     8


static EP_STATUS  g_rgEpStatus[]  = {
    {
        0,                    // End Point Number
        USB_ENDPOINT_TYPE_CONTROL,        // type supported
        0,           // direction supported
        EP0_PACKET_SIZE,    // packet size supported (16 bytes)
    },
    {
        1,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK           
        USB_IN_TRANSFER,             // IN
        EP1_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        2,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK
        USB_OUT_TRANSFER,            // OUT
        EP2_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        3,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_IN_TRANSFER,             // IN
        EP3_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        4,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_OUT_TRANSFER,            // OUT
        EP4_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        5,                    // End Point Number
        USB_ENDPOINT_TYPE_INTERRUPT,      // INTERRUPT
        USB_IN_TRANSFER,             // IN
        EP5_PACKET_SIZE,    // packet size supported (8 bytes)
    },
    {
        6,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK           
        USB_IN_TRANSFER,             // IN
        EP6_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        7,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK
        USB_OUT_TRANSFER,            // OUT
        EP7_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        8,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_IN_TRANSFER,             // IN
        EP8_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        9,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_OUT_TRANSFER,            // OUT
        EP9_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        0xA,                    // End Point Number
        USB_ENDPOINT_TYPE_INTERRUPT,      // INTERRUPT
        USB_IN_TRANSFER,             // IN
        EPA_PACKET_SIZE,    // packet size supported (8 bytes)
    },
    {
        0xB,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK           
        USB_IN_TRANSFER,             // IN
        EPB_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        0xC,                    // End Point Number
        USB_ENDPOINT_TYPE_BULK,           // BULK
        USB_OUT_TRANSFER,            // OUT
        EPC_PACKET_SIZE,    // packet size supported (64 bytes)
    },
    {
        0xD,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_IN_TRANSFER,             // IN
        EPD_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        0xE,                    // End Point Number
        USB_ENDPOINT_TYPE_ISOCHRONOUS,    // ISOCHRONOUS
        USB_OUT_TRANSFER,            // OUT
        EPE_PACKET_SIZE,    // packet size supported (256 bytes)
    },
    {
        0xF,                    // End Point Number
        USB_ENDPOINT_TYPE_INTERRUPT,      // INTERRUPT
        USB_IN_TRANSFER,             // IN
        EPF_PACKET_SIZE,    // packet size supported (8 bytes)
    }
};


#define ENDPOINT_COUNT  dim(g_rgEpStatus)
#define EP_VALID(x)     ((x) < ENDPOINT_COUNT)


typedef enum {
    EP0Setup = 0,
    EP0Out,
    EP0In
} EP0_DIR;

typedef struct EP0_REQUEST {
    EP0_DIR eDir;
    BOOL fCompleted;
    DWORD dwExpectedSize;
    BOOL fBackupNext;
    USB_DEVICE_REQUEST udr;
    
} *PEP0_REQUEST;


typedef struct CTRLR_PDD_CONTEXT {
    PVOID             pvMddContext;
    DWORD             dwSig;
    HANDLE            hIST;
    HANDLE            hevInterrupt;
    DWORD             dwISTPriority;
    BOOL              fRunning;
    BOOL              fSpeedReported;
    CRITICAL_SECTION  csIsrCtrlAccess;
    BOOL              attachedState;
    DWORD             numInPacketsSent;
    PVOID             pvLibContext;
    PFN_UFN_MDD_NOTIFY pfnNotify;
    HANDLE            hBusAccess;
    CEDEVICE_POWER_STATE cpsCurrent;

    EP0_REQUEST       ep0Request;

    // Registry
    DWORD             dwIOBase;
    DWORD             dwIOLen;
    DWORD             dwIrq;
    DWORD             dwSysIntr;

    BOOL              fEndpoint0AckNeeded;
    BOOL              fExitIST;
    BOOL              fRestartIST;
    BOOL              fIgnoreReset;

    WORD              wConfigurationValue;
    
    EP_STATUS         rgEpStatus[ENDPOINT_COUNT];
} *PCTRLR_PDD_CONTEXT;

#define XSC1_SIG 'XSC1' // "XScale" signature

#define IS_VALID_XSC1_CONTEXT(ptr) \
    ( (ptr != NULL) && (ptr->dwSig == XSC1_SIG) )


// determine whether the target endpoint can support OUT transfers
#define EP_OUT_CAPABLE(x)   ((x == 0) || (x == 2) || (x == 4) || (x == 7) || (x == 9) || (x == 12) || (x == 14))

// determine whether the target endpoint can support IN transfers
#define EP_IN_CAPABLE(x)    (( ! EP_OUT_CAPABLE(x) ) || (x == 0))


// Create Generic USB UDC In Endpoint  Control/Status Register (UDCCS) by
// Mapping to UDCCS1 bit definitions. All other "In" regs follow the same bit definition.
#define USB_UDCCS_TFS USB_UDCCS1_TFS // Tx FIFO has room for at least one packet
#define USB_UDCCS_TPC USB_UDCCS1_TPC // Packet sent and err/status bits valid
#define USB_UDCCS_FTF USB_UDCCS0_FTF // Flush the Tx FIFO
#define USB_UDCCS_TUR USB_UDCCS1_TUR // Tx FIFO experienced underrun
#define USB_UDCCS_SST USB_UDCCS1_SST // Write 1 to clear.  Stall was sent
#define USB_UDCCS_FST USB_UDCCS1_FST // Issue stall handshake
#define USB_UDCCS_TSP USB_UDCCS1_TSP // Short packet ready for transmission

// Create Generic USB UDC Out Endpoint  Control/Status Register (UDCCS) by
// Mapping to UDCCS2 bit definitions. All other "Out" regs follow the same bit definition.
#define USB_UDCCS_RFS  USB_UDCCS2_RFS  // Rx FIFO has 1 or more packets
#define USB_UDCCS_RPC  USB_UDCCS2_RPC  // Rx packet received and err/stats valid
#define USB_UDCCS_DME  USB_UDCCS2_DME  // DMA Enable
#define USB_UDCCS_RNE  USB_UDCCS2_RNE  // Receive FIFO is not empty
#define USB_UDCCS_RSP  USB_UDCCS2_RSP  // Short packet ready for reading

// Create Generic Mapping to Receive Registers
#define USB_UDCCS_ROF  USB_UDCCS4_ROF  // Receieve Overflow


#define DISABLE_INTRS_0TO7  0xFF  // Disable Interrupts 0 - 7
#define DISABLE_INTRS_8TO15 0xFF  // Disable Interrupts 8 - 15
#define CLEAR_INTRS_0TO7    0xFF  // Disable Interrupts 0 - 7
#define CLEAR_INTRS_8TO15   0xFF  // Disable Interrupts 8 - 15

// Mapping of ARM USB UDC Registers to User Space
volatile UDC_REGS *g_pUDCBase;

#define IN_TRANSFER     1
#define OUT_TRANSFER    2


// Forward Declaration Here 
extern "C" {
BOOL InitClock();
BOOL StartClock(unsigned int,BOOL);
BOOL StopClock(unsigned int,BOOL);
}


#ifdef DEBUG

// Validate the Xscale context.
static
VOID
ValidateContext(
                PCTRLR_PDD_CONTEXT pContext
                )
{
    PREFAST_DEBUGCHK(pContext);
    DEBUGCHK(pContext->dwSig == XSC1_SIG);
    DEBUGCHK(!pContext->hevInterrupt || pContext->hIST);
    DEBUGCHK(pContext->pfnNotify);
}

#else
#define ValidateContext(ptr)
#endif



// Retrieve the endpoint status structure.
static
inline
PEP_STATUS
GetEpStatus(
            PCTRLR_PDD_CONTEXT pContext,
            DWORD dwEndpoint
            )
{
    PEP_STATUS peps;

    ValidateContext(pContext);
    DEBUGCHK(EP_VALID(dwEndpoint));

    peps = &pContext->rgEpStatus[dwEndpoint];
    DEBUGCHK(peps->dwEndPointNumber == dwEndpoint);

    return peps;
}

/*++

Routine Description:

Return the control/status register of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

The control/status register of the target endpoint.

--*/
static
volatile ULONG *
_GetControlStatusRegister(
                          DWORD        dwEndpoint
                          )
{
    volatile ULONG *lpulStatusReg = NULL;

    DEBUGCHK(EP_VALID(dwEndpoint));

    static volatile ULONG * const sc_rglpulStatusRegs[] = {
        &g_pUDCBase->udccs0, 
        &g_pUDCBase->udccs1, 
        &g_pUDCBase->udccs2, 
        &g_pUDCBase->udccs3, 
        &g_pUDCBase->udccs4, 
        &g_pUDCBase->udccs5, 
        &g_pUDCBase->udccs6, 
        &g_pUDCBase->udccs7, 
        &g_pUDCBase->udccs8, 
        &g_pUDCBase->udccs9, 
        &g_pUDCBase->udccs10,
        &g_pUDCBase->udccs11,
        &g_pUDCBase->udccs12,
        &g_pUDCBase->udccs13,
        &g_pUDCBase->udccs14,
        &g_pUDCBase->udccs15,
    };
    DEBUGCHK(dim(sc_rglpulStatusRegs) == ENDPOINT_COUNT);

    if (dwEndpoint < dim(sc_rglpulStatusRegs)) {
        lpulStatusReg = sc_rglpulStatusRegs[dwEndpoint];
    }
    
    return lpulStatusReg;
} // _GetControlStatusRegister

/*++

Routine Description:

Return the data register of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

The data register of the target endpoint.

--*/
static
volatile ULONG *
_GetDataRegister(
                 DWORD        dwEndpoint    
                 )
{
    volatile ULONG *lpulDataReg = NULL;

    DEBUGCHK(EP_VALID(dwEndpoint));

    static volatile ULONG * const sc_rglpulDataRegs[] = {
        &g_pUDCBase->uddr0, 
        &g_pUDCBase->uddr1, 
        &g_pUDCBase->uddr2, 
        &g_pUDCBase->uddr3, 
        &g_pUDCBase->uddr4, 
        &g_pUDCBase->uddr5, 
        &g_pUDCBase->uddr6, 
        &g_pUDCBase->uddr7, 
        &g_pUDCBase->uddr8, 

⌨️ 快捷键说明

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