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

📄 sc2450pdd.cpp.forboardrev1

📁 SMDK2416_BSP
💻 FORBOARDREV1
📖 第 1 页 / 共 5 页
字号:
/**
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.
Copyright (c) 2006 Samsung Electronics, co. ltd  All rights reserved.

Module Name:  

    SC2443PDD.CPP	

Abstract:

    S3C2443 USB2.0 function device driver 

rev:

    2006.9.4	: First release (Woosuk Chung)
 
**/
#include <windows.h>
#include <nkintr.h>
#include <ddkreg.h>
#include <S3C2443.h>				
#include "sc2443pdd.h"


#define UDC_REG_PRIORITY_VAL _T("Priority256")
#define DBG 0

enum EP0_STATE {
    EP0_STATE_IDLE = 0,
    EP0_STATE_IN_DATA_PHASE,
    EP0_STATE_OUT_DATA_PHASE
};

#define IN_TRANSFER  1
#define OUT_TRANSFER 2

typedef struct EP_STATUS {
    DWORD                   dwEndpointNumber;
    DWORD                   dwDirectionAssigned;
    DWORD                   dwPacketSizeAssigned;
    BOOL                    fInitialized;
    DWORD                   dwEndpointType;
    PSTransfer              pTransfer;
    CRITICAL_SECTION        cs;
} *PEP_STATUS;

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


#define EP_0_PACKET_SIZE    0x40    // usb2.0  

#define ENDPOINT_COUNT  9
#define EP_VALID(x)     ((x) < ENDPOINT_COUNT)


#define DEFAULT_PRIORITY 100

//kim sang hee

DWORD StallFlag= FALSE;

typedef struct CTRL_PDD_CONTEXT {
    PVOID             pvMddContext;
    DWORD             dwSig;
    HANDLE            hIST;
    HANDLE            hevInterrupt;
    BOOL              fRunning;
    CRITICAL_SECTION  csIndexedRegisterAccess;
    BOOL              fSpeedReported;
    BOOL              fRestartIST;
    BOOL              fExitIST;
    BOOL              attachedState;
    BOOL              sendDataEnd;
    EP0_STATE         Ep0State;
    
    // registry 
    DWORD             dwIOBase;
    DWORD             dwSysIntr;
    DWORD             dwIrq;
    DWORD             dwIOLen;
    DWORD             dwISTPriority;

    USB_DEVICE_REQUEST udr;
    EP_STATUS         rgEpStatus[ENDPOINT_COUNT];
    
    PFN_UFN_MDD_NOTIFY      pfnNotify;
    HANDLE                  hBusAccess;
    CEDEVICE_POWER_STATE    cpsCurrent;
} *PCTRLR_PDD_CONTEXT;

#define SC2443_SIG '2443' // "SC2443" signature

#define IS_VALID_SC2443_CONTEXT(ptr) \
    ( (ptr != NULL) && (ptr->dwSig == SC2443_SIG) )


#ifdef DEBUG

#define ZONE_POWER           DEBUGZONE(8)

UFN_GENERATE_DPCURSETTINGS(UFN_DEFAULT_DPCURSETTINGS_NAME, 
    _T("Power"), _T(""), _T(""), _T(""), 
    DBG_ERROR | DBG_INIT); 
// Caution: Turning on more debug zones can cause STALLs due
// to corrupted setup packets.

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

#else
#define ValidateContext(ptr)
#endif

volatile BYTE *g_pUDCBase;

static BYTE USBClassInfo;
#define USB_RNDIS  0
#define USB_Serial 1
#define USB_MSF    2

#define SET   TRUE
#define CLEAR FALSE

#define CTRLR_BASE_REG_ADDR(offset) ((volatile ULONG*) ( (g_pUDCBase) + (offset)))

#define DRIVER_USB_KEY TEXT("Drivers\\USB\\FunctionDrivers")
#define DRIVER_USB_VALUE TEXT("DefaultClientDriver")

// Read a register.
inline
WORD
ReadReg(
        PCTRLR_PDD_CONTEXT pContext,
        DWORD dwOffset
        )
{
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));

    volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
    WORD bValue = (WORD) *pbReg;
    return bValue;
}


// Write a register.
inline
VOID
WriteReg(
         PCTRLR_PDD_CONTEXT pContext,
         DWORD dwOffset,
         DWORD bValue
         )
{
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));

    volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
    *pbReg = (ULONG) bValue;
}



// Calling with dwMask = 0 and SET reads and writes the contents unchanged.
inline
BYTE
SetClearReg(
            PCTRLR_PDD_CONTEXT pContext,
            DWORD dwOffset,
            WORD dwMask,
            BOOL  bSet
            )
{
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));

    volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
    BYTE bValue = (BYTE) *pbReg;

    if (bSet) {
        bValue |= dwMask;
    }
    else {
        bValue &= ~dwMask;
    }

    *pbReg = bValue;

    return bValue;
}
// Calling with dwMask = 0 and SET reads and writes the contents unchanged.
inline
BYTE
SetClearIndexedReg(
                   PCTRLR_PDD_CONTEXT pContext,
                   DWORD dwEndpoint,
                   DWORD dwOffset,
                   WORD dwMask,
                   BOOL  bSet
                   )
{
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));
    BYTE bValue = 0;

    EnterCriticalSection(&pContext->csIndexedRegisterAccess);
    // Write the EP number to the index reg
    WriteReg(pContext, IR, (BYTE) dwEndpoint);    
    // Now Write the Register associated with this Endpoint for a given offset
    bValue = SetClearReg(pContext, dwOffset, dwMask, bSet);
    LeaveCriticalSection(&pContext->csIndexedRegisterAccess);

    return bValue;
}

