2008년 1월 17일 목요일

Delphi Interface for Cypress FX2 CY7C68013

//
// Delphi Interface for Cypress FX2 CY7C68013
//
//
// 1. Why ?
// CyAPI.lib [Cypress USB DevStudio] for BC6,VC6_7
// No Dll. Directory Control needed for Delphi
//
//
// 2. ID VID : 0x0547
// PID : 0x1002
// Product : EZ-USB FX2 GPIF to Ext FIFO Example using FIFO Transactions
// TGUID '{AE18AA60-7F6A-11d4-97DD-00010229B959}'
//
// 3. EndPoint
// PIPE00 : Control End Point [Max Pkt Size 64]
// PIPE02 : Bulk Out [Max Pkt Size 512]
// PIPE86 : Bulk In [Max Pkt Size 512]
//
// 4. History
// First Date : 2007.10.26
// Last Modified : 2008.01.17
//
// 5. Version
// 0.1 : 2008.01.17
//
//
// 6. Bugs
//
//
// 7. Writer Simon,choi (simon@kredix.com)
// e-mail : simon@kredix.com
// simon@maxpaper.com
// simonsayz@naver.com
// blog : http://blog.naver.com/simonsayz
// http://s193382.blogspot.com/
//
//
unit UsbLibrary;

interface

Uses
Windows,Types,Classes,SysUtils,StdCtrls;

Const
cSetupAPI_dll = 'setupapi.dll';
cGUID_CLASS_CYUSBDRV : TGUID = '{AE18AA60-7F6A-11d4-97DD-00010229B959}';
//
Cmd_Usb_Reset = $B2;
Cmd_Usb_Ready = $B5;
//

Type
HDevInfo = Pointer;
ULONG_PTR = DWORD;
//
PSPDeviceInterfaceData = ^SP_DEVICE_INTERFACE_DATA;
SP_DEVICE_INTERFACE_DATA = packed record
cbSize : DWORD;
InterfaceClassGuid : TGUID;
Flags : DWORD;
Reserved : ULONG_PTR;
end;
PSPDeviceInterfaceDetailDataA = ^SP_DEVICE_INTERFACE_DETAIL_DATA_A;
SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record
cbSize: DWORD;
DevicePath: array [0..0] of AnsiChar;
end;
PSPDevInfoData = ^SP_DEVINFO_DATA;
SP_DEVINFO_DATA = packed record
cbSize: DWORD;
ClassGuid: TGUID;
DevInst: DWORD; // DEVINST handle
Reserved: ULONG_PTR;
end;
Var
memo_Rcv : TMemo; //

//
Function _USB_Init : Boolean;
Function _USB_Device (DeviceList : TStrings) : Integer;
Function _USB_Open (sDeviceName : String ) : Boolean;
Function _USB_Close : Boolean;
//
Function _USB_Cmd (USBCmd : Byte;
Var USBRcv : Word) : Boolean;
Function _USB_Write (pBuffer : Pointer;
ulBufferSize : DWord;
Var pByteWritten : DWord) : Boolean;
Function _USB_Read (pBuffer : Pointer;
ulBufferSize : DWord;
Var ulByteRead : DWord) : Boolean;

Implementation

Const
DIGCF_PRESENT = $00000002;
DIGCF_DEVICEINTERFACE = $00000010;

FILE_SHARE_READ = $1;
FILE_SHARE_WRITE = $2;
OPEN_EXISTING = 3;

FILE_DEVICE_UNKNOWN = $22;

METHOD_BUFFERED = 0;
METHOD_IN_DIRECT = 1;
METHOD_OUT_DIRECT = 2;
METHOD_NEITHER = 3;

FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
FILE_WRITE_ACCESS = 2;

Func_Vendor_Request = 8; // EZ FX2
Cmd_Buf_Max = 40;

Var
// Handle
cSetupAPI_Handle : THandle;
m_hPipeCtrl : THandle; // PIPE00
m_hPipeBulkIn : THandle; // PIPE02
m_hPipeBulkOut : THandle; // PIPE86
//
IOCTL_Vendor_Request : DWord;
Cmd_Buf : Packed Array[0..Cmd_Buf_Max-1] of Byte;

//------------------------------------------------------------------------------
//
// USB Device Enumernation & Find
//
// 1. Function _USB_Init : Boolean;
// 2. GetDeviceName
// 3. Function _USB_Device(DeviceList : TStrings) : Integer;
//
//------------------------------------------------------------------------------


