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

📄 usbhid.cpp

📁 CyPress的C8051F32X系列底层驱动(C语言)及上位机demo(vc环境)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************************
FileName		: USBHid.cpp
Author			: Dekimo - Mike Vogeleer
Date Of Creation: 22/09/2003
Purpose			: HID device communication

---------------------------------------
Change History  :

---------------------------------------
******************************************************************************************/

#include "stdafx.h"
#include "USBHid.h"

// ----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------
// Support for different DDK versions.
// ----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------

// Define one of these macros below to select the DDK version:
#define DDK_2000_DDK			// Retired Windows 2000 DDK
//#define DDK_XP_SP1_DDK		// Latest Windows XP SP1, Windows XP, Windows 2000, Windows Millenium Edition.
//#define DDK_SERVER_2003_DDK	// Latest Windows Server 2003, Windows XP SP1, Windows XP, Windows 2000.

// There are many versions of these files dangling around 
// in the Visual Studio, the SDK and various DDK directories.
// All the pathnames will be completely spelled out (instead 
// of using compiler/linker setting), to avoid ambiguity.

#ifdef DDK_2000_DDK
#pragma message ("Using retired Windows 2000 DDK")
// Use the setupapi.lib that comes with the compiler
// (even though the DDK also has a setupapi.lib library)
#pragma comment (lib, "setupapi.lib")
// Use the hid.lib file from the appropriate DDK directory
#pragma comment (lib, "\\winddk\\2600\\lib\\w2k\\i386\\hid.lib")
#endif

#ifdef DDK_XP_SP1_DDK
#pragma message ("Using Windows XP SP1 DDK")
// Use the setupapi.lib file that comes with the compiler
// (even though the DDK also has a setupapi.lib library)
#pragma comment (lib, "setupapi.lib")
// Use the hid.lib file from the appropriate DDK directory
#pragma comment (lib, "\\winddk\\2600\\lib\\wxp\\i386\\hid.lib")
//#pragma comment (lib, "\\winddk\\2600\\lib\\wxp\\i386\\hid.lib")
#endif

#ifdef DDK_SERVER_2003_DDK
#pragma message ("Using Windows Server 2003 DDK")
// Use the setupapi.lib file that comes with the compiler
// (even though the DDK also has a setupapi.lib library)
#pragma comment (lib, "setupapi.lib")
// Use the hid.lib file from the appropriate DDK directory
#pragma comment (lib, "\\winddk\\3790\\lib\\w2k\\i386\\hid.lib")
//#pragma comment (lib, "\\winddk\\3790\\lib\\wxp\\i386\\hid.lib")
#endif
// ----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------

#define PKT_SIZE (8)

static HANDLE hUSBRead;	// Handle to read from USB device
static HANDLE hUSBWrite; // Handle to write to USB device
static USB_CALLBACK_FUNCTION USB_callback_function; // Callback function when data arrives
static const void* extraInfo; // Parameter for callback function (in practice: HWND or CDialog*)
static BYTE buf[1 + PKT_SIZE]; // Receive buffer
static HANDLE hThread=0; // Read thread
static HANDLE hDevNotify=0; // For WindowProc() notifications of USB connect/disconnect.

// Forward declarations of helper functions:
static int hid_open(const CWnd* pNotifyWnd,HANDLE* hDevNotify,
					HANDLE* DeviceHandleRead,HANDLE* DeviceHandleWrite,
					unsigned VendorID,unsigned ProductID,unsigned* versionnr=0,
					unsigned* usage=0,unsigned *usagepage=0,
					unsigned* inputreportlength=0,unsigned* outputreportlength=0,
					unsigned* featurereportlength=0);
static int UsbHidStep(void);

static OVERLAPPED overlapped; // Must do overlapped IO (if we don't, a blocking ReadFile in one thread will cause a deadlock on CloseHandle() in the other thread)
static HANDLE hEventObject;
static volatile BYTE ThreadMayContinue;
static HANDLE hThreadDone;

static DWORD WINAPI InterruptThreadProc(LPVOID lpParameter) {

	// Setup the EventObject and the overlapped structure for overlapped, asynchronous IO.
	hEventObject = CreateEvent(NULL,0,0,"");
	hThreadDone = CreateEvent(NULL,0,0,"");

	overlapped.hEvent = hEventObject;
	overlapped.Offset = 0;
	overlapped.OffsetHigh = 0;

	// Maintain bookkeeping info to handle thread termination
	ThreadMayContinue=1;

	while(ThreadMayContinue) {
		if(UsbHidStep()) 
			break;
	}

	::CloseHandle(hEventObject);

	if(hThreadDone) SetEvent(hThreadDone);

	return 1;
}

