serial.pp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 BaseUnix,termio,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 := fpopen(DeviceName, O_RDWR or O_NOCTTY);
  51. end;
  52. procedure SerClose(Handle: TSerialHandle);
  53. begin
  54. fpClose(Handle);
  55. end;
  56. procedure SerFlush(Handle: TSerialHandle);
  57. begin
  58. fsync(Handle);
  59. end;
  60. function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  61. begin
  62. Result := fpRead(Handle, Buffer, Count);
  63. end;
  64. function SerWrite(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
  65. begin
  66. Result := fpWrite(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. FillChar(tios, SizeOf(tios), #0);
  75. case BitsPerSec of
  76. 50: tios.c_cflag := B50;
  77. 75: tios.c_cflag := B75;
  78. 110: tios.c_cflag := B110;
  79. 134: tios.c_cflag := B134;
  80. 150: tios.c_cflag := B150;
  81. 200: tios.c_cflag := B200;
  82. 300: tios.c_cflag := B300;
  83. 600: tios.c_cflag := B600;
  84. 1200: tios.c_cflag := B1200;
  85. 1800: tios.c_cflag := B1800;
  86. 2400: tios.c_cflag := B2400;
  87. 4800: tios.c_cflag := B4800;
  88. 19200: tios.c_cflag := B19200;
  89. 38400: tios.c_cflag := B38400;
  90. 57600: tios.c_cflag := B57600;
  91. 115200: tios.c_cflag := B115200;
  92. 230400: tios.c_cflag := B230400;
  93. {$ifndef BSD}
  94. 460800: tios.c_cflag := B460800;
  95. {$endif}
  96. else tios.c_cflag := B9600;
  97. end;
  98. tios.c_ispeed := tios.c_cflag;
  99. tios.c_ospeed := tios.c_ispeed;
  100. tios.c_cflag := tios.c_cflag or CREAD or CLOCAL;
  101. case ByteSize of
  102. 5: tios.c_cflag := tios.c_cflag or CS5;
  103. 6: tios.c_cflag := tios.c_cflag or CS6;
  104. 7: tios.c_cflag := tios.c_cflag or CS7;
  105. else tios.c_cflag := tios.c_cflag or CS8;
  106. end;
  107. case Parity of
  108. OddParity: tios.c_cflag := tios.c_cflag or PARENB or PARODD;
  109. EvenParity: tios.c_cflag := tios.c_cflag or PARENB;
  110. end;
  111. if StopBits = 2 then
  112. tios.c_cflag := tios.c_cflag or CSTOPB;
  113. if RtsCtsFlowControl in Flags then
  114. tios.c_cflag := tios.c_cflag or CRTSCTS;
  115. tcflush(Handle, TCIOFLUSH);
  116. tcsetattr(Handle, TCSANOW, tios)
  117. end;
  118. function SerSaveState(Handle: TSerialHandle): TSerialState;
  119. begin
  120. fpioctl(Handle, TIOCMGET, @Result.LineState);
  121. // fpioctl(Handle, TCGETS, @Result.tios);
  122. TcGetAttr(handle,result.tios);
  123. end;
  124. procedure SerRestoreState(Handle: TSerialHandle; State: TSerialState);
  125. begin
  126. // fpioctl(Handle, TCSETS, @State.tios);
  127. TCSetAttr(handle,TCSANOW,State.tios);
  128. fpioctl(Handle, TIOCMSET, @State.LineState);
  129. end;
  130. procedure SerSetDTR(Handle: TSerialHandle; State: Boolean);
  131. const
  132. DTR: Cardinal = TIOCM_DTR;
  133. begin
  134. if State then
  135. fpioctl(Handle, TIOCMBIS, @DTR)
  136. else
  137. fpioctl(Handle, TIOCMBIC, @DTR);
  138. end;
  139. procedure SerSetRTS(Handle: TSerialHandle; State: Boolean);
  140. const
  141. RTS: Cardinal = TIOCM_RTS;
  142. begin
  143. if State then
  144. fpioctl(Handle, TIOCMBIS, @RTS)
  145. else
  146. fpioctl(Handle, TIOCMBIC, @RTS);
  147. end;
  148. function SerGetCTS(Handle: TSerialHandle): Boolean;
  149. var
  150. Flags: Cardinal;
  151. begin
  152. fpioctl(Handle, TIOCMGET, @Flags);
  153. Result := (Flags and TIOCM_CTS) <> 0;
  154. end;
  155. function SerGetDSR(Handle: TSerialHandle): Boolean;
  156. var
  157. Flags: Cardinal;
  158. begin
  159. fpioctl(Handle, TIOCMGET, @Flags);
  160. Result := (Flags and TIOCM_DSR) <> 0;
  161. end;
  162. function SerGetRI(Handle: TSerialHandle): Boolean;
  163. var
  164. Flags: Cardinal;
  165. begin
  166. fpioctl(Handle, TIOCMGET, @Flags);
  167. Result := (Flags and TIOCM_RI) <> 0;
  168. end;
  169. end.