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

📄 sc2450pdd.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 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:  

    SC2450PDD.CPP	

Abstract:

    S3C2450 USB2.0 function device driver 

rev:

    2006.9.4	: First release (Woosuk Chung)
 
**/
#include <windows.h>
#include <nkintr.h>
#include <ddkreg.h>
#include <S3C2450.h>				
#include "sc2450pdd.h"
#include <S3C2450REF_GPIO.h>
#include <bsp.h>


static volatile BSP_ARGS *v_gBspArgs;
#define CARD_INSERTED 1
#define CARD_REMOVED 2
#define UDC_REG_PRIORITY_VAL _T("Priority256")
#define DBG 0

#define TEST_MODE_SUPPORT 1

#define INVALID_HANDLE         (HANDLE)-1

#if TEST_MODE_SUPPORT
#define USB_TEST_J 				0x01
#define USB_TEST_K 				0x02
#define USB_TEST_SE0_NAK 		0x03
#define USB_TEST_PACKET 		0x04
#define USB_TEST_FORCE_ENABLE 0x05

#define USB_FEATURE_TEST_MODE 2


#define TEST_PKT_SIZE 53
#define TEST_ARR_SIZE 27

WORD ahwTestPkt [TEST_ARR_SIZE] = {

	0x0000, 0x0000, 0x0000, 
	0xAA00, 0xAAAA, 0xAAAA, 0xAAAA,
	0xEEAA, 0xEEEE, 0xEEEE, 0xEEEE,
	0xFEEE,	0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0x7FFF, 0xDFBF,
	0xF7EF, 0xFDFB, 0x7EFC, 0xDFBF,
	0xF7EF, 0xFDFB, 0x007E, 0x0000 

};

#endif

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


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 SC2450_SIG '2450' // "SC2450" signature

#define IS_VALID_SC2450_CONTEXT(ptr) \
    ( (ptr != NULL) && (ptr->dwSig == SC2450_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 == SC2450_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")

#define DRIVER_USB_MSF_CARD_KEY TEXT("Drivers\\USB\\FunctionDrivers\\Mass_Storage_Class")
#define DRIVER_USB_MSF_CARD_VALUE  TEXT("DeviceName")


#define DRIVER_USB_MSF_MMC_KEY TEXT("Drivers\\SDCARD\\ClientDrivers\\Class\\MMC_Class")
#define DRIVER_USB_MSF_MMC_VALUE  TEXT("Index")

#define DRIVER_USB_MSF_SD_KEY TEXT("Drivers\\SDCARD\\ClientDrivers\\Class\\SDMemory_Class")
#define DRIVER_USB_MSF_SD_VALUE  TEXT("Index")



#define DRIVER_USB_MSF_FLASH_KEY TEXT("Drivers\\BuiltIn\\SMFLASH")
#define DRIVER_USB_MSF_FLASH_VALUE  TEXT("Index")
#define CLKCON_USBD (1<<7)

volatile S3C2450_CLKPWR_REG *pCLKPWR	= NULL;		// Clock power registers (needed to enable I2S and SPI clocks)
volatile S3C2450_IOPORT_REG *pIOPregs	= NULL;

// EINT2 Test Code by woo
UINT32 g_PlugIrq = IRQ_EINT2;	// Determined by SMDK2450 board layout.
UINT32 g_PlugSysIntr = SYSINTR_UNDEFINED;
HANDLE g_PlugThread;
HANDLE g_PlugEvent;
HANDLE g_SdCardDetectThread;
static DWORD PLUG_IST();
static DWORD SDCARD_DetectIST();

BOOL HW_USBClocks(CEDEVICE_POWER_STATE    cpsNew);

DWORD bSDMMCMSF = FALSE;
#define HIGH 1
#define FULL  0

#define POWER_THREAD_PRIORITY 101
// end woo
// Read a register.
inline
WORD
ReadReg(
        PCTRLR_PDD_CONTEXT pContext,
        DWORD dwOffset
        )
{
    DEBUGCHK(IS_VALID_SC2450_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_SC2450_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_SC2450_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_SC2450_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_SC2450_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_SC2450_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

⌨️ 快捷键说明

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