MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Core Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 // Moosserialport.cpp: implementation of the CMOOSLinuxSerialPort class. 00031 // 00033 #include "MOOSGenLibGlobalHelper.h" 00034 #include "MOOSLinuxSerialPort.h" 00035 00036 #include <cstring> 00037 00039 // Construction/Destruction 00041 00043 CMOOSLinuxSerialPort::CMOOSLinuxSerialPort() 00044 { 00045 m_nPortFD = -1; 00046 } 00047 00050 CMOOSLinuxSerialPort::~CMOOSLinuxSerialPort() 00051 { 00052 Close(); 00053 } 00054 00056 bool CMOOSLinuxSerialPort::Create(const char * sPort, int nBaudRate) 00057 { 00058 if (m_nPortFD >= 0) 00059 { 00060 MOOSTrace("Serial Port already open.\n"); 00061 return false; 00062 } 00063 00064 #ifndef _WIN32 00065 int nLinuxBaudRate = B9600; 00066 switch(nBaudRate) 00067 { 00068 #ifdef B500000 00069 case 500000: nLinuxBaudRate = B500000; break; 00070 #endif 00071 case 115200: nLinuxBaudRate = B115200; break; 00072 case 38400: nLinuxBaudRate = B38400; break; 00073 case 19200: nLinuxBaudRate = B19200; break; 00074 case 9600: nLinuxBaudRate = B9600; break; 00075 case 4800: nLinuxBaudRate = B4800; break; 00076 case 2400: nLinuxBaudRate = B2400; break; 00077 case 1200: nLinuxBaudRate = B1200; break; 00078 case 600: nLinuxBaudRate = B600; break; 00079 case 300: nLinuxBaudRate = B300; break; 00080 default : 00081 printf("Unsupported baud rate\n"); 00082 return false; 00083 break; 00084 } 00085 00086 // open and configure the serial port 00087 m_nPortFD = open(sPort, O_RDWR | O_NOCTTY | O_NDELAY); 00088 00089 if (m_nPortFD <0) 00090 { 00091 perror(sPort); 00092 exit(-1); 00093 } 00094 00095 //save the current configuration 00096 tcgetattr(m_nPortFD,&m_OldPortOptions); 00097 00098 //zero the buffers 00099 //bzero(&m_PortOptions, sizeof(m_PortOptions)); 00100 memset(&m_PortOptions,0,sizeof(m_PortOptions)); 00101 m_PortOptions.c_cflag = nLinuxBaudRate | CS8 | CLOCAL | CREAD; 00102 m_PortOptions.c_iflag = IGNPAR; 00103 m_PortOptions.c_oflag = 0; 00104 00105 /* set input mode (non-canonical, no echo,...) */ 00106 m_PortOptions.c_lflag = 0; 00107 00108 // inter-character timer unused 00109 m_PortOptions.c_cc[VTIME] = 0; 00110 // blocking read until 0 chars received, i.e. don't block 00111 m_PortOptions.c_cc[VMIN] = 0; 00112 00113 //save the new settings 00114 tcflush(m_nPortFD, TCIFLUSH); 00115 tcsetattr(m_nPortFD,TCSANOW,&m_PortOptions); 00116 00117 #endif 00118 00119 if(m_nPortFD!=0) 00120 m_sPort = sPort; 00121 00122 return m_nPortFD!=0; 00123 } 00124 00125 00126 00128 int CMOOSLinuxSerialPort::GetFD() 00129 { 00130 return m_nPortFD; 00131 } 00132 00133 00134 int CMOOSLinuxSerialPort::GrabN(char * pBuffer,int nRequired) 00135 { 00136 if (m_nPortFD < 0) 00137 { 00138 MOOSTrace("Can't GrabN because port is not open.\n"); 00139 return 0; 00140 } 00141 00142 #ifndef _WIN32 00143 //lock the port 00144 m_PortLock.Lock(); 00145 int nRead = read(m_nPortFD, pBuffer, nRequired); 00146 //lock the port 00147 m_PortLock.UnLock(); 00148 return nRead; 00149 #else 00150 return 0; 00151 #endif 00152 } 00153 00154 00155 00156 00159 int CMOOSLinuxSerialPort::Write(const char* Str,int nLen,double* pTime) 00160 { 00161 if (m_nPortFD < 0) 00162 { 00163 MOOSTrace("Cannot Write because port is not open.\n"); 00164 return 0; 00165 } 00166 00167 int nChars = 0; 00168 00169 //grab the time.. 00170 if(pTime!=NULL) 00171 { 00172 *pTime = MOOSTime(); 00173 } 00174 00175 //lock the port 00176 m_PortLock.Lock(); 00177 #ifndef _WIN32 00178 nChars = write(m_nPortFD, Str,nLen); 00179 #endif 00180 m_PortLock.UnLock(); 00181 00182 return nChars; 00183 00184 00185 for(int i = 0; i<nLen;i++) 00186 { 00187 #ifndef _WIN32 00188 00189 if(write(m_nPortFD, &Str[i],1)!=1) 00190 { 00191 MOOSTrace("Write Failed\n"); 00192 nChars = -1; 00193 break; 00194 } 00195 else 00196 { 00197 00198 nChars++; 00199 } 00200 #else 00201 00202 #endif 00203 } 00204 00205 m_PortLock.UnLock(); 00206 //how many chars did we write? 00207 00208 return nChars; 00209 } 00210 00214 void CMOOSLinuxSerialPort::Break() 00215 { 00216 00217 if (m_nPortFD < 0) 00218 { 00219 MOOSTrace("Cannot Break because port is not open\n"); 00220 return; 00221 } 00222 00223 //according to http://www.mkssoftware.com/docs/man3/tcsendbreak.3.asp 00224 //a default value of 0 should work fine, sends a break for 250-500ms, 00225 #ifndef _WIN32 00226 tcsendbreak(m_nPortFD, 0); 00227 #endif 00228 } 00229 00236 int CMOOSLinuxSerialPort::Flush() 00237 { 00238 if (m_nPortFD < 0) 00239 { 00240 MOOSTrace("Cannot Flush because port is not open.\n"); 00241 return -1; 00242 } 00243 00244 int nRes = -1; 00245 #ifndef _WIN32 00246 nRes = tcflush(m_nPortFD, TCOFLUSH); 00247 #endif 00248 00249 return nRes; 00250 } 00251 00252 bool CMOOSLinuxSerialPort::Close() 00253 { 00254 if (m_nPortFD < 0) 00255 { 00256 MOOSTrace("Cannot Close because port is not open.\n"); 00257 return false; 00258 } 00259 00260 bool bResult = true; 00261 CMOOSSerialPort::Close(); 00262 00263 #ifndef _WIN32 00264 tcsetattr(m_nPortFD, 00265 TCSANOW, 00266 &m_OldPortOptions); 00267 00268 bResult = close(m_nPortFD)==0; 00269 m_nPortFD = -1; 00270 #endif 00271 00272 return bResult; 00273 }