unit ToolsRS;

interface

uses

	Forms, AdPort, OoMisc;

	var

		BufIn, BufOut : Array [0..200000] of byte;
		FlagRS        : Boolean = false;
		FlagAbortKey  : Boolean = false;

		Count_error		: Integer = 0;
		RSTimeOut			: Boolean = True;

	procedure SendAddress (AdrCon:Byte);
	function RunCmdNew (Cmd : Byte; LengthOut,LengthIn :LongWord): Byte;
	function ContrlolSumCRC16(BufCRC : Array of Byte; LengthB : LongWord): Word;
	function LB(X: Word): Byte;
	function HB(X: Word): Byte;

implementation

uses CAN_Terminal;

Function ContrlolSumCRC16(BufCRC : Array of Byte; LengthB : LongWord) : Word;
Var
	CRC    : Word;
	Index1,
	Index2: LongWord;
	 rb  : Byte;
Begin

	CRC := $ffff;
	For Index1 := 0 To LengthB-1 Do
		Begin
			CRC := (CRC and $FFFF);
			CRC := (CRC XOR (BufCRC[Index1]));
			For Index2 := 1 To 8 Do
				If ((CRC And $1) <> 0) Then
					 CRC := ((CRC SHR 1) xor $A001) else CRC := (CRC SHR 1)
		end;
	Result := (CRC and $FFFF);

end;

procedure SendAddress (AdrCon:Byte);
var
		 ET            : EventTimer;

begin
	if AdrCon = 0 then exit;
	CANTerminal.MyCommPort.Parity:=pNone;
	CANTerminal.MyCommPort.PutChar(Chr(AdrCon));
end;



function RunCmdNew(Cmd : Byte; LengthOut,LengthIn :LongWord): Byte;
var

		b             : Byte;
		CSum,PAdr     : Word;
		CSumb         : Byte;
		BB            : LongWord;
		bb1,bb2       : Word;
		i,i1,i2       : LongWord;
		ET            : EventTimer;
		Ch            : Char;
		BufSize       : LongWord ;
		Posit         : LongWord;
		Block1        : Array [0..9000] of byte;
		FlagOpenRS    : Boolean;
		Fr            : Byte;