Var
SetupDiGetDeviceInterfaceDetail : Function
(DeviceInfoSet : HDEVINFO;
DeviceInterfaceData : PSPDeviceInterfaceData;
DeviceInterfaceDetailData : PSPDeviceInterfaceDetailDataA;
DeviceInterfaceDetailDataSize: DWORD; RequiredSize: PDWORD;
Device : PSPDevInfoData): LongBool; stdcall;

SetupDiGetClassDevs : Function
(ClassGuid : PGUID; const Enumerator: PChar;
hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;
SetupDiEnumDeviceInterfaces : Function
(DeviceInfoSet: HDEVINFO;
DeviceInfoData: PSPDevInfoData; var InterfaceClassGuid: TGUID;
MemberIndex: DWORD;
var DeviceInterfaceData: SP_DEVICE_INTERFACE_DATA): LongBool; stdcall;
SetupDiDestroyDeviceInfoList : Function
(DeviceInfoSet: HDEVINFO): LongBool; stdcall;

//
Function _USB_Init : Boolean;
begin
cSetupAPI_Handle := LoadLibrary(cSetupAPI_dll);
If cSetupAPI_Handle <> 0 then
begin
@SetupDiGetDeviceInterfaceDetail := GetProcAddress(cSetupAPI_Handle,
'SetupDiGetDeviceInterfaceDetailA');
@SetupDiGetClassDevs := GetProcAddress(cSetupAPI_Handle,
'SetupDiGetClassDevsA');
@SetupDiEnumDeviceInterfaces := GetProcAddress(cSetupAPI_Handle,
'SetupDiEnumDeviceInterfaces');
@SetupDiDestroyDeviceInfoList := GetProcAddress(cSetupAPI_Handle,
'SetupDiDestroyDeviceInfoList');
end;
//
m_hPipeCtrl := Invalid_Handle_Value;
m_hPipeBulkIn := Invalid_Handle_Value;
m_hPipeBulkOut := Invalid_Handle_Value;
//
_USB_Init := (cSetupAPI_Handle <> 0);
end;

Function GetDeviceName( HardwareDeviceInfo : HDevInfo;
DeviceInfoData : PSPDeviceInterfaceData;
DevName : TStrings) : Boolean;
Var
FunctionClassDeviceData : PSPDeviceInterfaceDetailDataA;
predictedLength : DWord;
requiredLength : DWord;
hOut : THandle;
begin
//
functionClassDeviceData := nil;
predictedLength := 0;
requiredLength := 0;
hOut := Invalid_Handle_Value;
//
SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
DeviceInfoData,
nil, // probing so no output buffer yet
0, // probing so output buffer length of zero
@requiredLength,
nil); // not interested in the specific dev-node

predictedLength := requiredLength;

GetMem(functionClassDeviceData,predictedLength);
functionClassDeviceData.cbSize := Sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

// Retrieve the information from Plug and Play.
if (Not SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
DeviceInfoData,
functionClassDeviceData,
predictedLength,
@requiredLength,
nil)) then
begin
FreeMem(functionClassDeviceData);
GetDeviceName := False;
Exit;
end;

//
DevName.Add( StrPas (functionClassDeviceData.DevicePath) );

FreeMem(functionClassDeviceData);
GetDeviceName := True;
end;

Function _USB_Device(DeviceList : TStrings) : Integer;
Var
NumberDevices : DWord;
HardwareDeviceInfo : HDevInfo;
DeviceInfoData : SP_Device_Interface_Data;
GUID_Var : TGUID;
DeviceEnd : Boolean;
DeviceCnt : Integer;
begin
//
hardwareDeviceInfo := SetupDiGetClassDevs(@cGUID_CLASS_CYUSBDRV,
nil,
0,
DIGCF_DEVICEINTERFACE or DIGCF_PRESENT);
NumberDevices := 0;
DeviceInfoData.cbSize := SizeOf(SP_DEVICE_INTERFACE_DATA);
GUID_Var := cGUID_CLASS_CYUSBDRV;

