📄 usbser.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <windows.h>
#include <oal.h>
#include <usb100.h>
#include <usbdbgddsi.h>
#include <usbfntypes.h>
#include <usbdbgutils.h>
#include "usbser.h"
///=============================================================================
/// extern variables
///=============================================================================
///=============================================================================
/// Extern functions
///=============================================================================
// implemented by PDD
extern BOOL UsbDbgPdd_Init (USBDBG_MDD_INTERFACE_INFO* pMddIfc,
USBDBG_PDD_INTERFACE_INFO* pPddIfc,
USBDBG_DEVICE_DESCRIPTOR* pDeviceDesc);
///=============================================================================
/// Local defines
///=============================================================================
#define SEND_RECV_TIME_OUT 20 // 20 secs
// Device specific request
#define SET_CONTROL_LINE_STATE 0x22
#define EP0_MAX_MSG_RECV_BUFFER 4 // no message ever recvd on EP0
///=============================================================================
/// Local function prototypes
///=============================================================================
///=============================================================================
/// Static variables
///=============================================================================
///////////////////////////////
// Serial USB Descriptor Set //
///////////////////////////////
static UCHAR m_pucUSBDescriptors[] =
{
/////////////////////////////////////////////
// Standard Device Descriptor (One Device) //
/////////////////////////////////////////////
/* 0 */ 18, // bLength = 18 bytes.
/* 1 */ USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType = DEVICE
/* 2 */ 0x10, 0x01, // bcdUSB = 1.1
/* 4 */ 0xff, // bDeviceClass = Communication Device Class
/* 5 */ 0xff, // bDeviceSubClass = Unused at this time.
/* 6 */ 0xff, // bDeviceProtocol = Unused at this time.
/* 7 */ 0, // bMaxPacketSize0 = EP0 buffer size. retrieved from PDD. 0 by default.
/* 8 */ 0x5E, 0x04, // idVendor = Microsoft Vendor ID.
/* 10 */ 0xCE, 0x00, // idProduct
/* 12 */ 0, 0, // bcdDevice
/* 14 */ 0x01, // iManufacturer = OEM should fill this..
/* 15 */ 0x02, // iProduct = OEM should fill this..
/* 16 */ 0x03, // iSerialNumber = OEM should fill this..
/* 17 */ 0x01, // bNumConfigs = 1
///////////////////////////////////////////////////////////
// Standard Configuration Descriptor (One Configuration) //
///////////////////////////////////////////////////////////
/* 18 */ 9, // bLength
/* 19 */ USB_CONFIGURATION_DESCRIPTOR_TYPE,
/* 20 */ 32, 0, // wTotalLength
/* 22 */ 1, // bNumInterfaces
/* 23 */ 1, // bConfigurationValue
/* 24 */ 0, // iConfiguration
/* 25 */ 0xC0, // bmAttributes = Self-Powered & Bus-Powered
/* 26 */ 0x32, // MaxPower = 100mA
///////////////////////////////////////////////////
// Standard Interface Descriptor (One Interface) //
///////////////////////////////////////////////////
/* 27 */ 9, // bLength
/* 28 */ USB_INTERFACE_DESCRIPTOR_TYPE,
/* 29 */ 0, // bInterfaceNumber
/* 30 */ 0, // bAlternateSetting
/* 31 */ 2, // bNumEndpoints (number endpoints used, excluding EP0)
/* 32 */ 0xff, // bInterfaceClass
/* 33 */ 0xff, // bInterfaceSubClass
/* 34 */ 0xff, // bInterfaceProtocol
/* 35 */ 0, // ilInterface (Index of this interface string desc.)
///////////////////////////////////////////////////
// Standard Endpoint Descriptor (EP1 - BULK OUT) //
///////////////////////////////////////////////////
/* 36 */ 7, // bLength
/* 37 */ USB_ENDPOINT_DESCRIPTOR_TYPE,
/* 38 */ 0x01, // bEndpointAddress (EP 1, OUT)
/* 39 */ 2, // bmAttributes (0010 = Bulk)
/* 40 */ 0, 0, // wMaxPacketSize. retrieved from PDD. 0 by default.
/* 42 */ 0, // bInterval (ignored for Bulk)
//////////////////////////////////////////////////
// Standard Endpoint Descriptor (EP2 - BULK IN) //
//////////////////////////////////////////////////
/* 43 */ 7, // bLength
/* 44 */ USB_ENDPOINT_DESCRIPTOR_TYPE,
/* 45 */ 0x82, // bEndpointAddress (EP 2, IN)
/* 46 */ 2, // bmAttributes (0010 = Bulk)
/* 47 */ 0, 0, // wMaxPacketSize. retrieved from PDD. 0 by default.
/* 49 */ 0 // bInterval (ignored for Bulk)
};
// bookkeeping pointers and defines to m_pucUSBDescriptors
// change the offsets if you change m_pucUSBDescriptors
//
static USB_ENDPOINT_DESCRIPTOR* m_pBulkInEndPtDesc =
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[43];
static USB_ENDPOINT_DESCRIPTOR* m_pBulkOutEndPtDesc =
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[36];
static USB_ENDPOINT_DESCRIPTOR* m_pUsbEndPointDescriptor[] =
{ (USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[36],
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[43]
};
static USBDBG_INTERFACE_DESCRIPTOR m_intrfcDesc1 =
{
(USB_INTERFACE_DESCRIPTOR*) &m_pucUSBDescriptors[27],
(USB_ENDPOINT_DESCRIPTOR**) &m_pUsbEndPointDescriptor[0]
};
static USBDBG_INTERFACE_DESCRIPTOR* m_pIntrfcDesc[] =
{
&m_intrfcDesc1
};
static USBDBG_CONFIG_DESCRIPTOR m_configDesc1 =
{
(USB_CONFIGURATION_DESCRIPTOR *) &m_pucUSBDescriptors[18],
(USBDBG_INTERFACE_DESCRIPTOR**) &m_pIntrfcDesc[0]
};
static USBDBG_CONFIG_DESCRIPTOR* m_configDesc[] =
{
&m_configDesc1
};
static USBDBG_DEVICE_DESCRIPTOR m_deviceDesc =
{
(USB_DEVICE_DESCRIPTOR* ) &m_pucUSBDescriptors,
(USBDBG_CONFIG_DESCRIPTOR**) &m_configDesc[0]
};
#define CONFIGDESC_LEN 32 //len from starting of USB_CONFIGURATION_DESCRIPTOR_TYPE
//to end (50)
#define CONTROL_ENDPT 0
#define BULKOUT_ENDPT 1 //logical bulkout endpoint num
#define BULKIN_ENDPT 2 //logical bulkin endpoint num
#define MAX_ENDPT BULKIN_ENDPT
#define USBSERIALNUM_DEFAULT L"FFFFFFFFFFFF\0"
static USB_STRING m_UsbSerialNum =
{
sizeof(USBSERIALNUM_DEFAULT) + 2,
USB_STRING_DESCRIPTOR_TYPE,
USBSERIALNUM_DEFAULT
};
static const USB_STRING_DESCRIPTOR m_SupportedLang =
{
0x04,
USB_STRING_DESCRIPTOR_TYPE,
0x0409 // US English by default
};
// default manufacturer
static const USB_STRING m_Manufacturer =
{
sizeof(MANUFACTURER) + 2,
USB_STRING_DESCRIPTOR_TYPE,
MANUFACTURER
};
// default product
static const USB_STRING m_Product =
{
sizeof(PRODUCT) + 2,
USB_STRING_DESCRIPTOR_TYPE,
PRODUCT
};
static BOOL m_fConnected = FALSE;
static BYTE m_ep0MsgRxBuffer[EP0_MAX_MSG_RECV_BUFFER];
static BYTE m_MsgParamBuf[64]; // 64 bytes message buffer
// when registering with the USBFN PDD layer, the PDD will fill in this
// structure with appropriate data and function pointers
static USBDBG_PDD_INTERFACE_INFO m_pddIfc;
// contains the MDD version information
static USBDBG_MDD_INTERFACE_INFO m_mddInterface;
typedef struct {
PBYTE pbBuffer;
DWORD cbTransferSize;
DWORD transferFlags;
DWORD status;
DWORD cbTransferred;
DWORD SendRecvNULL;
DWORD cbToTransfer;
} EPTransfer;
static EPTransfer m_epTransfers[MAX_ENDPT+1];
static DWORD m_epMaxPktSize[MAX_ENDPT+1];
static BYTE m_BulkRxPktBuf[RECVBUF_MAXSIZE];
static BOOL m_fSetupCancelled = FALSE;
// transfer status'
#define USBDBG_TRANSFER_STATUS_INPROGRESS 0x00000001
#define USBDBG_TRANSFER_STATUS_COMPLETE 0x00000002
#define USBDBG_TRANSFER_STATUS_ABORTED 0x00000004
#define USBDBG_TRANSFER_STATUS_STARTED 0x00000008
///=============================================================================
/// Private Function Prototypes
///=============================================================================
///=============================================================================
/// Private Functions
///=============================================================================
// start a transmit or receive transfer
static
void
StartTransfer(
DWORD epNum,
DWORD dir,
UINT8 *pData,
UINT32 cbDataLen,
DWORD transferflags
)
{
DWORD transferStatus = 0;
// get transfer struct on epNum
EPTransfer* pTransfer = &m_epTransfers[epNum];;
// if ep0 and transfer is cancelled return
if ((epNum == 0) && m_fSetupCancelled)
return;
// reset transfer struct
pTransfer->pbBuffer = pData;
pTransfer->cbTransferSize = cbDataLen;
pTransfer->transferFlags = transferflags;
pTransfer->status = USBDBG_TRANSFER_STATUS_INPROGRESS;
pTransfer->cbTransferred = 0;
// multiple of max pkt size?
if ((pTransfer->cbTransferSize & (m_epMaxPktSize[epNum]-1)) == 0)
pTransfer->SendRecvNULL = TRUE; // yes, send a NULL packet
else
pTransfer->SendRecvNULL = FALSE; // no
if (dir == ENDPT_DIR_RX)
{
// call PDD to enable RX FIFO
// PDD is expected to only start RX transfer and not return any
// data when USBDBG_MDD_TRANSFER_START flag is passed
pTransfer->cbToTransfer = m_pddIfc.pfnRecvData(
epNum,
pTransfer->pbBuffer,
pTransfer->cbTransferSize,
pTransfer->transferFlags | USBDBG_MDD_TRANSFER_START,
&transferStatus);
// if transfer is aborted, mark it
if (pTransfer->cbToTransfer == -1)
{
pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
goto clean;
}
// mark xfer complete if PDD signalled transfer complete
if (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE)
{
pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
}
// else NOP (transfer continues)
}
else // dir == ENDPT_DIR_TX
{
// send first xfer
pTransfer->cbToTransfer = m_pddIfc.pfnSendData(
epNum,
pTransfer->pbBuffer,
pTransfer->cbTransferSize,
pTransfer->transferFlags | USBDBG_MDD_TRANSFER_START,
&transferStatus);
if (pTransfer->cbToTransfer == -1)
{
pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
goto clean;
}
// mark xfer complete if PDD signalled transfer complete
if (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE)
{
pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
}
}
clean: ;
}
// continue a receive transfer already started on EP0 or IN endpt
static
void
ContinueRxTransfer(
DWORD epNum
)
{
DWORD transferStatus = 0;
EPTransfer* pTransfer = &m_epTransfers[epNum];
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+ContinueRxTransfer.\r\n"));
// quit if transfer has already been aborted
if (pTransfer->status & USBDBG_TRANSFER_STATUS_ABORTED)
goto clean;
// quit with an error message if transfer was never started
if (!(pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS))
{
USBDBGMSG(USBDBG_ZONE_WARN, (
L"WARN!:usbdbg:Rx xfer not in progress on ep=%d\r\n",
epNum));
goto clean;
}
// PDD's responsibility when pfnRecvData is called.
// 1. BULK ENDPT OUT - if buffer is filled up or short packet received,
// disable RX FIFO and set USBDBG_PDD_TRANSFER_COMPLETE
// 2. CONTROL DATA STAGE OUT - if buffer is filled up disable RX FIFO and
// set USBDBG_PDD_TRANSFER_COMPLETE
// 3. CONTROL STATUS STAGE - if buffer (size passed is 0) is filled up
// disable RX FIFO and set USBDBG_PDD_TRANSFER_COMPLETE.
// get data from PDD
pTransfer->cbToTransfer = m_pddIfc.pfnRecvData(
epNum,
pTransfer->pbBuffer + pTransfer->cbTransferred,
pTransfer->cbTransferSize - pTransfer->cbTransferred,
pTransfer->transferFlags,
&transferStatus);
// if transfer is aborted, mark it
if (pTransfer->cbToTransfer == -1)
{
pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
goto clean;
}
// a packet received on epNum
pTransfer->cbTransferred += pTransfer->cbToTransfer;
// mark xfer complete if RX buffer is full or PDD signalled transfer complet
if ((pTransfer->cbTransferred >= pTransfer->cbTransferSize) ||
(transferStatus & USBDBG_PDD_TRANSFER_COMPLETE))
{
pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
}
// else NOP (transfer continues)
clean:
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-ContinueRxTransfer.\r\n"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -