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

📄 usb2com.ark.cpp

📁 这是一个关于USB转接串口的驱动程序开发
💻 CPP
字号:
//********************************************************************
//	created:	12:7:2008   2:37
//	file:		usb2com.ark.cpp
//	author:		tiamo
//	purpose:	usb routine for ark3116
//********************************************************************

#include "stdafx.h"

//
// send vendor request
//
NTSTATUS Usb2ComSendVendorRequest(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in USHORT Index,__in UCHAR Value)
{
	if(Index > 0x10)
		return STATUS_INVALID_PARAMETER;

	PURB Urb											= static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_VENDOR_OR_CLASS_REQUEST),'URB '));
	if(!Urb)
		return STATUS_INSUFFICIENT_RESOURCES;

	UsbBuildVendorRequest(Urb,URB_FUNCTION_VENDOR_DEVICE,sizeof(_URB_CONTROL_VENDOR_OR_CLASS_REQUEST),USBD_TRANSFER_DIRECTION_OUT,0x40,0xfe,Value,Index,0,0,0,0);

	NTSTATUS Status										= Usb2ComSendUrbSync(DevExt,Urb);

	ExFreePool(Urb);
	return Status;
}

//
// recv vendor request
//
NTSTATUS Usb2ComRecvVendorRequest(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in USHORT Index,__out PUCHAR Result)
{
	if(Index > 0x10)
		return STATUS_INVALID_PARAMETER;

	PURB Urb											= static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_VENDOR_OR_CLASS_REQUEST),'URB '));
	if(!Urb)
		return STATUS_INSUFFICIENT_RESOURCES;

	UsbBuildVendorRequest(Urb,URB_FUNCTION_VENDOR_DEVICE,sizeof(_URB_CONTROL_VENDOR_OR_CLASS_REQUEST),USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
						  0xc0,0xfe,0,Index,Result,0,sizeof(UCHAR),0);

	NTSTATUS Status										= Usb2ComSendUrbSync(DevExt,Urb);

	ExFreePool(Urb);
	return Status;
}

//
// set baudrate
//
NTSTATUS Usb2ComSetBaudrate(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ConfigByte									= 0;
	NTSTATUS Status										= STATUS_SUCCESS;

	__try
	{
		Status											= Usb2ComRecvVendorRequest(DevExt,0x03,&ConfigByte);
		if(!NT_SUCCESS(Status))
			try_leave(NOTHING);

		Status											= Usb2ComSendVendorRequest(DevExt,0x03,ConfigByte | 0x80);
		if(!NT_SUCCESS(Status))
			try_leave(NOTHING);

		ULONG ArkBaudrate								= Usb2ComCalcArkBaudrate(DevExt->Baudrate);
		Status											= Usb2ComSendVendorRequest(DevExt,0x00,static_cast<UCHAR>(ArkBaudrate & 0xff));
		if(!NT_SUCCESS(Status))
			try_leave(NOTHING);

		Status											= Usb2ComSendVendorRequest(DevExt,0x01,static_cast<UCHAR>((ArkBaudrate >> 8) & 0xff));
		if(!NT_SUCCESS(Status))
			try_leave(NOTHING);

		Status											= Usb2ComSendVendorRequest(DevExt,0x03,ConfigByte);
	}
	__finally
	{

	}

	return Status;
}

//
// calc ark baudrate
//
ULONG Usb2ComCalcArkBaudrate(__in ULONG Baudrate)
{
	static ULONG BaudrateMap[0x2c] = 
	{
		3000000,    1,
		1500000,    2,
		1000000,    3,
		 500000,    6,
		 230400,   13,
		 115200,   26,
		  57600,   52,
		  38400,   78,
		  28800,  104,
		  19200,  156,
		  14400,  208,
		   9600,  312,
		   7200,  416,
		   4800,  625,
		   3600,  832,
		   2400, 1250,
		   1800, 1664,
		   1200, 2500,
		    600, 5000,
			300,10000,
			150,20000,
			 75,40000,
	};

	for(ULONG i = 0; i < sizeof(BaudrateMap) / sizeof(ULONG); i += 2)
	{
		if(BaudrateMap[i] == Baudrate)
		{
			Baudrate									= BaudrateMap[i + 1];
			break;
		}

		if(i == sizeof(BaudrateMap) / sizeof(ULONG) - 2)
		{
			if(Baudrate > 45 && Baudrate <= 3000000)
			{
				if(3000000 % Baudrate < (Baudrate >> 1))
					Baudrate							= 3000000 / Baudrate;
				else
					Baudrate							= 3000000 / Baudrate + 1;
			}
		}
	}

	return Baudrate;
}

//
// initialize fifo control
//
NTSTATUS Usb2ComInitializeFIFOControl(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	DevExt->SerialFIFOControl							= 8;
	NTSTATUS Status										= Usb2ComSendVendorRequest(DevExt,0x02,8);
	if(!NT_SUCCESS(Status))
		return Status;

	Status												= Usb2ComSendVendorRequest(DevExt,0x01,8);
	if(!NT_SUCCESS(Status))
		return Status;

	Status												= Usb2ComSendVendorRequest(DevExt,0x08,0);
	if(!NT_SUCCESS(Status))
		return Status;

	Status												= Usb2ComSendVendorRequest(DevExt,0x0B,0);
	
	return Status;
}

//
// set line control
//
NTSTATUS Usb2ComSetLineControl(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ConfigByte									= 0;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x03,&ConfigByte);
	if(!NT_SUCCESS(Status))
		return Status;

	switch(DevExt->SerialLineControl.WordLength)
	{
	case 5:
		ConfigByte										&= 0xfc;
		break;

	case 6:
		ConfigByte										&= 0xfd;
		ConfigByte										|= 0x01;
		break;

	case 7:
		ConfigByte										&= 0xfe;
		ConfigByte										|= 0x02;
		break;

	case 8:
		ConfigByte										|= 0x03;
		break;

	default:
		return STATUS_INVALID_PARAMETER;
		break;
	}

	switch(DevExt->SerialLineControl.StopBits)
	{
	case STOP_BIT_1:
		ConfigByte										&= 0xfb;
		break;

	case STOP_BITS_1_5:
		if(DevExt->SerialLineControl.WordLength	 != 5)
			return STATUS_INVALID_PARAMETER;

	case STOP_BITS_2:
		ConfigByte										|= 0x04;
		break;

	default:
		return STATUS_INVALID_PARAMETER;
		break;
	}

	switch(DevExt->SerialLineControl.Parity)
	{
	case NO_PARITY:
		ConfigByte										&= 0xe7;
		break;

	case ODD_PARITY:
		ConfigByte										&= 0xef;
		ConfigByte										|= 0x08;
		break;

	case EVEN_PARITY:
		ConfigByte										|= 0x18;
		break;

	default:
		return STATUS_INVALID_PARAMETER;
		break;
	}

	return Usb2ComSendVendorRequest(DevExt,0x03,ConfigByte);
}

//
// get modem control
//
NTSTATUS Usb2ComGetModemControl(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	return Usb2ComRecvVendorRequest(DevExt,0x04,&DevExt->SerialModemControl);
}

//
// set modem control
//
NTSTATUS Usb2ComSetModemControl(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	return Usb2ComSendVendorRequest(DevExt,0x04,DevExt->SerialModemControl);
}

//
// set FIFO control
//
NTSTATUS Usb2ComSetFIFOControl(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	return Usb2ComSendVendorRequest(DevExt,0x02,DevExt->SerialFIFOControl);
}

//
// set DTR
//
NTSTATUS Usb2ComSetDTR(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ModemControl;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x04,&ModemControl);
	if(!NT_SUCCESS(Status))
		return Status;

	//
	// SERIAL_MCR_DTR ?
	//
	DevExt->SerialModemControl							= ModemControl | 0x01;

	return Usb2ComSendVendorRequest(DevExt,0x04,DevExt->SerialModemControl);
}

//
// clear DTR
//
NTSTATUS Usb2ComClearDTR(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ModemControl;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x04,&ModemControl);
	if(!NT_SUCCESS(Status))
		return Status;

	DevExt->SerialModemControl							= ModemControl & 0xfe;

	return Usb2ComSendVendorRequest(DevExt,0x04,DevExt->SerialModemControl);
}

//
// set RTS
//
NTSTATUS Usb2ComSetRTS(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ModemControl;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x04,&ModemControl);
	if(!NT_SUCCESS(Status))
		return Status;

	//
	// SERIAL_MCR_RTS ?
	//
	DevExt->SerialModemControl							= ModemControl | 0x02;

	return Usb2ComSendVendorRequest(DevExt,0x04,DevExt->SerialModemControl);
}

//
// clear RTS
//
NTSTATUS Usb2ComClearRTS(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ModemControl;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x04,&ModemControl);
	if(!NT_SUCCESS(Status))
		return Status;

	DevExt->SerialModemControl							= ModemControl & 0xfd;

	return Usb2ComSendVendorRequest(DevExt,0x04,DevExt->SerialModemControl);
}

//
// set break on
//
NTSTATUS Usb2ComSetBreakOn(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ConfigByte;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x03,&ConfigByte);
	if(!NT_SUCCESS(Status))
		return Status;

	return Usb2ComSendVendorRequest(DevExt,0x03,ConfigByte | 0x01);
}

//
// set break off
//
NTSTATUS Usb2ComSetBreakOff(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	UCHAR ConfigByte;
	NTSTATUS Status										= Usb2ComRecvVendorRequest(DevExt,0x03,&ConfigByte);
	if(!NT_SUCCESS(Status))
		return Status;

	return Usb2ComSendVendorRequest(DevExt,0x03,ConfigByte & 0xfe);
}

⌨️ 快捷键说明

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