serial.pp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. { Unit for handling the serial interfaces for Linux and similar Unices.
  2. (c) 2000 Sebastian Guenther, [email protected]
  3. }
  4. unit Serial;
  5. {$MODE objfpc}
  6. {$H+}
  7. {$PACKRECORDS C}
  8. interface
  9. uses Unix;
  10. type
  11. TSerialHandle = LongInt;
  12. TParityType = (NoneParity, OddParity, EvenParity);
  13. TSerialFlags = set of (RtsCtsFlowControl);
  14. TSerialState = record
  15. LineState: LongWord;
  16. tios: termios;
  17. end;
  18. { Open the serial device with the given device name, for example:
  19. /dev/ttyS0, /dev/ttyS1... for normal serial ports
  20. /dev/ttyI0, /dev/ttyI1... for ISDN emulated serial ports
  21. other device names are possible; refer to your OS documentation.
  22. Returns "0" if device could not be found }
  23. function SerOpen(const DeviceName: String): TSerialHandle;
  24. { Closes a serial device previously opened with SerOpen. }
  25. procedure SerClose(Handle: TSerialHandle);
  26. { Flushes the data queues of the given serial device. }
  27. procedure SerFlush(Handle: TSerialHandle);
  28. { Reads a maximum of "Count" bytes of data into the specified buffer.
  29. Result: Number of bytes read. }
  30. function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  31. { Tries to write "Count" bytes from "Buffer".
  32. Result: Number of bytes written. }
  33. function SerWrite(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  34. procedure SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
  35. ByteSize: Integer; Parity: TParityType; StopBits: Integer;
  36. Flags: TSerialFlags);
  37. { Saves and restores the state of the serial device. }
  38. function SerSaveState(Handle: TSerialHandle): TSerialState;
  39. procedure SerRestoreState(Handle: TSerialHandle; State: TSerialState);
  40. { Getting and setting the line states directly. }
  41. procedure SerSetDTR(Handle: TSerialHandle; State: Boolean);
  42. procedure SerSetRTS(Handle: TSerialHandle; State: Boolean);
  43. function SerGetCTS(Handle: TSerialHandle): Boolean;
  44. function SerGetDSR(Handle: TSerialHandle): Boolean;
  45. function SerGetRI(Handle: TSerialHandle): Boolean;
  46. { ************************************************************************** }
  47. implementation
  48. function SerOpen(const DeviceName: String): TSerialHandle;
  49. begin
  50. Result := fdOpen(DeviceName, OPEN_RDWR or OPEN_EXCL or OPEN_NOCTTY);
  51. end;
  52. procedure SerClose(Handle: TSerialHandle);
  53. begin
  54. fdClose(Handle);
  55. end;
  56. procedure SerFlush(Handle: TSerialHandle);
  57. begin
  58. fdFlush(Handle);
  59. end;
  60. function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  61. begin
  62. Result := fdRead(Handle, Buffer, Count);
  63. end;
  64. function SerWrite(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  65. begin
  66. Result := fdWrite(Handle, Buffer, Count);
  67. end;
  68. procedure SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
  69. ByteSize: Integer; Parity: TParityType; StopBits: Integer;
  70. Flags: TSerialFlags);
  71. var
  72. tios: termios;
  73. begin
  74. TcGetAttr(handle,tios);
  75. // ioctl(Handle, TCGETS, @tios);
  76. case BitsPerSec of
  77. 50: tios.c_cflag := B50;
  78. 75: tios.c_cflag := B75;
  79. 110: tios.c_cflag := B110;
  80. 134: tios.c_cflag := B134;
  81. 150: tios.c_cflag := B150;
  82. 200: tios.c_cflag := B200;
  83. 300: tios.c_cflag := B300;
  84. 600: tios.c_cflag := B600;
  85. 1200: tios.c_cflag := B1200;
  86. 1800: tios.c_cflag := B1800;
  87. 2400: tios.c_cflag := B2400;
  88. 4800: tios.c_cflag := B4800;
  89. 19200: tios.c_cflag := B19200;
  90. 38400: tios.c_cflag := B38400;
  91. 57600: tios.c_cflag := B57600;
  92. 115200: tios.c_cflag := B115200;
  93. 230400: tios.c_cflag := B230400;
  94. {$ifndef BSD}
  95. 460800: tios.c_cflag := B460800;
  96. {$endif}
  97. else tios.c_cflag := B9600;
  98. end;
  99. case ByteSize of
  100. 5: tios.c_cflag := tios.c_cflag or CS5;
  101. 6: tios.c_cflag := tios.c_cflag or CS6;
  102. 7: tios.c_cflag := tios.c_cflag or CS7;
  103. else tios.c_cflag := tios.c_cflag or CS8;
  104. end;
  105. case Parity of
  106. OddParity: tios.c_cflag := tios.c_cflag or PARENB or PARODD;
  107. EvenParity: tios.c_cflag := tios.c_cflag or PARENB;
  108. end;
  109. if StopBits = 2 then
  110. tios.c_cflag := tios.c_cflag or CSTOPB;
  111. if RtsCtsFlowControl in Flags then
  112. tios.c_cflag := tios.c_cflag or CRTSCTS;
  113. tios.c_cflag := tios.c_cflag or CLOCAL or CREAD;
  114. TCSetAttr(handle,TCSANOW,tios)
  115. // ioctl(Handle, TCSETS, @tios);
  116. end;
  117. function SerSaveState(Handle: TSerialHandle): TSerialState;
  118. begin
  119. ioctl(Handle, TIOCMGET, @Result.LineState);
  120. // ioctl(Handle, TCGETS, @Result.tios);
  121. TcGetAttr(handle,result.tios);
  122. end;
  123. procedure SerRestoreState(Handle: TSerialHandle; State: TSerialState);
  124. begin
  125. // ioctl(Handle, TCSETS, @State.tios);
  126. TCSetAttr(handle,TCSANOW,State.tios);
  127. ioctl(Handle, TIOCMSET, @State.LineState);
  128. end;
  129. procedure SerSetDTR(Handle: TSerialHandle; State: Boolean);
  130. const
  131. DTR: Cardinal = TIOCM_DTR;
  132. begin
  133. if State then
  134. ioctl(Handle, TIOCMBIS, @DTR)
  135. else
  136. ioctl(Handle, TIOCMBIC, @DTR);
  137. end;
  138. procedure SerSetRTS(Handle: TSerialHandle; State: Boolean);
  139. const
  140. RTS: Cardinal = TIOCM_RTS;
  141. begin
  142. if State then
  143. ioctl(Handle, TIOCMBIS, @RTS)
  144. else
  145. ioctl(Handle, TIOCMBIC, @RTS);
  146. end;
  147. function SerGetCTS(Handle: TSerialHandle): Boolean;
  148. var
  149. Flags: Cardinal;
  150. begin
  151. ioctl(Handle, TIOCMGET, @Flags);
  152. Result := (Flags and TIOCM_CTS) <> 0;
  153. end;
  154. function SerGetDSR(Handle: TSerialHandle): Boolean;
  155. var
  156. Flags: Cardinal;
  157. begin
  158. ioctl(Handle, TIOCMGET, @Flags);
  159. Result := (Flags and TIOCM_DSR) <> 0;
  160. end;
  161. function SerGetRI(Handle: TSerialHandle): Boolean;
  162. var
  163. Flags: Cardinal;
  164. begin
  165. ioctl(Handle, TIOCMGET, @Flags);
  166. Result := (Flags and TIOCM_RI) <> 0;
  167. end;
  168. end.
  169. {
  170. $Log$
  171. Revision 1.5 2001-01-21 20:21:40 marco
  172. * Rename fest II. Rtl OK
  173. Revision 1.4 2000/12/28 20:50:04 peter
  174. * merged fixes from 1.0.x
  175. Revision 1.3 2000/10/10 14:12:36 sg
  176. * Some cosmetic improvements (no changes in interface, only within the
  177. source itself (comments etc.)
  178. Revision 1.2 2000/09/18 13:14:51 marco
  179. * Global Linux +bsd to (rtl/freebsd rtl/unix rtl/linux structure)
  180. Revision 1.2 2000/07/13 11:33:49 michael
  181. + removed logs
  182. }