-
Notifications
You must be signed in to change notification settings - Fork 0
/
myserial.pas
154 lines (119 loc) · 5.37 KB
/
myserial.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
{This unit was originally part of the FreePascal RTL library. It was adapted at some points to allow easier use on different platforms
and will stay in this repository under the original FreePascal license (see e.g. https://wiki.lazarus.freepascal.org/licensing) until the
changes could be merged back to master, if possible.}
unit MySerial;
{$if defined(UNIX)}
{$MODE objfpc}
{$H+}
{$PACKRECORDS C}
{$elseif defined(WINDOWS)}
{$MODE objfpc}
{$H+}
{$else}
{$warning MySerial is not supported on your platform!}
{$endif}
interface
//Uses
{$if defined(UNIX)}
uses BaseUnix,termio,unix;
{$elseif defined(WINDOWS)}
uses Windows;
{$endif}
//Global Definitions
type
{$if defined(UNIX)}
TSerialHandle = LongInt;
{$elseif defined(WINDOWS)}
TSerialHandle = THandle;
{$endif}
TParityType = (NoneParity, OddParity, EvenParity);
TStopBits = (SerialStop1, SerialStop15, SerialStop2);
TSerialFlags = set of (RtsCtsFlowControl);
{$if defined(UNIX)}
TSerialState = record
LineState: LongWord;
tios: termios;
end;
{$elseif defined(WINDOWS)}
TSerialState = TDCB;
{$endif}
type TSerialIdle= procedure(h: TSerialHandle);
{ Set this to a shim around Application.ProcessMessages if calling SerReadTimeout(),
SerBreak() etc. from the main thread so that it doesn't lock up a Lazarus app. }
var SerialIdle: TSerialIdle= nil;
//Platform independant interface
{ Open the serial device with the given device name, for example:
/dev/ttyS0, /dev/ttyS1... for normal serial ports
/dev/ttyI0, /dev/ttyI1... for ISDN emulated serial ports
other device names are possible; refer to your OS documentation.
Returns "0" if device could not be found }
function SerOpen(const DeviceName: String): TSerialHandle;
{ Closes a serial device previously opened with SerOpen. }
procedure SerClose(Handle: TSerialHandle);
{ Flushes the data queues of the given serial device. DO NOT USE THIS:
use either SerSync (non-blocking) or SerDrain (blocking). }
procedure SerFlush(Handle: TSerialHandle); deprecated;
{ Suggest to the kernel that buffered output data should be sent. This
is unlikely to have a useful effect except possibly in the case of
buggy ports that lose Tx interrupts, and is implemented as a preferred
alternative to the deprecated SerFlush procedure. }
procedure SerSync(Handle: TSerialHandle);
{ Wait until all buffered output has been transmitted. It is the caller's
responsibility to ensure that this won't block permanently due to an
inappropriate handshake state. }
procedure SerDrain(Handle: TSerialHandle);
{ Discard all pending input. }
procedure SerFlushInput(Handle: TSerialHandle);
{ Discard all unsent output. }
procedure SerFlushOutput(Handle: TSerialHandle);
{ Reads a maximum of "Count" bytes of data into the specified buffer.
Result: Number of bytes read. }
function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
{ Tries to write "Count" bytes from "Buffer".
Result: Number of bytes written. }
function SerWrite(Handle: TSerialHandle; Const Buffer; Count: LongInt): LongInt;
procedure SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
ByteSize: Integer; Parity: TParityType; StopBits: TStopBits;
Flags: TSerialFlags);
{ Saves and restores the state of the serial device. }
function SerSaveState(Handle: TSerialHandle): TSerialState;
procedure SerRestoreState(Handle: TSerialHandle; State: TSerialState);
{ Getting and setting the line states directly. }
procedure SerSetDTR(Handle: TSerialHandle; State: Boolean);
procedure SerSetRTS(Handle: TSerialHandle; State: Boolean);
function SerGetCTS(Handle: TSerialHandle): Boolean;
function SerGetDSR(Handle: TSerialHandle): Boolean;
function SerGetCD(Handle: TSerialHandle): Boolean;
function SerGetRI(Handle: TSerialHandle): Boolean;
{ Set a line break state. If the requested time is greater than zero this is in
mSec, in the case of unix this is likely to be rounded up to a few hundred
mSec and to increase by a comparable increment; on unix if the time is less
than or equal to zero its absolute value will be passed directly to the
operating system with implementation-specific effect. If the third parameter
is omitted or true there will be an implicit call of SerDrain() before and
after the break.
NOTE THAT on Linux, the only reliable mSec parameter is zero which results in
a break of around 250 mSec. Might be completely ineffective on Solaris.
}
procedure SerBreak(Handle: TSerialHandle; mSec: LongInt=0; sync: boolean= true);
{ This is similar to SerRead() but adds a mSec timeout. Note that this variant
returns as soon as a single byte is available, or as dictated by the timeout. }
function SerReadTimeout(Handle: TSerialHandle; var Buffer; mSec: LongInt): LongInt;
{ This is similar to SerRead() but adds a mSec timeout. Note that this variant
attempts to accumulate as many bytes as are available, but does not exceed
the timeout. Set up a SerIdle callback if using this in a main thread in a
Lazarus app. }
function SerReadTimeout(Handle: TSerialHandle; var Buffer; count: LongInt; mSec: Cardinal): LongInt;
function GetBytesWaiting(Handle: TSerialHandle; out bytesAtPort:integer):boolean;
implementation
{$if defined(UNIX)}
{$MODE objfpc}
{$H+}
{$PACKRECORDS C}
{$I serialunix.inc}
{$elseif defined(WINDOWS)}
{$I serialwin.inc}
{$else}
{$warning MySerial is not supported on your platform!}
{$endif}
end.