mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-27 23:31:50 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			233 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| { Unit for handling the serial interfaces for Linux and similar Unices.
 | |
|   (c) 2000 Sebastian Guenther, sg@freepascal.org
 | |
| }
 | |
| 
 | |
| unit Serial;
 | |
| 
 | |
| {$MODE objfpc}
 | |
| {$H+}
 | |
| {$PACKRECORDS C}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses Unix;
 | |
| 
 | |
| type
 | |
| 
 | |
|   TSerialHandle = LongInt;
 | |
| 
 | |
|   TParityType = (NoneParity, OddParity, EvenParity);
 | |
| 
 | |
|   TSerialFlags = set of (RtsCtsFlowControl);
 | |
| 
 | |
|   TSerialState = record
 | |
|     LineState: LongWord;
 | |
|     tios: termios;
 | |
|   end;
 | |
| 
 | |
| 
 | |
| { 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. }
 | |
| procedure SerFlush(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; var Buffer; Count: LongInt): LongInt;
 | |
| 
 | |
| procedure SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
 | |
|   ByteSize: Integer; Parity: TParityType; StopBits: Integer;
 | |
|   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 SerGetRI(Handle: TSerialHandle): Boolean;
 | |
| 
 | |
| 
 | |
| { ************************************************************************** }
 | |
| 
 | |
| implementation
 | |
| 
 | |
| 
 | |
| function SerOpen(const DeviceName: String): TSerialHandle;
 | |
| begin
 | |
|   Result := fdOpen(DeviceName, OPEN_RDWR or OPEN_EXCL or OPEN_NOCTTY);
 | |
| end;
 | |
| 
 | |
| procedure SerClose(Handle: TSerialHandle);
 | |
| begin
 | |
|   fdClose(Handle);
 | |
| end;
 | |
| 
 | |
| procedure SerFlush(Handle: TSerialHandle);
 | |
| begin
 | |
|   fdFlush(Handle);
 | |
| end;
 | |
| 
 | |
| function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
 | |
| begin
 | |
|   Result := fdRead(Handle, Buffer, Count);
 | |
| end;
 | |
| 
 | |
