?? avr309.dpr
字號:
Exit;
end;
Result:=DEVICE_NOT_PRESENT;
OutLength:=1;
if SendToDriver(FNCNumberDoSetRS232Baud,Lo(BaudRateByte),Hi(BaudRateByte),OutputData,OutLength) then
Result:=NO_ERROR;
SetEvent(SerializationEvent);
end;
//-------------------------------------------------------------------------------------------------------
function DoGetRS232Baud(var BaudRate:integer):integer; stdcall export;
//;get baud speed of serial line (exact value)
begin
if WaitForSingleObject(SerializationEvent,SerializationEventTimeout)=WAIT_TIMEOUT then
begin
ShowThreadErrorMessage;
Result:=DEVICE_NOT_PRESENT;
Exit;
end;
Result:=DEVICE_NOT_PRESENT;
OutLength:=2;
if not SendToDriver(FNCNumberDoGetRS232Baud,0,0,OutputData,OutLength) then
begin
SetEvent(SerializationEvent);
Exit;
end;
UARTx2Mode:=OutLength>1;
if not UARTx2Mode then OutputData[1]:=0; // ATmega returns 2 byte answer
BaudRate:=Round(12e6/(16*(255.0*OutputData[1]+OutputData[0]+1.0)));
if UARTx2Mode then BaudRate:=BaudRate*2; // ATmega has x2 mode on UART
Result:=NO_ERROR;
SetEvent(SerializationEvent);
end;
//-------------------------------------------------------------------------------------------------------
function DoGetRS232BufferLocal(var RS232Buffer:array of byte; var RS232BufferLength:integer):integer;
//local function to obtain FIFO buffer into buffer
var
i,j:integer;
HeaderLength:integer;
begin
if RS232BufferLength<=0 then
begin
RS232BufferLength:=0;
Result:=NO_ERROR;
Exit;
end;
if WaitForSingleObject(SerializationEvent,SerializationEventTimeout)=WAIT_TIMEOUT then
begin
ShowThreadErrorMessage;
Result:=DEVICE_NOT_PRESENT;
RS232BufferLength:=0;
Exit;
end;
Result:=DEVICE_NOT_PRESENT;
i:=0;
HeaderLength:=1;
if UARTx2Mode then inc(HeaderLength);
repeat
OutLength:=RS232BufferLength-i+HeaderLength;
if OutLength>OutputDataLength then
OutLength:=OutputDataLength;
if not SendToDriver(FNCNumberDoGetRS232Buffer,0,0,OutputData,OutLength) then
begin
RS232BufferLength:=0;
SetEvent(SerializationEvent);
Exit;
end;
if (OutLength<=1) then
Break;
for j:=i to i+OutLength-HeaderLength-1 do
RS232Buffer[j]:=OutputData[j-i+HeaderLength];
i:=i+OutLength-HeaderLength;
until (RS232BufferLength<=i);
RS232BufferLength:=i;
Result:=NO_ERROR;
SetEvent(SerializationEvent);
end;
//-------------------------------------------------------------------------------------------------------
function DoGetRS232Buffer(var RS232Buffer:array of byte; var RS232BufferLength:integer):integer; stdcall export;
//;get received bytes from FIFO RS232 buffer
var
BufferLength,i:integer;
RS232BufferWriteLocal:integer;
P:^integer;
begin
BufferLength:=0;
Result:=NO_ERROR;
if RS232BufferLength>0 then
for i:=1 to RS232BufferLength do
begin
P:=@PGlobalRS232Buffer^[GlobalRS232BufferWritePos];
RS232BufferWriteLocal:=P^;
if (RS232BufferRead=RS232BufferWriteLocal) then
Break;
RS232Buffer[BufferLength]:=PGlobalRS232Buffer^[RS232BufferRead];
inc(BufferLength);
RS232BufferRead:=(RS232BufferRead+1) mod (GlobalRS232BufferEnd+1);
end;
RS232BufferLength:=BufferLength;
end;
//-------------------------------------------------------------------------------------------------------
function DoRS232BufferSend(var RS232Buffer:array of byte; var RS232BufferLength:integer):integer; stdcall export;
//;transmit given RS232 buffer to serial line
var
BufferLength,i:integer;
begin
BufferLength:=0;
Result:=NO_ERROR;
try
if RS232BufferLength>0 then
for i:=1 to RS232BufferLength do
begin
if DoRS232Send(RS232Buffer[BufferLength])=DEVICE_NOT_PRESENT then
begin
Result:=DEVICE_NOT_PRESENT;
Break;
end;
inc(BufferLength);
end;
finally
RS232BufferLength:=BufferLength;
end;
end;
//-------------------------------------------------------------------------------------------------------
function DoGetRS232BufferThreadProc(Parameter: Pointer): Integer;
//system unique thread for reading device RS232 FIFO into RS232 buffer
var
Handles:array[0..1] of integer;
MutexHandles:array[0..1] of integer;
BufferLength:integer;
NewRS232BufferWrite:integer;
i,j:integer;
P:^integer;
label
EndOfBufferThreadProc;
begin
Handles[0]:=RS232BufferGetEvent;
Handles[1]:=RS232BufferEndEvent;
MutexHandles[0]:=RS232MutexHandle;
MutexHandles[1]:=RS232BufferEndEvent;
Result:=0;
j:=0;
LocalThreadRunningEvent:=CreateEvent(nil,false,false,nil); //event to signal end of execution of this thread
if IsRS232PrevInst then
case WaitForMultipleObjects(2,@MutexHandles,false,INFINITE) of
WAIT_OBJECT_0,WAIT_ABANDONED_0:
begin
WaitForSingleObject(RS232MutexHandle,3000);
IsRS232PrevInst:=false;
P:=@PGlobalRS232Buffer^[GlobalRS232BufferWritePos];
RS232BufferWrite:=P^;
end;
WAIT_OBJECT_0+1,WAIT_ABANDONED_0+1:
begin
SetEvent(LocalThreadRunningEvent);
Exit;
end;
end;
DoGetRS232BufferTimer:=timeSetEvent(RS232BufferTimerInterval,1, TFNTimeCallBack(RS232BufferGetEvent), 0, TIME_PERIODIC or TIME_CALLBACK_EVENT_SET);
repeat
case WaitForMultipleObjects(2,@Handles,false,INFINITE) of
WAIT_OBJECT_0:
begin
repeat
BufferLength:=GlobalRS232BufferEnd-RS232BufferWrite+1;
if DoGetRS232BufferLocal(PGlobalRS232Buffer^[RS232BufferWrite], BufferLength)<>NO_ERROR then
begin
if WaitForSingleObject(RS232BufferEndEvent,2000)<>WAIT_TIMEOUT then // wait 2 seconds if there is no answer (save bandwidth for non-RS232 buffer devices)
begin
goto EndOfBufferThreadProc;
end;
Break;
end;
NewRS232BufferWrite:=RS232BufferWrite+BufferLength;
j:=Low(TGlobalRS232Buffer);
if NewRS232BufferWrite>GlobalRS232BufferEnd then
begin
for i:=GlobalRS232BufferEnd+1 to NewRS232BufferWrite do
begin
PGlobalRS232Buffer^[j]:=PGlobalRS232Buffer^[i];
inc(j);
end;
NewRS232BufferWrite:=NewRS232BufferWrite mod (GlobalRS232BufferEnd+1);
end;
RS232BufferWrite:=NewRS232BufferWrite;
P:=@PGlobalRS232Buffer^[GlobalRS232BufferWritePos];
P^:=RS232BufferWrite;
until j<=Low(TGlobalRS232Buffer);
end;
WAIT_OBJECT_0+1:
begin
Break;
end;
end;
until false;
EndOfBufferThreadProc:
if DoGetRS232BufferTimer<>0 then
begin
timeKillEvent(DoGetRS232BufferTimer);
DoGetRS232BufferTimer:=0;
end;
SetEvent(LocalThreadRunningEvent);
end;
//-------------------------------------------------------------------------------------------------------
procedure InitRS232ExclusiveSystemBuffer;
//inicialization of system unique RS232 buffer (memory mapped file)
var
P:^integer;
begin
RS232MutexHandle:=CreateMutex(nil, false, RS232BufferMutexName);
if RS232MutexHandle <> 0 then
begin
if GetLastError = ERROR_ALREADY_EXISTS then
IsRS232PrevInst := TRUE
else
IsRS232PrevInst := FALSE;
end
else
begin
IsRS232PrevInst := FALSE;
end;
if not IsRS232PrevInst then
WaitForSingleObject(RS232MutexHandle,3000);
RS232BufferFileMappedHND:=CreateFileMapping(MAXDWORD,nil,PAGE_READWRITE or SEC_COMMIT or SEC_NOCACHE,0,GlobalRS232BufferLength,RS232BufferFileMappedName);
if RS232BufferFileMappedHND=0 then
Exit;
PGlobalRS232Buffer:=MapViewOfFile(RS232BufferFileMappedHND,FILE_MAP_WRITE,0,0,GlobalRS232BufferLength);
if PGlobalRS232Buffer=nil then
Exit;
if IsRS232PrevInst then
begin
P:=@PGlobalRS232Buffer^[GlobalRS232BufferWritePos];
RS232BufferRead:=P^;
end;
end;
//-------------------------------------------------------------------------------------------------------
procedure CloseRS232ExclusiveSystemBuffer;
//close of system unique RS232 buffer (memory mapped file)
begin
if PGlobalRS232Buffer<>nil then
begin
UnmapViewOfFile(PGlobalRS232Buffer);
end;
if RS232BufferFileMappedHND>0 then
begin
CloseHandle(RS232BufferFileMappedHND);
end;
RS232BufferFileMappedHND:=0;
if not IsRS232PrevInst then
ReleaseMutex(RS232MutexHandle);
CloseHandle(RS232MutexHandle);
end;
//-------------------------------------------------------------------------------------------------------
procedure DLLMain(Reason : DWORD);
begin
case Reason of
DLL_PROCESS_ATTACH: //next application starts using DLL
begin
//All buffers, threads, events and synchronization object create
InitRS232ExclusiveSystemBuffer; //create RS232 buffer (memory mapped file)
SerializationEvent:=CreateEvent(nil,false,true,SerializationEventName);// serialization event for device access
{$IFDEF DemoVersion}
DemoOK:=MessageBox(0,'Please register!','Free version!',MB_OK or MB_ICONINFORMATION or MB_TASKMODAL or MB_TOPMOST);
{$ENDIF}
HookHandle:=SetWindowsHookEx(WH_GETMESSAGE,FNHookProc,0,GetCurrentThreadID); //install Hook function (WM_QUIT message)
RS232BufferGetEvent:=CreateEvent(nil,false,false,nil); //event for start reading device FIFO
RS232BufferEndEvent:=CreateEvent(nil,false,false,nil); //event to finish FIFO reading thread
RS232BufferThreadHND:=BeginThread(nil,0,DoGetRS232BufferThreadProc,nil,CREATE_SUSPENDED,Cardinal(RS232BufferThreadId)); //create FIFO reading thread (suspended)
SetThreadPriority(RS232BufferThreadHND,THREAD_PRIORITY_TIME_CRITICAL); //highest priority for FIFO reading thread
ResumeThread(RS232BufferThreadHND); //start FIFO reading thread
end;
DLL_PROCESS_DETACH: //next application ends using DLL
begin
if HookHandle<>0 then UnhookWindowsHookEx(HookHandle); //uninstall Hook function (WM_QUIT message)
if RS232BufferThreadHND<>0 then //if Hook function not unistalls thread - then uninstall it
begin
if DoGetRS232BufferTimer<>0 then
begin
timeKillEvent(DoGetRS232BufferTimer);
DoGetRS232BufferTimer:=0;
end;
SetEvent(RS232BufferEndEvent);
if LocalThreadRunningEvent<>0 then
begin
WaitForSingleObject(LocalThreadRunningEvent,5000);
WaitForSingleObject(RS232BufferThreadHND,10);
LocalThreadRunningEvent:=0;
end
else
WaitForSingleObject(RS232BufferThreadHND,400);
CloseHandle(RS232BufferThreadHND);
end;
if LocalThreadRunningEvent<>0 then
begin
CloseHandle(LocalThreadRunningEvent);
LocalThreadRunningEvent:=0;
end;
CloseHandle(RS232BufferGetEvent); //free event for start reading device FIFO
CloseHandle(RS232BufferEndEvent); //free event to finish FIFO reading thread
CloseHandle(SerializationEvent); //free serialization event for device access
CloseRS232ExclusiveSystemBuffer; //free RS232 buffer (memory mapped file)
{$IFDEF DemoVersion}
DemoOK:=MessageBox(0,'Please register!','Free version!',MB_OK or MB_ICONINFORMATION or MB_TASKMODAL or MB_TOPMOST);
{$ENDIF}
end;
DLL_THREAD_ATTACH: //next thread starts using DLL
begin
{$IFDEF DemoVersion}
if Trunc(DemoOK+0.123)<>(abs(OKDemoValue)-1) then Halt; // for bad cracking error
{$ENDIF}
end;
DLL_THREAD_DETACH: //next thread ends using DLL
begin
end;
end;
end;//DLLMain
//-------------------------------------------------------------------------------------------------------
exports
//exported functions:
//DoSetInfraBufferEmpty, //;restart of infra reading (if was stopped by RAM reading)
DoGetInfraCode, //;transmit of receved infra code (if some code in infra buffer)
DoSetDataPortDirection, //;set direction of data bits
DoGetDataPortDirection, //;get direction of data bits
DoSetOutDataPort, //;set data bits (if are bits as input, then set theirs pull-ups)
DoGetOutDataPort, //;get data bits (if are bits as input, then get theirs pull-ups)
DoGetInDataPort, //;get data bits - pin reading
DoEEPROMRead, //;read EEPROM from given address
DoEEPROMWrite, //;write data byte to EEPROM to given address
DoRS232Send, //;send one data byte to RS232 line
DoRS232Read, //;read one data byte from serial line (only when FIFO not implemented in device)
DoSetRS232Baud, //;set baud speed of serial line
DoGetRS232Baud, //;get baud speed of serial line (exact value)
DoGetRS232Buffer, //;get received bytes from FIFO RS232 buffer
DoRS232BufferSend, //;transmit given RS232 buffer to serial line
DoSetRS232DataBits, //;set number of data bits of serial line
DoGetRS232DataBits, //;get number of data bits of serial line
DoSetRS232Parity, //;set parity of serial line
DoGetRS232Parity, //;get parity of serial line
DoSetRS232StopBits, //;set stopbits of serial line
DoGetRS232StopBits, //;get stopbits of serial line
DoSetDataPortDirections, //;set directions of data bits
DoGetDataPortDirections, //;get directions of data bits
DoSetOutDataPorts, //;set data bits (if are bits as input, then set theirs pull-ups)
DoGetOutDataPorts, //;get data bits (if are bits as input, then get theirs pull-ups)
DoGetInDataPorts; //;get data bits - pin reading
begin
DLLProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -