If you succeed to modify this code to be event driven, please post the source (and some example) to this forum!
Also any other suggestions to improve the code are welcome.
Here is the source code of the original DLL.
K8061D.DPR
[code]library K8061;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library’s USES clause AND your project’s (select
View-Project Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL–even those that
are nested in records and classes. ShareMem is the interface unit to
the DELPHIMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using DELPHIMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes,
K8061D in ‘K8061D.pas’;
exports
OpenDevice,
CloseDevices,
ReadAnalogChannel,
ReadAllAnalog,
OutputAnalogChannel,
OutputAllAnalog,
ClearAnalogChannel,
ClearAllAnalog,
SetAnalogChannel,
SetAllAnalog,
OutputAllDigital,
ClearDigitalChannel,
ClearAllDigital,
SetDigitalChannel,
SetAllDigital,
ReadDigitalChannel,
OutputPWM,
ReadAllDigital,
ReadCounters,
ReadVersion,
ResetCounters,
PowerGood,
Connected,
ReadBackDigitalOut,
ReadBackAnalogOut,
ReadBackPWMOut;
end.[/code]
K8061D.PAS
[code]unit K8061D;
interface
uses
Windows, SysUtils;
function OpenDevice: Longint ; stdcall;
procedure CloseDevices; stdcall;
function ReadAnalogChannel(CardNumber: Longint; Channel: Longint):Longint; stdcall;
procedure ReadAllAnalog(CardNumber: Longint; Buffer: Pointer); stdcall;
procedure OutputAnalogChannel(CardNumber: Longint; Channel: Longint; Data: Longint); stdcall;
procedure OutputAllAnalog(CardNumber: Longint; Buffer: Pointer); stdcall;
procedure ClearAnalogChannel(CardNumber: Longint; Channel: Longint); stdcall;
procedure ClearAllAnalog(CardNumber: Longint); stdcall;
procedure SetAnalogChannel(CardNumber: Longint; Channel: Longint); stdcall;
procedure SetAllAnalog(CardNumber: Longint); stdcall;
procedure OutputAllDigital(CardNumber: Longint; Data: Longint); stdcall;
procedure ClearDigitalChannel(CardNumber: Longint; Channel: Longint); stdcall;
procedure ClearAllDigital(CardNumber: Longint); stdcall;
procedure SetDigitalChannel(CardNumber: Longint; Channel: Longint); stdcall;
procedure SetAllDigital(CardNumber: Longint); stdcall;
function ReadDigitalChannel(CardNumber: Longint; Channel: Longint): Boolean; stdcall;
function ReadAllDigital(CardNumber: Longint): Longint; stdcall;
procedure OutputPWM(CardNumber: Longint; Data: Longint); stdcall;
procedure ReadCounters(CardNumber: Longint; Buffer: Pointer); stdcall;
procedure ResetCounters(CardNumber: Longint); stdcall;
procedure ReadVersion(CardNumber: Longint; Buffer: Pointer); stdcall;
procedure CheckInvalidHandle(CardNumber: Longint);
procedure OutIn(CardNumber:Longint; Tx:DWORD; Rx:DWORD);
function PowerGood(CardNumber: Longint): Boolean; stdcall;
function Connected(CardNumber: Longint): Boolean; stdcall;
function ReadBackDigitalOut(CardNumber: Longint):Longint; stdcall;
procedure ReadBackAnalogOut(CardNumber: Longint; Buffer: Pointer); stdcall;
function ReadBackPWMOut(CardNumber: Longint):Longint; stdcall;
implementation
var
OutPipe: array[0…7] of THandle;
InPipe: array[0…7] of THandle;
open: array[0…7] of boolean;
send_buf:array[0…50] of byte;
receive_buf:array[0…50] of byte;
i:integer;
instance:DWORD;
//function _MPUSBGetDLLVersion:Dword; cdecl; external ‘mpusbapi.dll’;
function _MPUSBGetDeviceCount(pVID_PID:PCHAR):Dword; cdecl; external ‘mpusbapi.dll’
function _MPUSBOpen(instance:DWORD; pVID_PID:PCHAR; pEP:PCHAR; dwDir:DWORD; dwReserved:DWORD):THandle; cdecl; external ‘mpusbapi.dll’;
function _MPUSBWrite(handle:THandle; pData:Pointer; dwLen:DWORD; pLength:Pointer; dwMilliseconds:DWORD):DWord; cdecl; external ‘mpusbapi.dll’;
function _MPUSBRead(handle:THandle; pData:Pointer; dwLen:DWORD; pLength:Pointer; dwMilliseconds:DWORD):DWord; cdecl; external ‘mpusbapi.dll’;
function _MPUSBClose(handle:THANDLE):DWORD; cdecl;external ‘mpusbapi.dll’;
procedure CheckInvalidHandle(CardNumber: Longint);
begin
if(GetLastError=ERROR_INVALID_HANDLE) then
begin
// Most likely cause of the error is the board was disconnected.
_MPUSBClose(OutPipe[CardNumber]);
_MPUSBClose(InPipe[CardNumber]);
InPipe[CardNumber]:=INVALID_HANDLE_VALUE;
OutPipe[CardNumber]:=INVALID_HANDLE_VALUE;
open[CardNumber]:=false;
end;
//else
//ShowMessage(‘Error Code :’+inttostr(GetLastError()));
end;
function OpenDevice: Longint; stdcall;
var OutPipe_tmp,InPipe_tmp:THandle;
SentDataLength,ReceiveLength:DWORD ;
tmp,i:byte;
begin
//MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
if (_MPUSBGetDeviceCount(pchar(‘vid_10cf&pid_8061’)))=0 then
begin
result:=-2;
exit
end;
OutPipe_tmp:=_MPUSBOpen(instance,pchar(‘vid_10cf&pid_8061’),pchar(’\MCHP_EP1’),0,0);
InPipe_tmp:=_MPUSBOpen(instance,pchar(‘vid_10cf&pid_8061’),pchar(’\MCHP_EP1’),1,0);
if (OutPipe_tmp<>INVALID_HANDLE_VALUE) and (InPipe_tmp<>INVALID_HANDLE_VALUE) then
begin
send_buf[0] := 12; //JUMPERS
_MPUSBWrite(OutPipe_tmp,@send_buf,1,@SentDataLength,1000);
_MPUSBRead(InPipe_tmp,@receive_buf,2,@ReceiveLength,1000);
tmp:=receive_buf[1];
open[tmp]:=true;
OutPipe[tmp]:=OutPipe_tmp;
InPipe[tmp]:=InPipe_tmp;
inc(instance);
result:=tmp;
end
else
begin
result:=-1;
end;
end;
procedure CloseDevices; stdcall;
var i:integer;
begin
for i:=0 to 7 do
begin
if open[i] then _MPUSBClose(OutPipe[i]);
if open[i] then _MPUSBClose(InPipe[i]);
open[i]:=false;
InPipe[i]:=INVALID_HANDLE_VALUE;
OutPipe[i]:=INVALID_HANDLE_VALUE;
end;
end;
function ReadAnalogChannel(CardNumber: Longint; Channel: Longint):Longint; stdcall;
begin
send_buf[0] := 0; //READ_ANALOG_CH
if Channel>8 then Channel:=8;
if Channel<1 then Channel:=1;
send_buf[1] := byte(Channel-1);
OutIn(CardNumber,2,4);
result:=receive_buf[2]+256*receive_buf[3];
end;
procedure ReadAllAnalog(CardNumber: Longint; Buffer: Pointer ); stdcall;
var p:^longint;
i,n:integer;
begin
p:=Buffer;
send_buf[0] := 1; // READ_ALL_ANALOG
OutIn(CardNumber,1,17);
for i:= 0 to 7 do
begin
n:=receive_buf[i*2+1]+256*receive_buf[i*2+2];
p^:=n;
inc§;
end;
end;
procedure OutputAnalogChannel(CardNumber: Longint; Channel: Longint; Data: Longint); stdcall;
begin
send_buf[0] := 2; // OUT_ANALOG_CH
if Channel>8 then Channel:=8;
if Channel<1 then Channel:=1;
send_buf[1] := Channel-1; // ch
send_buf[2] := Data; // data
OutIn(CardNumber,3,4);
end;
procedure OutputAllAnalog(CardNumber: Longint; Buffer: Pointer); stdcall;
var i:integer;
p:^longint;
begin
p:=Buffer;
send_buf[0] := 3; // OUT_ALL_ANALOG
for i:=1 to 8 do
begin
send_buf[i] := p^;
inc§;
end;
OutIn(CardNumber,9,2);
end;
procedure ClearAnalogChannel(CardNumber: Longint; Channel: Longint); stdcall;
begin
send_buf[0] := 2; // OUT_ANALOG_CH
send_buf[1] := Channel-1; // ch
send_buf[2] := 0; // data
OutIn(CardNumber,3,4);
end;
procedure ClearAllAnalog(CardNumber: Longint); stdcall;
var i:integer;
begin
send_buf[0] := 3; // OUT_ALL_ANALOG
for i:=1 to 8 do
begin
send_buf[i] := 0;
end;
OutIn(CardNumber,9,2);
end;
procedure SetAnalogChannel(CardNumber: Longint; Channel: Longint); stdcall;
begin
send_buf[0] := 2; // OUT_ANALOG_CH
send_buf[1] := Channel-1; // ch
send_buf[2] := 255; // data
OutIn(CardNumber,3,4);
end;
procedure SetAllAnalog(CardNumber: Longint); stdcall;
var i:integer;
begin
send_buf[0] := 3; // OUT_ALL_ANALOG
for i:=1 to 8 do
begin
send_buf[i] := 255;
end;
OutIn(CardNumber,9,2);
end;
procedure OutputPWM(CardNumber: Longint; Data: Longint); stdcall;
var k:DWORD ;
hi,lo:byte;
i:integer;
begin
k:=Data;
asm
mov eax,k
and al,03h
mov lo,al
mov eax,k
shr eax,2
mov hi,al
end;
send_buf[0] := 4; //OUT_PWM
send_buf[1] := lo;
send_buf[2] := hi;
OutIn(CardNumber,3,4);
end;
function ReadAllDigital(CardNumber: Longint): Longint; stdcall;
var i:integer;
begin
send_buf[0] := 5; //READ_DIGITAL_BYTE
OutIn(CardNumber,1,2);
result:=receive_buf[1];
end;
procedure OutputAllDigital(CardNumber: Longint; Data: Longint); stdcall;
begin
send_buf[0] := 6; //OUT_DIGITAL_BYTE
send_buf[1] := Data;
OutIn(CardNumber,2,3);
end;
function ReadDigitalChannel(CardNumber: Longint; Channel: Longint): Boolean; stdcall;
var b:byte;
begin
send_buf[0] := 5; //READ_DIGITAL_BYTE
OutIn(CardNumber,1,2);
b:=1;
b:=b shl (Channel-1);
result:=((receive_buf[1] and b)>0);
end;
procedure ClearDigitalChannel(CardNumber: Longint; Channel: Longint); stdcall;
var k:longint;
begin
k:=255-round(Exp((Channel-1)*ln(2)));
send_buf[0] := 7; // Clear Digital Channel
send_buf[1] := k;
OutIn(CardNumber,2,3);
end;
procedure ClearAllDigital(CardNumber: Longint); stdcall;
begin
send_buf[0] := 6; //OUT_DIGITAL_BYTE
send_buf[1] := 0;
OutIn(CardNumber,2,3);
end;
procedure SetDigitalChannel(CardNumber: Longint; Channel: Longint); stdcall;
var k:longint;
begin
k:=round(Exp((Channel-1)*ln(2)));
send_buf[0] := 8; // Set Digital Channel
send_buf[1] := k;
OutIn(CardNumber,2,3);
end;
procedure SetAllDigital(CardNumber: Longint); stdcall;
begin
send_buf[0] := 6; //OUT_DIGITAL_BYTE
send_buf[1] := 255;
OutIn(CardNumber,2,3);
end;
procedure ReadCounters(CardNumber: Longint; Buffer: Pointer ); stdcall;
var p:^longint;
i,n:integer;
begin
p:=Buffer;
send_buf[0] := 9; // READ_ERRORS
OutIn(CardNumber,1,5);
for i:= 0 to 1 do
begin
n:=receive_buf[i*2+1]+256*receive_buf[i*2+2];
p^:=n;
inc§;
end;
end;
procedure ResetCounters(CardNumber: Longint); stdcall;
begin
send_buf[0] := 10; // READ_ERRORS
OutIn(CardNumber,1,2);
end;
function PowerGood(CardNumber: Longint): boolean; stdcall;
begin
send_buf[0] := 13; // POWER_STATUS
OutIn(CardNumber,1,2);
result:=boolean(receive_buf[1]);
end;
function Connected(CardNumber: Longint): boolean; stdcall;
begin
result:=open[CardNumber];
end;
procedure ReadVersion(CardNumber: Longint; Buffer: Pointer ); stdcall;
var
p:^longint;
i,n:integer;
b:byte;
begin
p:=Buffer;
send_buf[0] := 11; // READ_VERSION
OutIn(CardNumber,1,49);
for i:= 1 to 24 do
begin
b:=receive_buf[i];
p^:=b;
inc§;
end;
p^:=ord(’ ‘);
inc§;
p^:=ord(’ ');
inc§;
for i:= 25 to 48 do
begin
b:=receive_buf[i];
p^:=b;
inc§;
end;
end;
procedure OutIn(CardNumber:Longint; Tx:DWORD; Rx:DWORD);
var SentDataLength,ReceiveLength:DWORD ;
h:DWORD ;
begin
if open[CardNumber] then h:=_MPUSBWrite(OutPipe[CardNumber],@send_buf,Tx,@SentDataLength,1000);
if h=0 then CheckInvalidHandle(CardNumber);
if open[CardNumber] then h:=_MPUSBRead(InPipe[CardNumber],@receive_buf,Rx,@ReceiveLength,1000);
if h=0 then CheckInvalidHandle(CardNumber);
end;
function ReadBackDigitalOut(CardNumber: Longint): Longint; stdcall;
var i:integer;
begin
send_buf[0] := 14; //READ_DIGITAL_OUT
OutIn(CardNumber,1,2);
result:=receive_buf[1];
end;
procedure ReadBackAnalogOut(CardNumber: Longint; Buffer: Pointer ); stdcall;
var p:^longint;
i,n:integer;
begin
p:=Buffer;
send_buf[0] := 15; // READ_ANALOG_OUT
OutIn(CardNumber,1,9);
for i:= 1 to 8 do
begin
n:=receive_buf[i];
p^:=n;
inc§;
end;
end;
function ReadBackPWMOut(CardNumber: Longint):Longint; stdcall;
begin
send_buf[0] := 16; // READ_PWM_OUT
OutIn(CardNumber,1,3);
result:=receive_buf[1]+4*receive_buf[2];
end;
initialization
for i:=0 to 7 do open[i]:=false;
instance:=0;
end.[/code]