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

📄 isp1581.cpp

📁 EP9315开发板的Wince6.0的BSP包文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//**********************************************************************
//                                                                      
// Filename: ISP1581.CPP
//                                                                      
// Description: ISP1581 USB Function Platform-Dependent Driver.
//
// 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.
//
// Use of this source code is subject to the terms of the Cirrus 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 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved 
//                                                                      
//**********************************************************************

#include "isp1581.h"

#include <ceddk.h>
#include <devload.h>
#include <ddkreg.h>
#include <nkintr.h>
#include <hwdefs.h>
#include <oalintr.h>



#define ACTIVE_HIGH

#ifdef ACTIVE_HIGH
#define DMA_PIN_CONFIG M2M_CTRL_ETDP_AHIGH_OUTPUT | \
                       M2M_CTRL_DACKP_ACTIVEHIGH | \
                       M2M_CTRL_DREQP_HIGHLEVEL
#define USB_PIN_CONFIG USB_DMAHW_EOT_ACTIVE_HIGH | \
                       USB_DMAHW_ACK_ACTIVE_HIGH | \
                       USB_DMAHW_DREQ_ACTIVE_HIGH
#else
#define DMA_PIN_CONFIG M2M_CTRL_ETDP_ALOW_OUTPUT | \
                       M2M_CTRL_DREQP_LOWLEVEL
#define USB_PIN_CONFIG USB_DMAHW_EOT_ACTIVE_LOW | \
                       USB_DMAHW_ACK_ACTIVE_LOW | \
                       USB_DMAHW_DREQ_ACTIVE_LOW
#endif



UFN_GENERATE_DPCURSETTINGS(UFN_DEFAULT_DPCURSETTINGS_NAME, 
    _T("Interrupts"), _T("Power"), _T(""), _T(""), 
    DBG_ERROR | DBG_INIT); 
    
    
#define REG_ALIGN_OFFSET 1
#define UDC_REG_PRIORITY_VAL _T("Priority256")
#define UDC_DMA_ENABLE_VAL _T("DMAEnable")

typedef struct _EP_STATUS {
    DWORD                   dwEndpoint;
    BOOL                    fInitialized;
    unsigned short          wMaxPacketSize;
    unsigned short          bmAttributes;
    PSTransfer              pTransfer;
    CRITICAL_SECTION        cs;

#ifdef DEBUG
    LPCTSTR                 pszType;
#endif
} EP_STATUS, *PEP_STATUS;



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


#define EP_0_PACKET_SIZE        0x40
#define EP_EF_MAX_PACKET_SIZE   0x40
#define EP_0EF_FIFO_CAPACITY    0x40
#define EP_ABCD_FIFO_CAPACITY   1024
#define EP_FIFO_DIVISION        (0x10000 / 4)

static int g_dma_enabled = 0;


static const EP_STATUS g_rgEpStatus[] = {
    { (0<<1) , },
    { (1<<1) , },
    { (2<<1) , },
    { (3<<1) , },
    { (4<<1) , },
    { (5<<1) , },
    { (6<<1) , },
    { (7<<1) , }
};

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

#define DEFAULT_PRIORITY 108

//#define DUMP_BUFFER
#ifdef DUMP_BUFFER
void DumpHexBuf(PUCHAR pBuf, DWORD Count)
{
#define ENTRIES_PER_LINE 16
    DWORD i,j;

    for (i = 0; i < Count; i += ENTRIES_PER_LINE)
    {
        RETAILMSG(1,(TEXT("\n0x%08X    "),i));

        for (j = 0; j < ENTRIES_PER_LINE; j++)
        {
            if ((i+j) >= Count)
                RETAILMSG(1,(TEXT("   ")));
            else
                RETAILMSG(1,(TEXT("%02X "), pBuf[i+j]));
        }

        for (j = 0; j < ENTRIES_PER_LINE; j++)
        {
            if ((i+j) >= Count)
            {
                break;
            }
            else
            {
                if ( ((pBuf[i+j] & 0xff)<0x20) || ((pBuf[i+j] & 0xff)> 0x7f) )
                    RETAILMSG(1, (TEXT(".")));
                else
                    RETAILMSG(1, (TEXT("%c"), pBuf[i+j]));
            }
        }
    }

    RETAILMSG(1, (TEXT("\n")));
}
#else
#define DumpHexBuf(x,y)
#endif

enum DEVICE_STATUS {
    DS_DETACHED = 0,
    DS_ATTACHED,
    DS_POWERED,
    DS_DEFAULT,
    DS_ADDRESSED,
    DS_CONFIGURED,
    DS_SUSPENDED,
};