// Read an indexed register.
inline
WORD
ReadIndexedReg(
               PCTRLR_PDD_CONTEXT pContext,
               DWORD dwEndpoint,
               DWORD regOffset
               )
{
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));

    EnterCriticalSection(&pContext->csIndexedRegisterAccess);
    // Write the EP number to the index reg
    WriteReg(pContext, IR, (BYTE) dwEndpoint);
    // Now Read the Register associated with this Endpoint for a given offset
    WORD bValue = ReadReg(pContext, regOffset);
    LeaveCriticalSection(&pContext->csIndexedRegisterAccess);
    return bValue;
}


// Write an indexed register.
inline
VOID
WriteIndexedReg(
                PCTRLR_PDD_CONTEXT pContext,
                DWORD dwEndpoint,
                DWORD regOffset,
                DWORD  bValue
                )
{  
    DEBUGCHK(IS_VALID_SC2443_CONTEXT(pContext));

    EnterCriticalSection(&pContext->csIndexedRegisterAccess);
    // Write the EP number to the index reg
    WriteReg(pContext, IR, (BYTE) dwEndpoint);    
    // Now Write the Register associated with this Endpoint for a given offset
    WriteReg(pContext, regOffset, bValue);
    LeaveCriticalSection(&pContext->csIndexedRegisterAccess);
}

/*++

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 *pulDataReg = NULL;

    //
    // find the data register (non-uniform offset)
    //
    switch (dwEndpoint) {
        case  0: pulDataReg = CTRLR_BASE_REG_ADDR(EP0BR);  break;
        case  1: pulDataReg = CTRLR_BASE_REG_ADDR(EP1BR);  break;
        case  2: pulDataReg = CTRLR_BASE_REG_ADDR(EP2BR);  break;
        case  3: pulDataReg = CTRLR_BASE_REG_ADDR(EP3BR);  break;
        case  4: pulDataReg = CTRLR_BASE_REG_ADDR(EP4BR);  break;
        case  5: pulDataReg = CTRLR_BASE_REG_ADDR(EP5BR);  break;
        case  6: pulDataReg = CTRLR_BASE_REG_ADDR(EP6BR);  break;
        case  7: pulDataReg = CTRLR_BASE_REG_ADDR(EP7BR);  break;
        case  8: pulDataReg = CTRLR_BASE_REG_ADDR(EP8BR);  break;
        default:
            DEBUGCHK(FALSE);
            break;
    }

    return pulDataReg;
} // _GetDataRegister


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

    PEP_STATUS peps = &pContext->rgEpStatus[dwEndpoint];

    return peps;
}


// Return the irq bit for this endpoint.
inline
static
BYTE
EpToIrqStatBit(
               DWORD dwEndpoint
               )
{
    DEBUGCHK(EP_VALID(dwEndpoint));

    return (1 << (BYTE)dwEndpoint);
}

/*++

Routine Description:

Enable the interrupt of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

None.

--*/
static
VOID
EnableDisableEndpointInterrupt(
                        PCTRLR_PDD_CONTEXT  pContext,
                        DWORD               dwEndpoint,
                        BOOL                fEnable
                        )
{
    // TODO: Make new cs or rename this one
    EnterCriticalSection(&pContext->csIndexedRegisterAccess);
    
    // Disable the Endpoint Interrupt
    WORD bEpIntReg = ReadReg(pContext, EIER);
    BYTE bIrqEnBit = EpToIrqStatBit(dwEndpoint);

    if (fEnable) {
        bEpIntReg |= bIrqEnBit;
    }
    else {
        bEpIntReg &= ~bIrqEnBit;
    }
    
    WriteReg(pContext, EIER, bEpIntReg);

    LeaveCriticalSection(&pContext->csIndexedRegisterAccess);    
}

static
inline
VOID
EnableEndpointInterrupt(
    PCTRLR_PDD_CONTEXT  pContext,
    DWORD               dwEndpoint
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    EnableDisableEndpointInterrupt(pContext, dwEndpoint, TRUE);

    FUNCTION_LEAVE_MSG();
}

static
inline
VOID
DisableEndpointInterrupt(
    PCTRLR_PDD_CONTEXT  pContext,
    DWORD               dwEndpoint
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    EnableDisableEndpointInterrupt(pContext, dwEndpoint, FALSE);

    FUNCTION_LEAVE_MSG();
}

/*++

Routine Description:

Clear the interrupt status register index of an endpoint.

Arguments:

dwEndpoint - the target endpoint

Return Value:

None.

--*/
static
VOID
ClearEndpointInterrupt(
                       PCTRLR_PDD_CONTEXT pContext,
                       DWORD        dwEndpoint
                       )
{    
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    // Clear the Endpoint Interrupt
    BYTE bIntBit = EpToIrqStatBit(dwEndpoint);
    WriteReg(pContext, EIR, bIntBit);

    FUNCTION_LEAVE_MSG();
} // _ClearInterrupt


// Reset an endpoint

VOID
ResetEndpoint(
              PCTRLR_PDD_CONTEXT pContext,

⌨️ 快捷键说明

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