This change adds two new optional parameters to GNAT.Serial_Comminications.Set to allow the user to specify a local port (no modem control lines), and to choose a flow control method (none, hardware, software). Note that the default behaviour is now consistently no flow control on all platforms. Previously it was the case on Windows only; on Linux, RTS/CTS flow control was always enabled.
Tested on x86_64-pc-linux-gnu, committed on trunk 2012-08-06 Thomas Quinot <qui...@adacore.com> * g-sercom.adb, g-sercom.ads, g-sercom-mingw.adb, g-sercom-linux.adb (Set): Add Local and Flow_Control settings.
Index: g-sercom.adb =================================================================== --- g-sercom.adb (revision 190155) +++ g-sercom.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2007-2010, AdaCore -- +-- Copyright (C) 2007-2012, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -82,6 +82,8 @@ Stop_Bits : Stop_Bits_Number := One; Parity : Parity_Check := None; Block : Boolean := True; + Local : Boolean := True; + Flow : Flow_Control := None; Timeout : Duration := 10.0) is begin Index: g-sercom.ads =================================================================== --- g-sercom.ads (revision 190155) +++ g-sercom.ads (working copy) @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2007-2010, AdaCore -- +-- Copyright (C) 2007-2012, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -62,6 +62,9 @@ type Parity_Check is (None, Even, Odd); -- Either no parity check or an even or odd parity + type Flow_Control is (None, RTS_CTS, Xon_Xoff); + -- No flow control, hardware flow control, software flow control + type Serial_Port is new Ada.Streams.Root_Stream_Type with private; procedure Open @@ -77,13 +80,18 @@ Stop_Bits : Stop_Bits_Number := One; Parity : Parity_Check := None; Block : Boolean := True; + Local : Boolean := True; + Flow : Flow_Control := None; Timeout : Duration := 10.0); -- The communication port settings. If Block is set then a read call -- will wait for the whole buffer to be filed. If Block is not set then - -- the given Timeout (in seconds) is used. Note that the timeout precision - -- may be limited on some implementation (e.g. on GNU/Linux the maximum - -- precision is a tenth of seconds). + -- the given Timeout (in seconds) is used. If Local is set then modem + -- control lines (in particular DCD) are ignored (not supported on + -- Windows). + -- Note that the timeout precision may be limited on some implementation + -- (e.g. on GNU/Linux the maximum precision is a tenth of seconds). + overriding procedure Read (Port : in out Serial_Port; Buffer : out Ada.Streams.Stream_Element_Array; Index: g-sercom-mingw.adb =================================================================== --- g-sercom-mingw.adb (revision 190155) +++ g-sercom-mingw.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2007-2010, AdaCore -- +-- Copyright (C) 2007-2012, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -175,8 +175,12 @@ Stop_Bits : Stop_Bits_Number := One; Parity : Parity_Check := None; Block : Boolean := True; + Local : Boolean := True; + Flow : Flow_Control := None; Timeout : Duration := 10.0) is + pragma Unreferenced (Local); + Success : BOOL; Com_Time_Out : aliased COMMTIMEOUTS; Com_Settings : aliased DCB; @@ -197,13 +201,26 @@ Com_Settings.BaudRate := DWORD (Data_Rate_Value (Rate)); Com_Settings.fParity := 1; Com_Settings.fBinary := Bits1 (System.Win32.TRUE); - Com_Settings.fOutxCtsFlow := 0; Com_Settings.fOutxDsrFlow := 0; Com_Settings.fDsrSensitivity := 0; - Com_Settings.fDtrControl := DTR_CONTROL_DISABLE; - Com_Settings.fOutX := 0; + Com_Settings.fDtrControl := DTR_CONTROL_ENABLE; Com_Settings.fInX := 0; - Com_Settings.fRtsControl := RTS_CONTROL_DISABLE; + Com_Settings.fRtsControl := RTS_CONTROL_ENABLE; + + case Flow is + when None => + Com_Settings.fOutX := 0; + Com_Settings.fOutxCtsFlow := 0; + + when RTS_CTS => + Com_Settings.fOutX := 0; + Com_Settings.fOutxCtsFlow := 1; + + when Xon_Xoff => + Com_Settings.fOutX := 1; + Com_Settings.fOutxCtsFlow := 0; + end case; + Com_Settings.fAbortOnError := 0; Com_Settings.ByteSize := BYTE (C_Bits (Bits)); Com_Settings.Parity := BYTE (C_Parity (Parity)); Index: g-sercom-linux.adb =================================================================== --- g-sercom-linux.adb (revision 190155) +++ g-sercom-linux.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2007-2010, AdaCore -- +-- Copyright (C) 2007-2012, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -38,11 +38,14 @@ with System; use System; with System.Communication; use System.Communication; with System.CRTL; use System.CRTL; +with System.OS_Constants; with GNAT.OS_Lib; use GNAT.OS_Lib; package body GNAT.Serial_Communications is + package OSC renames System.OS_Constants; + use type Interfaces.C.unsigned; type Port_Data is new int; @@ -54,43 +57,26 @@ function fcntl (fd : int; cmd : int; value : int) return int; pragma Import (C, fcntl, "fcntl"); - O_RDWR : constant := 8#02#; - O_NOCTTY : constant := 8#0400#; - O_NDELAY : constant := 8#04000#; - FNDELAY : constant := O_NDELAY; - F_SETFL : constant := 4; - TCSANOW : constant := 0; - TCIFLUSH : constant := 0; - CLOCAL : constant := 8#04000#; - CREAD : constant := 8#0200#; - CSTOPB : constant := 8#0100#; - CRTSCTS : constant := 8#020000000000#; - PARENB : constant := 8#00400#; - PARODD : constant := 8#01000#; - - -- c_cc indexes - - VTIME : constant := 5; - VMIN : constant := 6; - C_Data_Rate : constant array (Data_Rate) of unsigned := - (B1200 => 8#000011#, - B2400 => 8#000013#, - B4800 => 8#000014#, - B9600 => 8#000015#, - B19200 => 8#000016#, - B38400 => 8#000017#, - B57600 => 8#010001#, - B115200 => 8#010002#); + (B1200 => OSC.B1200, + B2400 => OSC.B2400, + B4800 => OSC.B4800, + B9600 => OSC.B9600, + B19200 => OSC.B19200, + B38400 => OSC.B38400, + B57600 => OSC.B57600, + B115200 => OSC.B115200); C_Bits : constant array (Data_Bits) of unsigned := - (CS7 => 8#040#, CS8 => 8#060#); + (CS7 => OSC.CS7, CS8 => OSC.CS8); C_Stop_Bits : constant array (Stop_Bits_Number) of unsigned := - (One => 0, Two => CSTOPB); + (One => 0, Two => OSC.CSTOPB); C_Parity : constant array (Parity_Check) of unsigned := - (None => 0, Odd => PARENB or PARODD, Even => PARENB); + (None => 0, + Odd => OSC.PARENB or OSC.PARODD, + Even => OSC.PARENB); procedure Raise_Error (Message : String; Error : Integer := Errno); pragma No_Return (Raise_Error); @@ -114,6 +100,8 @@ (Port : out Serial_Port; Name : Port_Name) is + use OSC; + C_Name : constant String := String (Name) & ASCII.NUL; Res : int; @@ -184,8 +172,12 @@ Stop_Bits : Stop_Bits_Number := One; Parity : Parity_Check := None; Block : Boolean := True; + Local : Boolean := True; + Flow : Flow_Control := None; Timeout : Duration := 10.0) is + use OSC; + type termios is record c_iflag : unsigned; c_oflag : unsigned; @@ -229,12 +221,24 @@ or C_Bits (Bits) or C_Stop_Bits (Stop_Bits) or C_Parity (Parity) - or CLOCAL - or CREAD - or CRTSCTS; + or CREAD; + Current.c_iflag := 0; Current.c_lflag := 0; - Current.c_iflag := 0; Current.c_oflag := 0; + + if Local then + Current.c_cflag := Current.c_cflag or CLOCAL; + end if; + + case Flow is + when None => + null; + when RTS_CTS => + Current.c_cflag := Current.c_cflag or CRTSCTS; + when Xon_Xoff => + Current.c_iflag := Current.c_iflag or IXON; + end case; + Current.c_ispeed := Data_Rate_Value (Rate); Current.c_ospeed := Data_Rate_Value (Rate); Current.c_cc (VMIN) := char'Val (0);