typedef struct _USBSLAVE_PDD_CONTEXT
{
    DWORD               dwSig;
    PBYTE               pbConfigAddr;
    PBYTE               pbFifoAddr;
    PVOID               pvMddContext;
    HANDLE              hIST;
    HANDLE              hevInterrupt;
    DWORD               dwISTPriority;
    BOOL                fRunning;
    CRITICAL_SECTION    csSharedRegisterAccess;
    DWORD               dwSysIntr;
    HANDLE              hISRHandler;
    BOOL                fSpeedReported;
    volatile BOOL       fExitIST;
    BOOL                fRestartIST;
    BOOL                fForceFullSpeed;
    BOOL                fAttached;
    PFN_UFN_MDD_NOTIFY  pfnNotify;
    HANDLE              hBusAccess;
    CEDEVICE_POWER_STATE cpsCurrent;
    DEVICE_STATUS 		DeviceStatus;
    EP_STATUS           rgEpStatus[ENDPOINT_COUNT];
//
    unsigned long       pusTemIOBASE;
    unsigned char       ucSetupFlags;

    unsigned long       pusDMAVirtualBASE;
    unsigned long       pusDMAPhysicalBASE;
} USBSLAVE_PDD_CONTEXT, *PUSBSLAVE_PDD_CONTEXT;

//
//
//
//*****************************************************************************
//
//DelayuS delay some us time
//
//******************************************************************************
void DelayuS(ULONG ulMicroSec)
{
    LARGE_INTEGER liStart, liCurrent;
    BOOL b;
    b = QueryPerformanceCounter(&liStart);
    ASSERT(b);
    
    do
    {
        Sleep(0);
        b = QueryPerformanceCounter(&liCurrent);
        ASSERT(b);
    } while((liStart.QuadPart + (LONGLONG)ulMicroSec) >=liCurrent.QuadPart);
}


//****************************************************************************
//
// USBStallEndpoint stalls or un-stalls the specified endpoint.
//
//****************************************************************************
void
USBStallEndpoint( PUSBSLAVE_PDD_CONTEXT pContext,unsigned long ulEndpoint, unsigned long bStall)
{
    volatile unsigned short *pIOBASE =  (unsigned short *)pContext->pusTemIOBASE;
    
    if(bStall)
    {
        pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short)(ulEndpoint) ;
        pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] |= USB_EPCONTROL_STALL;

        pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET] &= ~USB_EPTYPE_ENABLE;
        pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET] |= USB_EPTYPE_ENABLE;
    }
    else
    {
    	if(0 == ulEndpoint)
    	{
            pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short)(ulEndpoint) ;
            pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] &= ~USB_EPCONTROL_STALL;
    	}
    	else
    	{
            pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short)(ulEndpoint) ;
            pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] &= ~USB_EPCONTROL_STALL;
    
            pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET] &= ~USB_EPTYPE_ENABLE;
            pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET] |= USB_EPTYPE_ENABLE;
    	}
    }
}

#define SET   TRUE
#define CLEAR FALSE


// Retrieve the endpoint status structure.
inline
static
PEP_STATUS
GetEpStatus(
    PUSBSLAVE_PDD_CONTEXT pContext,
    DWORD dwEndpoint
    )
{
    PEP_STATUS peps = &pContext->rgEpStatus[dwEndpoint];
    return peps;
}

static inline VOID
EnableEndpointInterrupt(
    PUSBSLAVE_PDD_CONTEXT pContext,
    DWORD dwEndpoint
    )
{

    volatile unsigned short *pIOBASE =  (unsigned short *)pContext->pusTemIOBASE;
    unsigned long ulIntMask;

    DelayuS(500);
    
    ulIntMask   =   (0xC00<< (dwEndpoint & (~1)) );

    pIOBASE[HwUSBIntEnable >> REG_ALIGN_OFFSET] |= (unsigned short)ulIntMask;
    pIOBASE[(HwUSBIntEnable >> REG_ALIGN_OFFSET) + 1] |= (unsigned short)(ulIntMask>>16);
}


static inline VOID
DisableEndpointInterrupt(
    PUSBSLAVE_PDD_CONTEXT pContext,
    DWORD dwEndpoint
    )
{
    volatile unsigned short *pIOBASE =  (unsigned short *)pContext->pusTemIOBASE;
    unsigned long ulIntMask;


    DelayuS(500);
    ulIntMask   =   (0xC00<< (dwEndpoint & (~1)) );

    pIOBASE[HwUSBIntEnable >> REG_ALIGN_OFFSET] &= (unsigned short)(~ulIntMask);
    pIOBASE[(HwUSBIntEnable >> REG_ALIGN_OFFSET) + 1] &= (unsigned short)((~ulIntMask)>>16);
}