static int UsbHidStep(void) { // Drives RX state machine
	DWORD ulBytesSucceed=0,ulBytesRequest=PKT_SIZE/*+4*/;

	// Non-blocking, asynchronous, overlapped ReadFile(). This function returns immediately
	ReadFile(hUSBRead,(unsigned char*)buf, ulBytesRequest=PKT_SIZE+1/*+4*/, &ulBytesSucceed, &overlapped);
	// If data arrives, hEventObject will be signalled and the data will be in buf[]. 
	// If data does not arrive, WaitForSingleObject() returns after 100ms. This allows to
	// terminate the thread when ThreadMayContinue becomes false.
	switch (WaitForSingleObject(hEventObject,100)) {
	case WAIT_OBJECT_0:	{ // Data arrived
		if(!GetOverlappedResult(hUSBRead,&overlapped,&ulBytesSucceed,0)) { // Get number of received bytes
			USB_callback_function(0,extraInfo);
			break; // Device was disconnected!
		}
			
		if(ulBytesSucceed==ulBytesRequest) {
			if(ThreadMayContinue)
				USB_callback_function(buf,extraInfo);
		} else {
			return 1;
		}
		break;
		}
	case WAIT_TIMEOUT: { // If nothing arrived during those 100msec, cancel our IO request
		CancelIo(hUSBRead);
		break;
	default:
		break;
		}
	}

	return 0;
	
}

unsigned char UsbHidOpen(USB_CALLBACK_FUNCTION usb_callback_function,const CWnd* p) {

	unsigned version,usage,usagepage,ilen,olen;
	if(hid_open(p,&hDevNotify,&hUSBRead,&hUSBWrite,0x10C4,0x0001,&version,&usage,&usagepage,&ilen,&olen)) {
		DWORD id;
		USB_callback_function=usb_callback_function;
		extraInfo=(const void*)p;
		hThread=0;
		hThread=CreateThread(0,4096,InterruptThreadProc,0/*lpParameter*/,0,&id);
	
		return 0;
	}
	return 3;
}

DWORD UsbHidWrite(BYTE* buf) { // Write to device
	buf[0]=0; // First byte is report number (should be 0)
	DWORD ulBytesSucceed=0,ulBytesRequest=PKT_SIZE+1;

	WriteFile(hUSBWrite, buf , ulBytesRequest, &ulBytesSucceed, NULL);

	if(ulBytesSucceed != ulBytesRequest) {
		return 1;
	}
	return 0;
}

void UsbHidClose(void) {

	// Notify the thread that it should finished asap.
	ThreadMayContinue=0;

	// Tell windows we are not interested in device notification messages any more
	if(IsWin2KorXP()) {
		if(hDevNotify) UnregisterDeviceNotification(hDevNotify);
		hDevNotify=0;
	}
		
	if(hThread) { 
		if(WAIT_OBJECT_0==WaitForSingleObject(hThreadDone,100)) {
			::CloseHandle(hThread); // If the thread is not finished, CloseHandle() would block indefinitely
		}
		::CloseHandle(hThreadDone);hThreadDone=0;
	}
	hThread=0;

	if ( hUSBRead != NULL ) {
		::CloseHandle(hUSBRead);
		hUSBRead = NULL;
	}

	if ( hUSBWrite != NULL ) {
		::CloseHandle(hUSBWrite);
		hUSBWrite = NULL;
	}
}

BOOL IsWin2KorXP(void) {
	OSVERSIONINFO VersionInfo;
	VersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
	GetVersionEx(&VersionInfo);
	return (VersionInfo.dwMajorVersion==5);
}

// ------------------------------------------------------------------------------------
// ----------------------- Helper functions (very HID specific) ----------------------- 
// ------------------------------------------------------------------------------------

// There are many versions of these files dangling around 
// in the Visual Studio, the SDK and various DDK directories.
// All the pathnames will be completely spelled out (instead 
// of using compiler/linker setting), to avoid ambiguity.

#ifdef DDK_2000_DDK
#include "/winddk/2600/inc/w2k/initguid.h"

#define MAX_LOADSTRING 256

extern "C" {
//#include "/ntddk/inc/hidsdi.h"
//}
//#include "/ntddk/inc/setupapi.h"


#include "/winddk/2600/inc/w2k/hidsdi.h"
//#include "/winddk/2600/inc/ddk/wdm/w2k/hidsdi.h"
//#include "/winddk/2600/inc/wxp/hidsdi.h"
//#include "/winddk/2600/inc/ddk/wdm/wxp/hidsdi.h"
}
#include "/winddk/2600/inc/w2k/setupapi.h"




#include <dbt.h>
#endif

#ifdef DDK_XP_SP1_DDK
#include "/winddk/2600/inc/w2k/initguid.h"

#define MAX_LOADSTRING 256

extern "C" {
#include "/winddk/2600/inc/w2k/hidsdi.h"
//#include "/winddk/2600/inc/ddk/wdm/w2k/hidsdi.h"
//#include "/winddk/2600/inc/wxp/hidsdi.h"
//#include "/winddk/2600/inc/ddk/wdm/wxp/hidsdi.h"
}

⌨️ 快捷键说明

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