DeviceEnd := False;
DeviceCnt := 0;
Repeat
Inc(DeviceCnt);
If (SetupDiEnumDeviceInterfaces(HardwareDeviceInfo,
nil,
GUID_Var,
NumberDevices,
DeviceInfoData)) then
GetDeviceName(hardwareDeviceInfo,
@deviceInfoData,
DeviceList)
else
DeviceEnd := True;
Until (ERROR_NO_MORE_ITEMS <> GetLastError ) or ( DeviceCnt < m_hpipectrl =" Invalid_Handle_Value)" m_hpipebulkout =" Invalid_Handle_Value)" m_hpipebulkin =" Invalid_Handle_Value)"> Invalid_Handle_Value then CloseHandle(m_hPipeCtrl );
If m_hPipeBulkOut <> Invalid_Handle_Value then CloseHandle(m_hPipeBulkOut);
If m_hPipeBulkIn <> Invalid_Handle_Value then CloseHandle(m_hPipeBulkIn );
//
Exit;
end;
//
_USB_Open := True;
end;

//
Function _USB_Close : Boolean;
begin
If m_hPipeCtrl <> Invalid_Handle_Value then CloseHandle(m_hPipeCtrl );
If m_hPipeBulkIn <> Invalid_Handle_Value then CloseHandle(m_hPipeBulkIn );
If m_hPipeBulkOut <> Invalid_Handle_Value then CloseHandle(m_hPipeBulkOut );
//
m_hPipeCtrl := Invalid_Handle_Value;
m_hPipeBulkIn := Invalid_Handle_Value;
m_hPipeBulkOut := Invalid_Handle_Value;
//
_USB_Close := True;
end;


//------------------------------------------------------------------------------
//
// USB Device Function
//
// 1. Function _USB_Cmd (USBCmd : Byte; Var USBRcv : Word) : Boolean;
// 2. Function _USB_Write (pBuffer : Pointer;
// ulBufferSize : DWord;
// Var pByteWritten : DWord) : Boolean;
// 3. Function _USB_Write (pBuffer : Pointer;
// ulBufferSize : DWord;
// Var pByteWritten : DWord) : Boolean;
//
//------------------------------------------------------------------------------

Type
// C0 B2 03 0D 00 00 02 00
// ^ Request Type 1100:000
// ^ Direction : Device To Host
// ^ Type : Vendor
// ^ Recipient : Device
// ^ Request B2 [Value]
// ^ Value 030D
// ^ Index 0000
// ^ Length 0200
TCtl_Request = Record
Target : Byte; // 0x00 TGT_Device
ReqType : Byte; // 0x02 Req_Vendor
Direction : Byte; // 0x01 DIR_From_Device
ReqCode : Byte; // 0xB2 [Value]
Value : Word; // 0x0D03
Index : Word; // 0
End;

//
Function _USB_Cmd (USBCmd : Byte; Var USBRcv : Word) : Boolean;
Var
Inx : Integer;
Rst : Boolean;
nByte : DWord;
begin
FillChar(Cmd_Buf,SizeOf(Cmd_Buf),#0);
Inx := 0;
Cmd_Buf[Inx] := $C0; Inc(Inx);
Cmd_Buf[Inx] := USBCmd; Inc(Inx);
Cmd_Buf[Inx] := $00; Inc(Inx);
Cmd_Buf[Inx] := $0D; Inc(Inx);
Cmd_Buf[Inx] := $00; Inc(Inx);
Cmd_Buf[Inx] := $00; Inc(Inx);
Cmd_Buf[Inx] := $02; Inc(Inx);
Cmd_Buf[Inx] := $00; Inc(Inx);
//
rst := DeviceIOControl(m_hPipeCtrl,
IOCTL_Vendor_Request,
@Cmd_Buf, // Send Buf
Cmd_Buf_Max, // Send Buf Size
@Cmd_Buf, // Recv Buf
Cmd_Buf_Max, // Recv Buf Size
nByte, // Recv Bytes
nil);
Move(Cmd_Buf,USBRcv,2);
Result := Rst;
end;

//
Function _USB_Write(pBuffer : Pointer;
ulBufferSize : DWord;
Var pByteWritten : DWord) : Boolean;
begin
If m_hPipeBulkOut = Invalid_Handle_Value then
begin
_USB_Write := False;
Exit;
end;
//
If Not(Windows.WriteFile(m_hPipeBulkOut,pBuffer^,ulBufferSize,pByteWritten,nil)) then
begin
_USB_Write := False;
Exit;
end;
//
_USB_Write := True;
end;

//
Function _USB_Read (pBuffer : Pointer;
ulBufferSize : DWord;
Var ulByteRead : DWord) : Boolean;
Var
Tmp : Array[0..1024] of Byte;
TmpStr : String;
TmpLp : Integer;
begin
If m_hPipeBulkIn = Invalid_Handle_Value then
begin
_USB_Read := False;
Exit;
end;
//
If Not(Windows.ReadFile(m_hPipeBulkIn,pBuffer^,ulBufferSize,ulByteRead,nil)) then
begin
_USB_Read := False;
Exit;
end;
//
_USB_Read := (ulByteRead <> 0);
end;

Initialization
IOCTL_Vendor_Request := CTL_Code(FILE_DEVICE_UNKNOWN,
Func_Vendor_Request,
Method_Buffered,
File_Any_Access);
end.

댓글 없음: