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

📄 z228_usb_msc.cpp

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*++
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subject to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2006 Jade Technologies Co., Ltd. 
*   All rights reserved.

Module Name: 

        z228_usb_msc.CPP

Abstract:

        OTG USB Function (Mass Storage) Platform -Dependent Driver.

--*/

//#define CHN
//#define DEBUG_TEXT

#ifdef CHN
#define MESSAGE_TITLE TEXT("选择'是'为U盘模式,选择'否'为充电模式(请确保选择U盘模式前,将当前运行的应用程序关闭!!)")
#else
#define MESSAGE_TITLE TEXT("Press 'YES' to Storage Mass or 'NO' to charge?(Please quit the running programs before you press 'YES'!!)")
#endif

#include "z228_usb_msc.h"
#include <ceddk.h>
#include <devload.h>
#include <ddkreg.h>
#include <nkintr.h>
#include <netui.h>
#include <pkfuncs.h>
#include <oalfuncs.h>
#include "dma.h"


//****************************************************
//the macro indicates if mass storage is independent
//   USB_MULTIFUN  -  Mass storage has to work with the host driver 
//     others      -  Mass storage works by itself
//****************************************************
//#define USB_MULTIFUN

#define USB_DATA_OUT    0
#define USB_DATA_IN     0
#define USB_INIT       		0
#define USB_DEBUG       0
#define USB_ERROR       1

//yz_add_070627
#define GPIO_num 8
#define GPIO_pin 2
//yz_end

#define UDC_REG_PRIORITY_VAL _T("Priority256")
#define DEFAULT_PRIORITY 108

const char pszFname[2]=" ";

#ifdef DEBUG_TEXT
	FILE * fp=NULL;
#endif

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

#define LOCK_ENDPOINT1(peps)     EnterCriticalSection(&peps->cs)
#define UNLOCK_ENDPOINT1(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>>2)

#define EP_CFG_0_OFFSET           0x300
#define EP_CFG_A_OFFSET           0x320
#define EP_CFG_B_OFFSET           0x340
#define EP_CFG_C_OFFSET           0x360
#define EP_CFG_D_OFFSET           0x380
#define EP_CFG_E_OFFSET           0x3A0
#define EP_CFG_F_OFFSET           0x3C0

#define EP_A_HS_MAXPKT_INDEX      0x020
#define EP_A_FS_MAXPKT_INDEX      0x021
#define EP_B_HS_MAXPKT_INDEX      0x030
#define EP_B_FS_MAXPKT_INDEX      0x031
#define EP_C_HS_MAXPKT_INDEX      0x040
#define EP_C_FS_MAXPKT_INDEX      0x041
#define EP_D_HS_MAXPKT_INDEX      0x050
#define EP_D_FS_MAXPKT_INDEX      0x051
#define EP_E_HS_MAXPKT_INDEX      0x060
#define EP_E_FS_MAXPKT_INDEX      0x061
#define EP_F_HS_MAXPKT_INDEX      0x070
#define EP_F_FS_MAXPKT_INDEX      0x071

typedef struct _EP_STATUS {
    DWORD                   dwEndpoint;
    DWORD                   dwBaseOffset;
    DWORD                   cbFifo;
    DWORD                   dwFifoOffset;
    DWORD                   dwFlags;
    BOOL                    fInitialized;
    DWORD                   dwPacketSizeAssigned;
    PSTransfer              pTransfer;
    CRITICAL_SECTION        cs;
#ifdef DEBUG
    LPCTSTR                 pszType;
#endif
} EP_STATUS, *PEP_STATUS;

static const EP_STATUS g_rgEpStatus[] = {
    { 0, EP_CFG_0_OFFSET, EP_0EF_FIFO_CAPACITY ,EP_FIFO_DIVISION, 0x1},
    { 1, EP_CFG_A_OFFSET, EP_ABCD_FIFO_CAPACITY ,EP_FIFO_DIVISION * 2, 0x20000 },
    { 2, EP_CFG_B_OFFSET, EP_ABCD_FIFO_CAPACITY ,EP_FIFO_DIVISION * 3 , 0x4},
    { 3, EP_CFG_C_OFFSET, EP_ABCD_FIFO_CAPACITY, },
    { 4, EP_CFG_D_OFFSET, EP_ABCD_FIFO_CAPACITY,  },
    { 5, EP_CFG_E_OFFSET, EP_0EF_FIFO_CAPACITY },
    { 6, EP_CFG_F_OFFSET, EP_0EF_FIFO_CAPACITY }
};

#define ENDPOINT_COUNT  dim(g_rgEpStatus)

typedef struct _Z228_CONTEXT {
    DWORD               dwSig;
    PBYTE               pbFifoAddr;
    PVOID               pvMddContext;
    HANDLE              hIST;    
    HANDLE              hevIntrEvent;
    HANDLE              hMainThread;
    HANDLE              hTestThread;
    HANDLE              hevDevEvent;
    HANDLE              hevDevDoneEvent;
    HANDLE              hevHostEvent;
    HANDLE              hevHostDoneEvent;
    DWORD              dwISTPriority;
    BOOL                  fRunning;
    CRITICAL_SECTION    csSharedRegisterAccess;
    DWORD               dwSysIntr;
    BOOL                  fSpeedReported;
    BOOL                  fExitIST;
    BOOL                  fRestartIST;
    BOOL                  fForceFullSpeed;
    BOOL                  fAttached;
    BOOL                  fFunction;
    PFN_UFN_MDD_NOTIFY  pfnNotify;
    HANDLE		hBusAccess;
    CEDEVICE_POWER_STATE cpsCurrent;
    EP_STATUS           rgEpStatus[ENDPOINT_COUNT];
}Z228_CONTEXT, *PZ228_CONTEXT;

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

#define 	Z228_SIG 	'822Z' // "Z228" signature

#define IS_VALID_Z228_CONTEXT(ptr) \
    ( (ptr != NULL) && (ptr->dwSig == Z228_SIG) )


#define IN_TRANSFER_INTERRUPTS  DATA_PKT_TX_INT_MASK
#define OUT_TRANSFER_INTERRUPTS DATA_PKT_RX_INT_MASK

#define  	SET  	1
#define  	CLEAR  	0

#define GET_ENDPOINT_LETTER(dw) ((dw) ? (dw) + 'A' - 1 : '0')


// Forward declarations
static
VOID
CompleteTransfer(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps,
    DWORD dwUsbError
    );

inline
static 
int 
z228_Hw_Init(
				);


DWORD
WINAPI
UfnPdd_SendControlStatusHandshake(
    PVOID           pvPddContext,
    DWORD           dwEndpoint
    );

#ifdef DEBUG

extern DBGPARAM dpCurSettings;


#define ZONE_INTERRUPTS      DEBUGZONE(8)
#define ZONE_POWER          DEBUGZONE(9)

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

// Validate the Z228 context.
static
VOID
ValidateContext(
    PZ228_CONTEXT pContext
    )
{
    PREFAST_DEBUGCHK(pContext);
    DEBUGCHK(pContext->dwSig == Z228_SIG);
    DEBUGCHK(!pContext->hevIntrEvent|| pContext->hIST);
    DEBUGCHK(VALID_DX(pContext->cpsCurrent));
    DEBUGCHK(pContext->pfnNotify);
}

static const LPCTSTR g_rgpszEndpointTypes[4] = {
    _T("CONTROL"),
    _T("ISOCHRONOUS"),
    _T("BULK"),
    _T("INTERRUPT")
};

#else

#define ValidateContext(ptr)

#endif

DWORD bCharge;

DWORD *udc_base = NULL;

/******************************************************************
 * z228 usb register's operation
 ******************************************************************/
inline unsigned long usb_read(DWORD port)
{
	return *(volatile unsigned long *)(udc_base+(port>>2));
}

inline void usb_write(DWORD val, DWORD port)
{
	*(volatile DWORD *)(udc_base+(port>>2)) = val;
}

inline void usb_set(ULONG val, DWORD port)
{
	*(volatile DWORD *)(udc_base+(port>>2))|= val;
}

inline void usb_clear(DWORD val, DWORD port)
{
	*(volatile DWORD *)(udc_base+(port>>2)) &=~val;
}

/******************************************************************
 * Low level FIFO operation
 ******************************************************************/