begin
		 if CANTerminal.MyCommPort.OutBuffUsed <> 0 then exit;

		 FlagRs:=True;
		 FlagAbortKey:=False;
		 CANTerminal.AbortKey.Visible:=True;

		 FlagOpenRS := CANTerminal.MyCommPort.Open;

		 CANTerminal.MyCommPort.Open:=True;

		 CANTerminal.MyCommPort.FlushInBuffer;
		 CANTerminal.MyCommPort.FlushOutBuffer;

		 Posit:=0;
		 CANTerminal.PBRs.Position:=0;
		 CANTerminal.PBRs.Max:=LengthOut+LengthIn;

		 Count_error := 0;

		 BufIn[0]:=0;
		 BufIn[1]:=0;
		 BufIn[2]:=0;
		 BufIn[3]:=0;
		 BufIn[4]:=0;
		 BufIn[5]:=0;
		 BufIn[6]:=0;
		 BufIn[7]:=0;
		 BufIn[8]:=0;
		 BufIn[9]:=0;

		 Padr:=$3f8+5;

		 if Cmd<>0 then SendAddress(Cmd);

		 BufOut[LengthOut]:=0;
		 BufOut[LengthOut+1]:=0;
		 BufOut[LengthOut+2]:=0;
		 BufOut[LengthOut+3]:=0;

		 i1:=LengthOut+1;
		 i2:=0;

		 repeat

					 if i1>=1024 then begin

						 for i:=0 to 1023 do Block1[i] := BufOut[i+i2];

						 while CANTerminal.MyCommPort.OutBuffUsed<>0 do;

						 CANTerminal.MyCommPort.PutBlock(Block1,1024);
						 Posit:=Posit+1024;

						 i1:=i1-1024;
						 i2:=i2+1024;

					 end
					 else
					 begin

						 if ((i1<1024) and (i1>0)) then begin

							 for i:=0 to i1-1 do Block1[i] := BufOut[i+i2];

							 while CANTerminal.MyCommPort.OutBuffUsed<>0 do;

							 CANTerminal.MyCommPort.PutBlock(Block1,i1);
							 Posit:=Posit+i1;

							 while CANTerminal.MyCommPort.OutBuffUsed<>0 do;

							 i1:=0;
							 i2:=LengthOut;
						 end;

					 end;
					 CANTerminal.PBRs.Position:=Posit;
					 Application.ProcessMessages;

					 if FlagAbortKey then begin
						 Result:=3;
						 FlagRs:=False;

						 CANTerminal.MyCommPort.Open:=FlagOpenRS;
						 exit;

						 FlagAbortKey:=False;
						 CANTerminal.AbortKey.Visible:=False;
					 end;

		 until  (i1=0);

		 while CANTerminal.MyCommPort.OutBuffUsed<>0 do;

		 i:=0;

		 while i<(LengthIn) do begin

			 bb:=0;

			 RSTimeOut:= false;
			 NewTimer(ET,Round(CANTerminal.TimeWait.Value));

			 repeat
					CANTerminal.MyCommPort.ProcessCommunications;
	//				Application.ProcessMessages;

					if CANTerminal.MyCommPort.InBuffUsed>1024 then begin
							CANTerminal.MyCommPort.GetBlock(Block1,1024);
							for i1:=0 to 1023 do BufIn[i+i1]:=Block1[i1];
							i:=i+i1;
							Posit:=Posit+1024;
					end;

					If CANTerminal.MyCommPort.CharReady then
					begin
						inc(Posit);
						CANTerminal.PBRs.Position:=Posit;
						Ch:=CANTerminal.MyCommPort.GetChar;
						bb:=1;

						BufIn[i]:=Ord(Ch);
						inc(i);

 //						if not ((i>2) and (i > BufIn[2]+4))
//						then Application.ProcessMessages;

						Break;

					end;

					 if FlagAbortKey then begin
						 FlagAbortKey:=False;
						 CANTerminal.AbortKey.Visible:=False;
						 Result:=3;	//	Получение прервано кнопкой
						 FlagRs:=False;
						 CANTerminal.MyCommPort.Open:=FlagOpenRS;
						 exit;
					 end;

			 until TimerExpired(ET) { or (RSTimeOut) };

			 If bb=0 then Break;

		 end;

		 CANTerminal.MyCommPort.FlushInBuffer;
		 CANTerminal.MyCommPort.FlushOutBuffer;


		 FlagAbortKey:=False;
		 CANTerminal.AbortKey.Visible:=False;

		If bb=0 then
		begin
			Result:=1;	//	ничего не пришло...
			CANTerminal.MyCommPort.Open:=FlagOpenRS;
			FlagRs:=False;
			exit;
		end;

		Csum:=ContrlolSumCRC16(BufIn,LengthIn-2);

		if CSum<>(BufIn[LengthIn-2]+BufIn[LengthIn-1]*256) then
		begin
			Result:=2;	//	не сошлась контрольная сумма
			FlagRs:=False;
			CANTerminal.MyCommPort.Open:=FlagOpenRS;
			exit;
		end
		else
				Result:=0;

		CANTerminal.MyCommPort.Open:=FlagOpenRS;
		FlagRs:=False;
		CSum:=i;
		if PAdr=0 then CSum:=i;

end;




{Получение младшего байта}
function LB(X: Word): Byte;
var	b1: Byte;
begin
	 asm
		mov  ax,X
		mov  b1,al
	 end;
	 Result:=b1;
end;

{Получение старшего байта}
function HB(X: Word): Byte;
var	b1: Byte;
begin
	 asm
		mov  ax,X
		mov  b1,ah
	 end;
	 Result:=b1;
end;


end.
