annotate gcc/ada/libgnat/g-sercom__linux.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- G N A T . S E R I A L _ C O M M U N I C A T I O N S --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 2007-2018, AdaCore --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- This is the GNU/Linux implementation of this package
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 with Ada.Streams; use Ada.Streams;
kono
parents:
diff changeset
35 with Ada; use Ada;
kono
parents:
diff changeset
36 with Ada.Unchecked_Deallocation;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 with System; use System;
kono
parents:
diff changeset
39 with System.Communication; use System.Communication;
kono
parents:
diff changeset
40 with System.CRTL; use System.CRTL;
kono
parents:
diff changeset
41 with System.OS_Constants;
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 with GNAT.OS_Lib; use GNAT.OS_Lib;
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 package body GNAT.Serial_Communications is
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 package OSC renames System.OS_Constants;
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 use type Interfaces.C.unsigned;
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 type Port_Data is new int;
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 subtype unsigned is Interfaces.C.unsigned;
kono
parents:
diff changeset
54 subtype char is Interfaces.C.char;
kono
parents:
diff changeset
55 subtype unsigned_char is Interfaces.C.unsigned_char;
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 function fcntl (fd : int; cmd : int; value : int) return int;
kono
parents:
diff changeset
58 pragma Import (C, fcntl, "fcntl");
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 C_Data_Rate : constant array (Data_Rate) of unsigned :=
kono
parents:
diff changeset
61 (B75 => OSC.B75,
kono
parents:
diff changeset
62 B110 => OSC.B110,
kono
parents:
diff changeset
63 B150 => OSC.B150,
kono
parents:
diff changeset
64 B300 => OSC.B300,
kono
parents:
diff changeset
65 B600 => OSC.B600,
kono
parents:
diff changeset
66 B1200 => OSC.B1200,
kono
parents:
diff changeset
67 B2400 => OSC.B2400,
kono
parents:
diff changeset
68 B4800 => OSC.B4800,
kono
parents:
diff changeset
69 B9600 => OSC.B9600,
kono
parents:
diff changeset
70 B19200 => OSC.B19200,
kono
parents:
diff changeset
71 B38400 => OSC.B38400,
kono
parents:
diff changeset
72 B57600 => OSC.B57600,
kono
parents:
diff changeset
73 B115200 => OSC.B115200);
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 C_Bits : constant array (Data_Bits) of unsigned :=
kono
parents:
diff changeset
76 (CS7 => OSC.CS7, CS8 => OSC.CS8);
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 C_Stop_Bits : constant array (Stop_Bits_Number) of unsigned :=
kono
parents:
diff changeset
79 (One => 0, Two => OSC.CSTOPB);
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 C_Parity : constant array (Parity_Check) of unsigned :=
kono
parents:
diff changeset
82 (None => 0,
kono
parents:
diff changeset
83 Odd => OSC.PARENB or OSC.PARODD,
kono
parents:
diff changeset
84 Even => OSC.PARENB);
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 procedure Raise_Error (Message : String; Error : Integer := Errno);
kono
parents:
diff changeset
87 pragma No_Return (Raise_Error);
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 ----------
kono
parents:
diff changeset
90 -- Name --
kono
parents:
diff changeset
91 ----------
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 function Name (Number : Positive) return Port_Name is
kono
parents:
diff changeset
94 N : constant Natural := Number - 1;
kono
parents:
diff changeset
95 N_Img : constant String := Natural'Image (N);
kono
parents:
diff changeset
96 begin
kono
parents:
diff changeset
97 return Port_Name ("/dev/ttyS" & N_Img (N_Img'First + 1 .. N_Img'Last));
kono
parents:
diff changeset
98 end Name;
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 ----------
kono
parents:
diff changeset
101 -- Open --
kono
parents:
diff changeset
102 ----------
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 procedure Open
kono
parents:
diff changeset
105 (Port : out Serial_Port;
kono
parents:
diff changeset
106 Name : Port_Name)
kono
parents:
diff changeset
107 is
kono
parents:
diff changeset
108 use OSC;
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 C_Name : constant String := String (Name) & ASCII.NUL;
kono
parents:
diff changeset
111 Res : int;
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 begin
kono
parents:
diff changeset
114 if Port.H = null then
kono
parents:
diff changeset
115 Port.H := new Port_Data;
kono
parents:
diff changeset
116 end if;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 Port.H.all := Port_Data (open
kono
parents:
diff changeset
119 (C_Name (C_Name'First)'Address, int (O_RDWR + O_NOCTTY + O_NDELAY)));
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 if Port.H.all = -1 then
kono
parents:
diff changeset
122 Raise_Error ("open: open failed");
kono
parents:
diff changeset
123 end if;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 -- By default we are in blocking mode
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 Res := fcntl (int (Port.H.all), F_SETFL, 0);
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 if Res = -1 then
kono
parents:
diff changeset
130 Raise_Error ("open: fcntl failed");
kono
parents:
diff changeset
131 end if;
kono
parents:
diff changeset
132 end Open;
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 -----------------
kono
parents:
diff changeset
135 -- Raise_Error --
kono
parents:
diff changeset
136 -----------------
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 procedure Raise_Error (Message : String; Error : Integer := Errno) is
kono
parents:
diff changeset
139 begin
kono
parents:
diff changeset
140 raise Serial_Error with Message
kono
parents:
diff changeset
141 & (if Error /= 0
kono
parents:
diff changeset
142 then " (" & Errno_Message (Err => Error) & ')'
kono
parents:
diff changeset
143 else "");
kono
parents:
diff changeset
144 end Raise_Error;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 ----------
kono
parents:
diff changeset
147 -- Read --
kono
parents:
diff changeset
148 ----------
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 overriding procedure Read
kono
parents:
diff changeset
151 (Port : in out Serial_Port;
kono
parents:
diff changeset
152 Buffer : out Stream_Element_Array;
kono
parents:
diff changeset
153 Last : out Stream_Element_Offset)
kono
parents:
diff changeset
154 is
kono
parents:
diff changeset
155 Len : constant size_t := Buffer'Length;
kono
parents:
diff changeset
156 Res : ssize_t;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 begin
kono
parents:
diff changeset
159 if Port.H = null then
kono
parents:
diff changeset
160 Raise_Error ("read: port not opened", 0);
kono
parents:
diff changeset
161 end if;
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 Res := read (Integer (Port.H.all), Buffer'Address, Len);
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 if Res = -1 then
kono
parents:
diff changeset
166 Raise_Error ("read failed");
kono
parents:
diff changeset
167 end if;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 Last := Last_Index (Buffer'First, size_t (Res));
kono
parents:
diff changeset
170 end Read;
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 ---------
kono
parents:
diff changeset
173 -- Set --
kono
parents:
diff changeset
174 ---------
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 procedure Set
kono
parents:
diff changeset
177 (Port : Serial_Port;
kono
parents:
diff changeset
178 Rate : Data_Rate := B9600;
kono
parents:
diff changeset
179 Bits : Data_Bits := CS8;
kono
parents:
diff changeset
180 Stop_Bits : Stop_Bits_Number := One;
kono
parents:
diff changeset
181 Parity : Parity_Check := None;
kono
parents:
diff changeset
182 Block : Boolean := True;
kono
parents:
diff changeset
183 Local : Boolean := True;
kono
parents:
diff changeset
184 Flow : Flow_Control := None;
kono
parents:
diff changeset
185 Timeout : Duration := 10.0)
kono
parents:
diff changeset
186 is
kono
parents:
diff changeset
187 use OSC;
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 type termios is record
kono
parents:
diff changeset
190 c_iflag : unsigned;
kono
parents:
diff changeset
191 c_oflag : unsigned;
kono
parents:
diff changeset
192 c_cflag : unsigned;
kono
parents:
diff changeset
193 c_lflag : unsigned;
kono
parents:
diff changeset
194 c_line : unsigned_char;
kono
parents:
diff changeset
195 c_cc : Interfaces.C.char_array (0 .. 31);
kono
parents:
diff changeset
196 c_ispeed : unsigned;
kono
parents:
diff changeset
197 c_ospeed : unsigned;
kono
parents:
diff changeset
198 end record;
kono
parents:
diff changeset
199 pragma Convention (C, termios);
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 function tcgetattr (fd : int; termios_p : Address) return int;
kono
parents:
diff changeset
202 pragma Import (C, tcgetattr, "tcgetattr");
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 function tcsetattr
kono
parents:
diff changeset
205 (fd : int; action : int; termios_p : Address) return int;
kono
parents:
diff changeset
206 pragma Import (C, tcsetattr, "tcsetattr");
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 function tcflush (fd : int; queue_selector : int) return int;
kono
parents:
diff changeset
209 pragma Import (C, tcflush, "tcflush");
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 Current : termios;
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 Res : int;
kono
parents:
diff changeset
214 pragma Warnings (Off, Res);
kono
parents:
diff changeset
215 -- Warnings off, since we don't always test the result
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 begin
kono
parents:
diff changeset
218 if Port.H = null then
kono
parents:
diff changeset
219 Raise_Error ("set: port not opened", 0);
kono
parents:
diff changeset
220 end if;
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 -- Get current port settings
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 Res := tcgetattr (int (Port.H.all), Current'Address);
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 -- Change settings now
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 Current.c_cflag := C_Data_Rate (Rate)
kono
parents:
diff changeset
229 or C_Bits (Bits)
kono
parents:
diff changeset
230 or C_Stop_Bits (Stop_Bits)
kono
parents:
diff changeset
231 or C_Parity (Parity)
kono
parents:
diff changeset
232 or CREAD;
kono
parents:
diff changeset
233 Current.c_iflag := 0;
kono
parents:
diff changeset
234 Current.c_lflag := 0;
kono
parents:
diff changeset
235 Current.c_oflag := 0;
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 if Local then
kono
parents:
diff changeset
238 Current.c_cflag := Current.c_cflag or CLOCAL;
kono
parents:
diff changeset
239 end if;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 case Flow is
kono
parents:
diff changeset
242 when None =>
kono
parents:
diff changeset
243 null;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 when RTS_CTS =>
kono
parents:
diff changeset
246 Current.c_cflag := Current.c_cflag or CRTSCTS;
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 when Xon_Xoff =>
kono
parents:
diff changeset
249 Current.c_iflag := Current.c_iflag or IXON;
kono
parents:
diff changeset
250 end case;
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 Current.c_ispeed := Data_Rate_Value (Rate);
kono
parents:
diff changeset
253 Current.c_ospeed := Data_Rate_Value (Rate);
kono
parents:
diff changeset
254 Current.c_cc (VMIN) := char'Val (0);
kono
parents:
diff changeset
255 Current.c_cc (VTIME) := char'Val (Natural (Timeout * 10));
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 -- Set port settings
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 Res := tcflush (int (Port.H.all), TCIFLUSH);
kono
parents:
diff changeset
260 Res := tcsetattr (int (Port.H.all), TCSANOW, Current'Address);
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 -- Block
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 Res := fcntl (int (Port.H.all), F_SETFL, (if Block then 0 else FNDELAY));
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 if Res = -1 then
kono
parents:
diff changeset
267 Raise_Error ("set: fcntl failed");
kono
parents:
diff changeset
268 end if;
kono
parents:
diff changeset
269 end Set;
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 -----------
kono
parents:
diff changeset
272 -- Write --
kono
parents:
diff changeset
273 -----------
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 overriding procedure Write
kono
parents:
diff changeset
276 (Port : in out Serial_Port;
kono
parents:
diff changeset
277 Buffer : Stream_Element_Array)
kono
parents:
diff changeset
278 is
kono
parents:
diff changeset
279 Len : constant size_t := Buffer'Length;
kono
parents:
diff changeset
280 Res : ssize_t;
kono
parents:
diff changeset
281
kono
parents:
diff changeset
282 begin
kono
parents:
diff changeset
283 if Port.H = null then
kono
parents:
diff changeset
284 Raise_Error ("write: port not opened", 0);
kono
parents:
diff changeset
285 end if;
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 Res := write (int (Port.H.all), Buffer'Address, Len);
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 if Res = -1 then
kono
parents:
diff changeset
290 Raise_Error ("write failed");
kono
parents:
diff changeset
291 end if;
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 pragma Assert (size_t (Res) = Len);
kono
parents:
diff changeset
294 end Write;
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 -----------
kono
parents:
diff changeset
297 -- Close --
kono
parents:
diff changeset
298 -----------
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 procedure Close (Port : in out Serial_Port) is
kono
parents:
diff changeset
301 procedure Unchecked_Free is
kono
parents:
diff changeset
302 new Unchecked_Deallocation (Port_Data, Port_Data_Access);
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Res : int;
kono
parents:
diff changeset
305 pragma Unreferenced (Res);
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 begin
kono
parents:
diff changeset
308 if Port.H /= null then
kono
parents:
diff changeset
309 Res := close (int (Port.H.all));
kono
parents:
diff changeset
310 Unchecked_Free (Port.H);
kono
parents:
diff changeset
311 end if;
kono
parents:
diff changeset
312 end Close;
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 end GNAT.Serial_Communications;