unit communication; {$mode objfpc}{$H+} interface uses Classes, SysUtils,variables, crt,serial {$ifdef unix} ,baseunix; {$else} ,windows, winSock2,ctypes, dos, process; Type TFDSet=Winsock2.TFDSet; timeval=Winsock2.timeval; cint=ctypes.cint; {$endif} function senddata(param:longint;dd:double):longint; function getserialport:longint; procedure initUSB(shandler:longint); procedure closeUSB; function startUSB:longint; function getUSB(t:longint):string; procedure createfifo; procedure writefifo(d:data_t); function dataavailable:boolean; function readfifo(var d:data_t):boolean; procedure send_createfifo; procedure send_writefifo(d:send_t); function send_dataavailable:boolean; function send_readfifo(var d:send_t):boolean; function senddata_out:longint; procedure command_createfifo; procedure command_writefifo(d:String); function command_dataavailable:boolean; function command_readfifo(var d:String):boolean; procedure sendcommand(s:string); procedure datareadfromdevice; //procedure savedatas; var threadon:longint; device:string; notconnected:boolean=false; implementation uses main; const FIFOSIZE=10000; var p_str:pchar; mysocket:longint; fifo:array[0..FIFOSIZE] of data_t; fiforeadp,fifowritep:longint; send_fifo:array[0..FIFOSIZE] of send_t; send_fiforeadp,send_fifowritep:longint; command_fifo:array[0..FIFOSIZE] of String; command_fiforeadp,command_fifowritep:longint; ca:array[0..1024] of byte; USB_data:array[0..1024] of byte; serialhandler : LongInt; Parity : TParityType; { TParityType = (NoneParity, OddParity, EvenParity); } StopBits : Integer; Flags : TSerialFlags; { TSerialFlags = set of (RtsCtsFlowControl); } procedure createfifo; begin fifowritep:=0; fiforeadp:=0; end; procedure writefifo(d:data_t); begin fifo[fifowritep]:=d; inc(fifowritep); if fifowritep>=FIFOSIZE then fifowritep:=0; end; function dataavailable:boolean; begin if fiforeadp=fifowritep then dataavailable:=false else dataavailable:=true; end; function readfifo(var d:data_t):boolean; begin if fiforeadp=fifowritep then readfifo:=false else begin d:=fifo[fiforeadp]; inc(fiforeadp); if fiforeadp>=FIFOSIZE then fiforeadp:=0; readfifo:=true; end; end; procedure send_createfifo; begin send_fifowritep:=0; send_fiforeadp:=0; end; procedure send_writefifo(d:send_t); begin send_fifo[send_fifowritep]:=d; inc(send_fifowritep); //writeln(send_fifowritep); if send_fifowritep>=FIFOSIZE then send_fifowritep:=0; end; function send_dataavailable:boolean; begin if send_fiforeadp=send_fifowritep then send_dataavailable:=false else send_dataavailable:=true; end; function send_readfifo(var d:send_t):boolean; begin if send_fiforeadp=send_fifowritep then send_readfifo:=false else begin d:=send_fifo[send_fiforeadp]; inc(send_fiforeadp); if send_fiforeadp>=FIFOSIZE then send_fiforeadp:=0; send_readfifo:=true; end; end; procedure command_createfifo; begin command_fifowritep:=0; command_fiforeadp:=0; end; procedure command_writefifo(d:String); begin command_fifo[command_fifowritep]:=d; inc(command_fifowritep); if command_fifowritep>=FIFOSIZE then command_fifowritep:=0; end; function command_dataavailable:boolean; begin if command_fiforeadp=command_fifowritep then command_dataavailable:=false else command_dataavailable:=true; end; function command_readfifo(var d:String):boolean; begin if command_fiforeadp=command_fifowritep then command_readfifo:=false else begin d:=command_fifo[command_fiforeadp]; inc(command_fiforeadp); if command_fiforeadp>=FIFOSIZE then command_fiforeadp:=0; command_readfifo:=true; end; end; function get_double(start:longint):double; var d:double; dp:^byte; i:longint; begin dp:=@d; for i:=0 to 7 do begin dp^:=USB_data[i+start]; inc(dp); end; get_double:=d; end; procedure put_double(dd:double); var d:double; dp:^byte; i:longint; begin d:=dd; dp:=@d; for i:=0 to 7 do begin ca[i]:=dp^; inc(dp); //writeln(ca[i]); end; end; function senddata(param:longint;dd:double):longint; var p:send_t; begin p.param:=param; p.paramdata:=dd; send_writefifo(p); end; function senddata_out:longint; var cc: array[0..256] of byte; p:send_t; begin {$ifdef TEST} senddata:=0; exit; {$endif} //writeln(send_dataavailable); if not send_dataavailable then begin senddata_out:=0; exit; end; send_readfifo(p); cc[0]:=byte('S');cc[1]:=byte('T'); SerWrite(serialhandler, cc, 2); put_double(p.param); SerWrite(serialhandler, ca, 8); put_double(p.paramdata); SerWrite(serialhandler, ca, 8); cc[0]:=byte('E'); cc[1]:=byte('D'); SerWrite(serialhandler, cc, 2); cc[0]:=byte(' '); SerDrain(serialhandler); sleep(50); senddata_out:=1; //writeln(trunc(p.param),' ',p.paramdata) end; function getDTA:longint; var s:string; begin Flags:= [ ]; // None SerSetParams(serialhandler,115200,8,NoneParity,1,Flags); initUSB(serialhandler); s:=getUSB(10); writeln('itt0'+s); senddata(SRESET,0); senddata_out; sleep(1000); s:=getUSB(10000); writeln('itt'+s); if pos('DTA',s)<>0 then begin s:=getUSB(5000); getDTA:=0; writeln('DTA connected'); messagestr:='Connected to DTA'; exit; end; closeUSB; getDTA:=-1; end; function ss(dev:string):longint; begin serialhandler:=SerOpen(dev); if serialhandler>0 then if getDTA=0 then begin device:=dev; ss:=serialhandler; exit; end; ss:=-1; end; function getserialport:longint; var s:string; dev:string; begin {$ifdef Linux} dev:='/dev/ttyACM0'; {$else} dev:='COM3'; {$endif} getserialport:=ss(dev); if getserialport>0 then exit; {$ifdef Linux} dev:='/dev/ttyACM1'; {$else} dev:='COM2'; {$endif} getserialport:=ss(dev); if getserialport>0 then exit; {$ifdef Linux} dev:='/dev/ttyACM2'; {$else} dev:='COM1'; {$endif} getserialport:=ss(dev); if getserialport>0 then exit; {$ifdef Linux} dev:='/dev/ttyACM3'; {$else} dev:='COM4'; {$endif} getserialport:=ss(dev); if getserialport>0 then exit; getserialport:=-1; end; procedure initUSB(shandler:longint); var status:longint=0; x:String; i:longint; ss:byte; begin sleep(1000); while (Length(x)<2000) and (status>=0) do begin status:= SerRead(shandler, ss, 1); if status=0 then begin sleep(1); inc(i); end; //if (status>0) then writeln(ss); if (status>0) then x:=x+chr(ss); if i>1000 then begin exit; end; end; end; procedure sendcommand(s:string); var writecount:longint; status:longint; ss:string; begin ss:='MS '+s+chr(13); writecount := length(ss); //writeln(ss); status := SerWrite(serialhandler, ss[1], writecount ); end; function getUSB(t:longint):string; var s:String=' '; status:longint=0; x:String; i:longint=0; ss:byte; begin getUSB:=''; if serialhandler<0 then exit; while (Length(x)<50) and (status>=0) do begin status:= SerRead(serialhandler, ss, 1); if (status=0) and (t=0) then begin getUSB:='nodata'; exit; end; if status=0 then begin sleep(1); inc(i); end; if (ss=10) then status:=-1; if (status>0) then begin i:=0; if ss<>13 then x:=x+chr(ss); end; if i>t then begin getUSB:='timeout'; exit; end; end; getUSB:=x; end; function startUSB:longint; var s:string; begin if getserialport<0 then begin startUSB:=-1; writeln('no device found'); exit; end; startUSB:=0; //writeln('device '+device); end; procedure closeUSB; begin SerSync(serialhandler); { flush out any remaining before closure } SerFlushOutput(serialhandler); { discard any remaining output } SerClose(serialhandler); end; function dataready:longint; var status:longint; ss:array[0..255] of byte; s:string; datanum:longint=22*8; i:longint; begin s:=''; status:=SerReadTimeout(serialhandler, ss, 2,100); if status=0 then begin dataready:=0; exit; end; if (char(ss[0])='M') and (char(ss[1])='S') then while true do begin status:=SerReadTimeout(serialhandler, ss, 1,100); if (status<>0) and (ss[0]<>10) then s:=s+char(ss[0]); if (status=0) or (ss[0]=10) then begin //writeln(s); dataready:=-1; exit; end; end; if (char(ss[0])='S') and (char(ss[1])='T') then begin status:=SerReadTimeout(serialhandler,USB_data, datanum,100); if status=datanum then begin dataready:=1; for i:=0 to 21 do begin d_send[i]:=get_double(8*i); end; datagetonb:=false; exit; end; end; datagetonb:=false; dataready:=-2; end; procedure datareadfromdevice; var i:longint; begin {$ifndef TEST} if dataready<=0 then begin sleep(10); exit; end; {$endif} {$ifdef TEST} begin t:=t+dtime/1e9;; readdata.time:=t; readdata.q:=10.0*sin(6.28*t/10.0); readdata.tempp:=20.0*sin(6.28*t/10.0+1.5); readdata.temp:=20.0*sin(6.28*t/10.0+1.8); readdata.temp2:=5.0*sin(6.28*t/10.0+1.8); if running then begin writefifo(readdata); inc(datanum); {$I-} ioresult; //write(filetmp, readdata); {$I+} end; end {$else} tempzero:=d_send[13]; tempslope:=d_send[14]; tempparab:=d_send[15]; pa:=d_send[16]; pb:=d_send[17]; pc:=d_send[18]; inttime:=d_send[19]; temp20:=d_send[20]; q0:=d_send[21]; readdata.q:=d_send[0]; readdata.time:=d_send[8]/1e6; readdata.temp1:=d_send[1]; readdata.tempf:=d_send[2]; readdata.temp2:= readdata.temp1- readdata.q; readdata.lag:=d_send[4]; readdata.powerback:=d_send[5]; readdata.tempp:=d_send[9]; readdata.power:=100*d_send[7]; readdata.rate:=d_send[10]*6e7; readdata.paramdata:=d_send[11]; readdata.param:=d_send[12]; writefifo(readdata); {$endif} end; end.