361 lines
7.9 KiB
Plaintext
Executable File
361 lines
7.9 KiB
Plaintext
Executable File
{ USerial : Windows/DOS 16C450 or 16C550 or Mesa Serial port routines }
|
|
|
|
type
|
|
ComPortHardwareTypes = (STDComPort,MESAComPort,SSLBPPort,NOPort);
|
|
|
|
var
|
|
CharTimeOut : longint; { milliseconds }
|
|
ExitOnTimeout : boolean;
|
|
TheBaudRateMul : real;
|
|
TheBaudRate : longint;
|
|
SerError : boolean;
|
|
ComPortHardwareType : ComPortHardwareTypes;
|
|
|
|
{$IFNDEF WINDOWS}
|
|
{$I serial.pas }
|
|
{I MesaUart.pas }
|
|
{$I M32Uart.pas }
|
|
{$ENDIF}
|
|
|
|
procedure SerSetRTSHigh;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
Ser.RTS := true;
|
|
{$ELSE}
|
|
case ComPortHardwareType of
|
|
STDComPort: ForceRTSHigh(TheComPort);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure SerSetRTSLow;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
Ser.RTS := false;
|
|
{$ELSE}
|
|
case ComPortHardwareType of
|
|
STDComPort: ForceRTSLow(TheComPort);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
|
|
{$IFDEF WINDOWS}
|
|
procedure SerTossChars;
|
|
var dummychar : char;
|
|
begin
|
|
ser.Purge;
|
|
repeat
|
|
delay(10);
|
|
if ser.WaitingData <> 0 then
|
|
begin
|
|
dummychar := char(ser.RecvByte(CharTimeOut));
|
|
end;
|
|
delay(10);
|
|
until ser.WaitingData = 0;
|
|
end;
|
|
|
|
{$ELSE NOT WINDOWS}
|
|
|
|
|
|
procedure SerTossChars;
|
|
begin
|
|
case ComPortHardwareType of
|
|
STDComPort: TossChars(TheComPort,20);
|
|
MESAComPort: MesaSerTossChars(TheComport);
|
|
end;
|
|
end;
|
|
|
|
function STDBaudRateValid(comport : word; br,bm : real) : boolean;
|
|
var ourbaud,testbaud,ratio : real;
|
|
divisor : word;
|
|
begin
|
|
STDBaudRateValid := true;
|
|
ourbaud := br/bm;
|
|
divisor := round(STDBRClock/round(br/bm*16.0));
|
|
testbaud := StdBRClock / divisor /16.0;
|
|
ratio := ourbaud / testbaud;
|
|
if (ratio > 1.0) and (ratio > 1.03) then STDBaudRateValid := false;
|
|
if (ratio < 1.0) and (ratio < 0.97) then STDBaudRateValid := false;
|
|
end;
|
|
|
|
function STDSetBaud(comport : word; br,bm : real) : boolean;
|
|
var ourbaud : real;
|
|
begin
|
|
if STDBaudRateValid(comport,br,bm) then
|
|
begin
|
|
ourbaud := br/bm;
|
|
{$IFDEF WINDOWS}
|
|
ser.Config(round(ourbaud),8,'N',0,false,false);
|
|
{$ELSE} { DOS }
|
|
SetBaudRate(comport,round(ourbaud));
|
|
{$ENDIF}
|
|
STDSetBaud := true;
|
|
end
|
|
else
|
|
begin
|
|
STDSetBaud := false;
|
|
writeln('Invalid Baud Rate');
|
|
end;
|
|
end;
|
|
|
|
{ dos }
|
|
|
|
function DosSerRecvChar(var c : char) : boolean;
|
|
var timeout : longint;
|
|
ourchar : char;
|
|
begin
|
|
timeout := CharTimeOut;
|
|
while ((port[TheComPort + LineStat] and DataReady) = 0) and (timeout <> 0) do timeout := timeout -1;
|
|
if timeout <> 0 then
|
|
begin
|
|
ourchar := char(port[TheComPort + RecReg]);
|
|
DosSerRecvChar := true;
|
|
c := ourchar;
|
|
{$IFDEF SDEBUG}
|
|
Hexprint(byte(ourchar),2);
|
|
write(' ');
|
|
{$ENDIF}
|
|
end
|
|
else
|
|
begin
|
|
DosSerRecvChar := false;
|
|
SerError := true;
|
|
if ExitOnTimeout then Error(CharTimeoutErr);
|
|
end;
|
|
end;
|
|
|
|
function DosSerRecvString(n : integer;var s : string) : boolean;
|
|
var
|
|
count : integer;
|
|
is : string;
|
|
timeout : longint;
|
|
ourchar : char;
|
|
charok : boolean;
|
|
begin
|
|
DosSerRecvString := false;
|
|
charok := true;
|
|
is := '';
|
|
for count := 1 to n do
|
|
begin
|
|
if DosSerRecvChar(ourchar) then
|
|
begin
|
|
is := is + ourchar;
|
|
end else charok := false;
|
|
end;
|
|
DosSerRecvString := charok;
|
|
s := is;
|
|
end;
|
|
|
|
procedure DosSerSendChar(c : char);
|
|
var dummy : char;
|
|
begin
|
|
if SerType = TwoWire then
|
|
begin
|
|
ForceRTSHigh(TheComPort);
|
|
{delay(1);}
|
|
end;
|
|
while (port[TheComPort + LineStat] and THRE) = 0 do {wait for xmit char} ;
|
|
port[TheComPort + TrHReg] := byte(c);
|
|
{$IFDEF SDEBUG}
|
|
DebugString := DebugString + HexString(longint(c),2) + ' ';
|
|
{$ENDIF}
|
|
|
|
if SerType = TwoWire then
|
|
begin
|
|
WaitForXmitDone(TheComPort);
|
|
ForceRTSLow(TheComPort);
|
|
DosSerRecvChar(dummy);
|
|
end;
|
|
end;
|
|
|
|
procedure DosSerSendString(s : string);
|
|
var i : integer;
|
|
begin
|
|
DisableInterrupts;
|
|
for i := 1 to length(s) do
|
|
begin
|
|
DosSerSendChar(s[i]);
|
|
end;
|
|
EnableInterrupts;
|
|
end;
|
|
|
|
procedure DosSerOpen(comport : word; br,bm : real);
|
|
begin
|
|
DefaultComInit(comport);
|
|
EnableFifos(comport); { don't check if fifos are there because it sends garbage }
|
|
STDSetBaud(comport,br,bm);
|
|
TossChars(comport,20); { make real sure there are no pending chars }
|
|
end;
|
|
|
|
function DosCanRead(ms : integer) : boolean;
|
|
var ctimeout : longint;
|
|
begin
|
|
if ms <> 0 then
|
|
begin
|
|
ctimeout := LoopsPermS * longint(ms);
|
|
while ((port[TheComPort + LineStat] and DataReady = 0) and (ctimeout <> 0)) do ctimeout := ctimeout -1;
|
|
if ctimeout <> 0 then DosCanRead := true else DosCanRead := false;
|
|
end
|
|
else if ((port[TheComPort + LineStat] and DataReady) <> 0) then DosCanRead := true else DosCanRead := false
|
|
end;
|
|
{$ENDIF WINDOWS}
|
|
|
|
{ all }
|
|
|
|
function SerOpen(var message : string) : boolean;
|
|
var openok : boolean;
|
|
begin
|
|
message := '';
|
|
SerOpen := false;
|
|
openok := false;
|
|
{$IFDEF WINDOWS}
|
|
|
|
{Writeln('Attempt to open serial port: ',TheComPort); }
|
|
ser:=TBlockserial.Create;
|
|
{ser.RaiseExcept:=True;}
|
|
ser.Connect(TheComPort);
|
|
ser.Config(round(TheBaudrate/TheBaudRateMul),8,'N',0,false,false);
|
|
if ser.LastError = 0 then openok := true else message := TheComPort;
|
|
SerTossChars;
|
|
{$ELSE} { DOS }
|
|
case ComPortHardwareType of
|
|
MESAComPort:
|
|
begin
|
|
if MesaComportThere(TheComPort) then
|
|
begin
|
|
MesaSerOpen(TheComPort,TheBaudRate,TheBaudRateMul);
|
|
openok := true;
|
|
end;
|
|
message := 'MesaCom port'
|
|
end;
|
|
|
|
STDComPort:
|
|
begin
|
|
if ComPortThere(TheComport) then
|
|
begin
|
|
DosSerOpen(TheComPort,TheBaudRate,TheBaudRateMul);
|
|
openok := true;
|
|
end;
|
|
message := 'Dos Com port'
|
|
end;
|
|
end; { case }
|
|
{$ENDIF}
|
|
if openok then
|
|
begin
|
|
message := message + ' open ok';
|
|
SerOpen := true;
|
|
end else message := message + ' open failed';
|
|
end;
|
|
|
|
procedure SerClose;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
ser.free;
|
|
{$ELSE} { DOS }
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function SerRecvChar(var c : char) : boolean;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
SerError := true;
|
|
c := char(ser.RecvByte(CharTimeOut));
|
|
if ser.LastError = ErrTimeout then
|
|
begin
|
|
SerRecvChar := false;
|
|
if ExitOnTimeout then Error(CharTimeoutErr);
|
|
end
|
|
else
|
|
begin
|
|
SerRecvChar := true;
|
|
SerError := false;
|
|
end;
|
|
{$ELSE} { DOS }
|
|
case ComPortHardwareType of
|
|
MESAComPort: SerRecvChar := MesaSerRecvChar(c);
|
|
STDComPort: SerRecvChar := DosSerRecvChar(c);
|
|
end;
|
|
{$ENDIF}
|
|
{$IFDEF SERDEBUG}
|
|
Hexprint(byte(c),2);
|
|
writeln;
|
|
{$ENDIF}
|
|
|
|
end;
|
|
|
|
function SerRecvString(n : integer;var s : string) : boolean;
|
|
var index : integer;
|
|
begin
|
|
s := '';
|
|
{$IFDEF WINDOWS}
|
|
s := ser.RecvBufferStr(n,CharTimeOut);
|
|
if ser.LastError = ErrTimeout then SerRecvString := false else SerRecvString := true;
|
|
{$ELSE} { DOS }
|
|
case ComPortHardwareType of
|
|
MESAComPort: SerRecvString := MesaSerRecvString(n,s);
|
|
STDComPort: SerRecvString := DosSerRecvString(n,s);
|
|
end;
|
|
{$ENDIF}
|
|
{$IFDEF SERDEBUG}
|
|
write('Recv Data: ');
|
|
for index := 1 to length(s) do
|
|
begin
|
|
hexprint(byte(s[index]),2);
|
|
write(',');
|
|
end;
|
|
writeln;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure SerSendChar(c : char);
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
ser.SendByte(byte(c));
|
|
{$ELSE} { DOS }
|
|
case ComPortHardwareType of
|
|
MESAComPort: MesaSerSendChar(c);
|
|
STDComPort: DosSerSendChar(c);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure SerSendString(s : string);
|
|
var index : integer;
|
|
begin
|
|
{$IFDEF SERDEBUG}
|
|
write('Send Data: ');
|
|
for index := 1 to length(s) do
|
|
begin
|
|
hexprint(byte(s[index]),2);
|
|
write(',');
|
|
end;
|
|
writeln;
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFDEF WINDOWS}
|
|
ser.SendString(s);
|
|
{$ELSE}
|
|
case ComPortHardwareType of
|
|
MESAComPort: MesaSendString(s);
|
|
STDComPort: DosSerSendString(s);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function SerCanRead(ms: longint) : boolean;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
SerCanRead := ser.CanReadEx(ms);
|
|
{$ELSE} { DOS }
|
|
case ComPortHardwareType of
|
|
MESAComPort: SerCanRead := MesaCanRead(ms);
|
|
STDComPort: SerCanRead := DosCanRead(ms);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{fixed toss char reversed paramaters range check error 12-16-2009}
|
|
{don't setrtshigh/low in mesa mode 2-3-2010 }
|