inline static void  copy_fifo (DWORD *dst, DWORD *src, DWORD count)
{
	DWORD i; 
	unsigned char *tsrc, *tdst;
	
	if (count > 0) {
		DWORD times = count >>2;
		DWORD remains = count & 0x3;
		
		for (i = 0; i<times; i++) 
	    	*(dst+i) = *(src+i);

   
		/* Now handle the leftovers */
		if (remains) {
			tsrc = (unsigned char *)(src + times);
			tdst = (unsigned char *)(dst + times);
			
			while (remains--)
				*tdst++ = *tsrc++;
		}
	}
}

#ifdef DEBUG
static
VOID
ValidateTransferDirection(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps,
    PSTransfer pTransfer
    )
{
    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);
    PREFAST_DEBUGCHK(pTransfer);
}
#else
#define ValidateTransferDirection(ptr1, ptr2, ptr3)
#endif

/*
 * Flush EP
 */
static
void 
flush(
   DWORD ENP
   )
{
	  usb_write(0, UDC_RX_CONTROL(ENP));
	  usb_read(UDC_RX_CONTROL(ENP));
	  usb_write(UDC_FLUSHFIFO, UDC_RX_CONTROL(ENP));
}

// Get the index to the max packet register for this endpoint and speed.
static
DWORD
GetMaxPktIdx(
    DWORD dwEndpoint,
    UFN_BUS_SPEED speed
    )
{
    DEBUGCHK(dwEndpoint < ENDPOINT_COUNT);
    DEBUGCHK(dwEndpoint); // Do not call for endpoint 0.

    DWORD dwDelta = (EP_B_HS_MAXPKT_INDEX - EP_A_HS_MAXPKT_INDEX); 
    DWORD dwIdx = (dwDelta * (dwEndpoint - 1)) + EP_A_HS_MAXPKT_INDEX;
        RETAILMSG(USB_DEBUG, (_T("==> GetMaxPktIdx ()\r\n")));

    if (speed == BS_FULL_SPEED) {
        ++dwIdx;
    }

    DEBUGCHK(dwIdx >= EP_A_HS_MAXPKT_INDEX);
    DEBUGCHK(dwIdx <= EP_F_FS_MAXPKT_INDEX);

    return dwIdx;
}


// Retrieve the endpoint status structure.
inline
static
PEP_STATUS
GetEpStatus(
    PZ228_CONTEXT pContext,
    DWORD dwEndpoint
    )
{
    ValidateContext(pContext);
    DEBUGCHK(EP_VALID(dwEndpoint));
   // RETAILMSG(USB_DEBUG, (_T("==> GetEpStatus ()\r\n")));

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

    return peps;
}


// Clear the transfer status bits.
static
inline
VOID
ClearTransferStatus(
    PZ228_CONTEXT pContext,
    const EP_STATUS *peps
    )
{
    DEBUGCHK(pContext);
    PREFAST_DEBUGCHK(peps);
    RETAILMSG(USB_DEBUG, (_T("==> ClearTransferStatus ()\r\n")));       
}


// Return the irq bit for this endpoint.
inline
static
DWORD
EpToIrqStatBit(
    DWORD dwEndpoint
    )
{
    DEBUGCHK(EP_VALID(dwEndpoint));
    RETAILMSG(USB_DEBUG, (_T("==> EpToIrqStatBit ()\r\n")));

    return (1 << dwEndpoint);
}

// Reset an endpoint
static
VOID
ResetEndpoint(
    PZ228_CONTEXT pContext,
    PEP_STATUS peps
    )
{
    
    RETAILMSG(USB_DEBUG, (_T("+ ResetEndpoint\r\n")));

    ValidateContext(pContext);
    PREFAST_DEBUGCHK(peps);
    
}
    


// Reset the z228 (device and EP0).
static
VOID
ResetDevice(
    PZ228_CONTEXT pContext
    )
{	
	PHYSICAL_ADDRESS PhysicalIoBase;
	DWORD *reset=NULL;
	DWORD  tcount =10;
	
	RETAILMSG(USB_DEBUG, (_T("+ResetDevice\r\n")));
	
	/* Disable interrupts */
	usb_write(0, UDC_INTR_ENABLE);
	usb_write(0, UDC_ENDP_INTR_ENABLE);
	usb_write(0, UHC_INTR_ENABLE);

     //system control register

⌨️ 快捷键说明

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