* [Ada] Serial port flow control support
@ 2012-08-06 8:36 Arnaud Charlet
0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2012-08-06 8:36 UTC (permalink / raw)
To: gcc-patches; +Cc: Thomas Quinot
[-- Attachment #1: Type: text/plain, Size: 609 bytes --]
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 <quinot@adacore.com>
* g-sercom.adb, g-sercom.ads, g-sercom-mingw.adb, g-sercom-linux.adb
(Set): Add Local and Flow_Control settings.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 10765 bytes --]
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);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-08-06 8:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-06 8:36 [Ada] Serial port flow control support Arnaud Charlet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).