//****************************************************************************
//
// InitEndpoint.
//
//****************************************************************************
void InitEndpoint(
    PVOID                       pvPddContext,
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDesc,
    DWORD                       dwEndpoint
)
{
    PUSBSLAVE_PDD_CONTEXT pContext = (PUSBSLAVE_PDD_CONTEXT) pvPddContext;
    volatile unsigned short *pIOBASE =  (unsigned short *)pContext->pusTemIOBASE;
    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);

    if(!peps->fInitialized) return;
    LOCK_ENDPOINT(peps);

	if(USB_DIRECTION_IN(pEndpointDesc->bEndpointAddress)) 
	{
		peps->dwEndpoint |= USB_ENDPOINT_DIR_IN;
	}
	else
    {
		peps->dwEndpoint |= USB_ENDPOINT_DIR_OUT;
	}

     // Write the packet size and count of transactions / microframe
    pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short) (peps->dwEndpoint);
    pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET] = 0xff00;
    pIOBASE[HwUSBEndpointMaxPacketSize >> REG_ALIGN_OFFSET] = (unsigned short) peps->wMaxPacketSize;
    
    // Configure and enable the endpoint
    pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short) (peps->dwEndpoint);
    pIOBASE[HwUSBEndpointType >> REG_ALIGN_OFFSET]  = (
                                                USB_EPTYPE_NO_EMPTY |
                                                USB_EPTYPE_DOUBLE_BUFFER |
                                                peps->bmAttributes  |
                                                USB_EPTYPE_ENABLE
                                                );
    // Clear FIFO
    pIOBASE[HwUSBEndpointIndex >> REG_ALIGN_OFFSET] = (unsigned short) (peps->dwEndpoint);
    pIOBASE[HwUSBEndpointControl >> REG_ALIGN_OFFSET] |= USB_EPCONTROL_CLEAR;

    UNLOCK_ENDPOINT(peps);
}

//****************************************************************************
//
// USBEnable configures the ISP1581 device.
//
//****************************************************************************
void
USBChipEnable(PUSBSLAVE_PDD_CONTEXT pContext, BOOL bSoftReset)
{
    unsigned long dwIntMask;
    volatile unsigned short *pIOBASE =  (unsigned short *)pContext->pusTemIOBASE;
    
    if(bSoftReset)
    {
        pIOBASE[HwUSBMode >> REG_ALIGN_OFFSET] = USB_MODE_SOFT_RESET;
        Sleep(50);
    }
    //
    //Enable USB
    //
    pIOBASE[HwUSBAddress >> REG_ALIGN_OFFSET] |= USB_ADDRESS_DEVICE_ENABLE;

//    Sleep(10);

    //
    // Configure the ISP1581 and enable the SoftConnect pull-up.
    //

    pIOBASE[HwUSBMode >> REG_ALIGN_OFFSET]=0;/*disable the ,and SoftConnect pull-down*/

    pIOBASE[HwUSBMode >> REG_ALIGN_OFFSET] |= 
                USB_MODE_CLOCK_ON | 
                USB_MODE_WAKE_UP_CS | 
                USB_MODE_INT_ENABLE | 
                USB_MODE_SOFT_CONNECT;/*0x09=|1001|*/

//    Sleep(10);

    //
    // Configure the interrupt line.
    //
    pIOBASE[HwUSBIntConfig >> REG_ALIGN_OFFSET] |= 
                USB_INTCONFIG_CDBGMOD_ACK |
                USB_INTCONFIG_DDBGMODIN_ACK |
                USB_INTCONFIG_DDBGMODOUT_ACK |
                0x01;


    //
    // Enable the interrupts for the bulk endpoints.
    //
    dwIntMask = 
//                USB_INT_EP7_RX |
//                USB_INT_EP7_TX |
//                USB_INT_EP6_RX |
//                USB_INT_EP6_TX |
//                USB_INT_EP5_RX |
//                USB_INT_EP5_TX |
//                USB_INT_EP4_RX |
//                USB_INT_EP4_TX |
//                USB_INT_EP3_RX |
//                USB_INT_EP3_TX |
                USB_INT_EP2_RX |
                USB_INT_EP2_TX |
                USB_INT_EP1_RX |
                USB_INT_EP1_TX |
                USB_INT_EP0_RX |
                USB_INT_EP0_TX |
                USB_INT_HS_STATUS |
                USB_INT_EP0_SETUP |
                USB_INT_BUS_RESET ;
                //|USB_INT_DMA);


 
    pIOBASE[HwUSBIntEnable >> REG_ALIGN_OFFSET] = (unsigned short) dwIntMask;
    pIOBASE[(HwUSBIntEnable >> REG_ALIGN_OFFSET) + 1] = (unsigned short) (dwIntMask>>16);

    // 
    // Reset 1581 dma core
    //
    pIOBASE[HwUSBDMACommand >> REG_ALIGN_OFFSET] = USB_DMACOMMAND_RESET_DMA;

    //
    // Set DMA ep to an unused endpoint.
    //
    pIOBASE[HwUSBDMAEndpoint >> REG_ALIGN_OFFSET] = USB_DMAEP_SEVEN_OUT;

    // 
    // init 1581 DMA
    //
    pIOBASE[HwUSBDMAConfig >> REG_ALIGN_OFFSET]  = 
            (USB_DMACONFIG_BURST_1|
            USB_DMACONFIG_MODE_DACK | 
            USB_DMACONFIG_WIDTH_16);  

    pIOBASE[HwUSBDMAHardware >> REG_ALIGN_OFFSET] =
            (USB_DMAHW_ENDIAN_NORMAL |
            USB_PIN_CONFIG |
            USB_DMAHW_WRITE_ACTIVE_LOW |
            USB_DMAHW_READ_ACTIVE_LOW);


    //
    // enable 1581 DMA interrupt
    //
    pIOBASE[HwUSBDMAIntEnable >> REG_ALIGN_OFFSET]  = 0x0D00;

}


static
VOID
ResetDevice(

⌨️ 快捷键说明

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