📄 usb2com.ark.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 + -