| function SerWrite(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt;
 | |
| begin
 | |
|   Result := fdWrite(Handle, Buffer, Count);
 | |
| end;
 | |
| 
 | |
| procedure SerSetParams(Handle: TSerialHandle; BitsPerSec: LongInt;
 | |
|   ByteSize: Integer; Parity: TParityType; StopBits: Integer;
 | |
|   Flags: TSerialFlags);
 | |
| var
 | |
|   tios: termios;
 | |
| begin
 | |
|   TcGetAttr(handle,tios);
 | |
|  // ioctl(Handle, TCGETS, @tios);
 | |
| 
 | |
|   case BitsPerSec of
 | |
|     50: tios.c_cflag := B50;
 | |
|     75: tios.c_cflag := B75;
 | |
|     110: tios.c_cflag := B110;
 | |
|     134: tios.c_cflag := B134;
 | |
|     150: tios.c_cflag := B150;
 | |
|     200: tios.c_cflag := B200;
 | |
|     300: tios.c_cflag := B300;
 | |
|     600: tios.c_cflag := B600;
 | |
|     1200: tios.c_cflag := B1200;
 | |
|     1800: tios.c_cflag := B1800;
 | |
|     2400: tios.c_cflag := B2400;
 | |
|     4800: tios.c_cflag := B4800;
 | |
|     19200: tios.c_cflag := B19200;
 | |
|     38400: tios.c_cflag := B38400;
 | |
|     57600: tios.c_cflag := B57600;
 | |
|     115200: tios.c_cflag := B115200;
 | |
|     230400: tios.c_cflag := B230400;
 | |
| {$ifndef BSD}
 | |
|     460800: tios.c_cflag := B460800;
 | |
| {$endif}
 | |
|     else tios.c_cflag := B9600;
 | |
|   end;
 | |
| 
 | |
|   case ByteSize of
 | |
|     5: tios.c_cflag := tios.c_cflag or CS5;
 | |
|     6: tios.c_cflag := tios.c_cflag or CS6;
 | |
|     7: tios.c_cflag := tios.c_cflag or CS7;
 | |
|     else tios.c_cflag := tios.c_cflag or CS8;
 | |
|   end;
 | |
| 
 | |
|   case Parity of
 | |
|     OddParity: tios.c_cflag := tios.c_cflag or PARENB or PARODD;
 | |
|     EvenParity: tios.c_cflag := tios.c_cflag or PARENB;
 | |
|   end;
 | |
| 
 | |
|   if StopBits = 2 then
 | |
|     tios.c_cflag := tios.c_cflag or CSTOPB;
 | |
| 
 | |
|   if RtsCtsFlowControl in Flags then
 | |
|     tios.c_cflag := tios.c_cflag or CRTSCTS;
 | |
| 
 | |
|   tios.c_cflag := tios.c_cflag or CLOCAL or CREAD;
 | |
|   TCSetAttr(handle,TCSANOW,tios)
 | |
| //  ioctl(Handle, TCSETS, @tios);
 | |
| end;
 | |
| 
 | |
| function SerSaveState(Handle: TSerialHandle): TSerialState;
 | |
| begin
 | |
|   ioctl(Handle, TIOCMGET, @Result.LineState);
 | |
| //  ioctl(Handle, TCGETS, @Result.tios);
 | |
|   TcGetAttr(handle,result.tios);
 | |
| 
 | |
| end;
 | |
| 
 | |
| procedure SerRestoreState(Handle: TSerialHandle; State: TSerialState);
 | |
| begin
 | |
| //  ioctl(Handle, TCSETS, @State.tios);
 | |
|     TCSetAttr(handle,TCSANOW,State.tios);
 | |
|     ioctl(Handle, TIOCMSET, @State.LineState);
 | |
| end;
 | |
| 
 | |
| procedure SerSetDTR(Handle: TSerialHandle; State: Boolean);
 | |
| const
 | |
|   DTR: Cardinal = TIOCM_DTR;
 | |
| begin
 | |
|   if State then
 | |
|     ioctl(Handle, TIOCMBIS, @DTR)
 | |
|   else
 | |
|     ioctl(Handle, TIOCMBIC, @DTR);
 | |
| end;
 | |
| 
 | |
| procedure SerSetRTS(Handle: TSerialHandle; State: Boolean);
 | |
| const
 | |
|   RTS: Cardinal = TIOCM_RTS;
 | |
| begin
 | |
|   if State then
 | |
|     ioctl(Handle, TIOCMBIS, @RTS)
 | |
|   else
 | |
|     ioctl(Handle, TIOCMBIC, @RTS);
 | |
| end;
 | |
| 
 | |
| function SerGetCTS(Handle: TSerialHandle): Boolean;
 | |
| var
 | |
|   Flags: Cardinal;
 | |
| begin
 | |
|   ioctl(Handle, TIOCMGET, @Flags);
 | |
|   Result := (Flags and TIOCM_CTS) <> 0;
 | |
| end;
 | |
| 
 | |
| function SerGetDSR(Handle: TSerialHandle): Boolean;
 | |
| var
 | |
|   Flags: Cardinal;
 | |
| begin
 | |
|   ioctl(Handle, TIOCMGET, @Flags);
 | |
|   Result := (Flags and TIOCM_DSR) <> 0;
 | |
| end;
 | |
| 
 | |
| function SerGetRI(Handle: TSerialHandle): Boolean;
 | |
| var
 | |
|   Flags: Cardinal;
 | |
| begin
 | |
|   ioctl(Handle, TIOCMGET, @Flags);
 | |
|   Result := (Flags and TIOCM_RI) <> 0;
 | |
| end;
 | |
| 
 | |
| 
 | |
| end.
 | |
| 
 | |
| {
 | |
|   $Log$
 | |
|   Revision 1.5  2001-01-21 20:21:40  marco
 | |
|    * Rename fest II. Rtl OK
 | |
| 
 | |
|   Revision 1.4  2000/12/28 20:50:04  peter
 | |
|     * merged fixes from 1.0.x
 | |
| 
 | |
|   Revision 1.3  2000/10/10 14:12:36  sg
 | |
|   * Some cosmetic improvements (no changes in interface, only within the
 | |
|     source itself (comments etc.)
 | |
| 
 | |
|   Revision 1.2  2000/09/18 13:14:51  marco
 | |
|    * Global Linux +bsd to (rtl/freebsd rtl/unix rtl/linux structure)
 | |
| 
 | |
|   Revision 1.2  2000/07/13 11:33:49  michael
 | |
|   + removed logs
 | |
| 
 | |
| }
 | 
