1 // serial.cxx -- Unix serial I/O support
3 // Written by Curtis Olson, started November 1998.
5 // Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 // (Log is kept at end of this file)
27 #include <sys/types.h>
32 #include <Debug/logstream.hxx>
37 fgSERIAL::fgSERIAL() {
41 fgSERIAL::fgSERIAL(const string& device, int baud) {
49 fgSERIAL::~fgSERIAL() {
50 // closing the port here screws us up because if we would even so
51 // much as make a copy of an fgSERIAL object and then delete it,
52 // the file descriptor gets closed. Doh!!!
57 bool fgSERIAL::open_port(const string& device) {
58 struct termios config;
60 fd = open(device.c_str(), O_RDWR | O_NONBLOCK);
61 cout << "Serial fd created = " << fd << endl;
64 FG_LOG( FG_SERIAL, FG_ALERT, "Cannot open " << device
65 << " for serial I/O" );
71 // set required port parameters
72 if ( tcgetattr( fd, &config ) != 0 ) {
73 FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
77 // cfmakeraw( &config );
79 // cout << "config.c_iflag = " << config.c_iflag << endl;
81 // software flow control on
82 config.c_iflag |= IXON;
83 // config.c_iflag |= IXOFF;
85 // config.c_cflag |= CLOCAL;
88 // disable hardware flow control
89 config.c_cflag &= ~(CRTSCTS);
92 // cout << "config.c_iflag = " << config.c_iflag << endl;
94 if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
95 FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
103 bool fgSERIAL::close_port() {
109 bool fgSERIAL::set_baud(int baud) {
110 struct termios config;
111 speed_t speed = B9600;
113 if ( tcgetattr( fd, &config ) != 0 ) {
114 FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
120 } else if ( baud == 1200 ) {
122 } else if ( baud == 2400 ) {
124 } else if ( baud == 4800 ) {
126 } else if ( baud == 9600 ) {
128 } else if ( baud == 19200 ) {
130 } else if ( baud == 38400 ) {
132 } else if ( baud == 57600 ) {
134 } else if ( baud == 115200 ) {
136 #if defined( linux ) || defined( __FreeBSD__ )
137 } else if ( baud == 230400 ) {
141 FG_LOG( FG_SERIAL, FG_ALERT, "Unsupported baud rate " << baud );
145 if ( cfsetispeed( &config, speed ) != 0 ) {
146 FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting input baud rate" );
150 if ( cfsetospeed( &config, speed ) != 0 ) {
151 FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting output baud rate" );
155 if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
156 FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
163 string fgSERIAL::read_port() {
164 const int max_count = 1024;
165 char buffer[max_count+1];
169 count = read(fd, buffer, max_count);
170 // cout << "read " << count << " bytes" << endl;
174 if ( errno != EAGAIN ) {
175 FG_LOG( FG_SERIAL, FG_ALERT,
176 "Serial I/O on read, error number = " << errno );
181 buffer[count] = '\0';
188 int fgSERIAL::write_port(const string& value) {
191 count = write(fd, value.c_str(), value.length());
192 // cout << "write '" << value << "' " << count << " bytes" << endl;
194 if ( (int)count != (int)value.length() ) {
195 if ( errno == EAGAIN ) {
196 // ok ... in our context we don't really care if we can't
197 // write a string, we'll just get it the next time around
199 FG_LOG( FG_SERIAL, FG_ALERT,
200 "Serial I/O on write, error number = " << errno );
209 // Revision 1.7 1998/12/04 01:24:35 curt
210 // Tweak for SGI portability.
212 // Revision 1.6 1998/11/30 17:15:29 curt
213 // Having the class destructor close the fd was a bad idea ... especially if you
214 // ever make a copy of the instance and then subsequently destroy either.
215 // close_port() is now a separate member function.
217 // Revision 1.5 1998/11/25 01:33:23 curt
218 // Remove call to cfmakeraw()
220 // Revision 1.4 1998/11/23 21:47:00 curt
221 // Cygnus tools compatibility tweaks.
223 // Revision 1.3 1998/11/19 13:52:54 curt
224 // port configuration tweaks & experiments.
226 // Revision 1.2 1998/11/19 03:35:43 curt
229 // Revision 1.1 1998/11/16 13:53:02 curt