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 #ifdef _WIN32 00031 #pragma warning(disable : 4786) 00032 #endif 00033 00034 00035 // Serial.h - Definition of the CNTSerial class 00036 // 00037 // Copyright (C) 1999-2001 Ramon de Klein (R.de.Klein@iaf.nl) 00038 // 00039 // This program is free software; you can redistribute it and/ormodify 00040 // it under the terms of the GNU General Public License as published by 00041 // the Free Software Foundation; either version 2 of the License, or 00042 // (at your option) any later version. 00043 // 00044 // This program is distributed in the hope that it will be useful, 00045 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00046 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00047 // GNU General Public License for more details. 00048 // 00049 // You should have received a copy of the GNU General Public License 00050 // along with this program; if not, write to the Free Software 00051 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00052 00053 00054 #ifndef __SERIAL_H 00055 #define __SERIAL_H 00056 00057 00059 // 00060 // CNTSerial - Win32 wrapper for serial communications 00061 // 00062 // Serial communication often causes a lot of problems. This class 00063 // tries to supply an easy to use interface to deal with serial 00064 // devices. 00065 // 00066 // The class is actually pretty ease to use. You only need to open 00067 // the COM-port, where you need to specify the basic serial 00068 // communication parameters. You can also choose to setup handshaking 00069 // and read timeout behaviour. 00070 // 00071 // The following serial classes are available: 00072 // 00073 // CNTSerial - Serial communication support. 00074 // CNTSerialWnd - Asynchronous serial support, which uses the Win32 00075 // message queue for event notification. This is often 00076 // preferred in GUI applications. 00077 // CNTSerialMFC - Preferred class to use in MFC-based GUI threads. 00078 // 00079 // 00080 // Pros: 00081 // ----- 00082 // - Easy to use (hides a lot of nasty Win32 stuff) 00083 // - Fully ANSI and Unicode aware 00084 // 00085 // Cons: 00086 // ----- 00087 // - Little less flexibility then native Win32 API, however you can 00088 // use this API at the same time for features which are missing 00089 // from this class. 00090 // - Incompatible with Windows 95 or Windows NT v3.51 (or earlier), 00091 // because CancelIo isn't support on these platforms. 00092 // 00093 // 00094 // Copyright (C) 1999-2001 Ramon de Klein 00095 // (R.de.Klein@iaf.nl) 00096 #include "MOOSSerialPort.h" 00098 class CNTSerial : public CMOOSSerialPort 00099 { 00100 // Class enumerations 00101 public: 00102 // Communication event 00103 typedef enum 00104 { 00105 EEventNone = -1, // Event trigged without cause 00106 EEventBreak = EV_BREAK, // A break was detected on input 00107 EEventCTS = EV_CTS, // The CTS signal changed state 00108 EEventDSR = EV_DSR, // The DSR signal changed state 00109 EEventError = EV_ERR, // A line-status error occurred 00110 EEventRing = EV_RING, // A ring indicator was detected 00111 EEventRLSD = EV_RLSD, // The RLSD signal changed state 00112 EEventRecv = EV_RXCHAR, // Data is received on input 00113 EEventRcvEv = EV_RXFLAG, // Event character was received on input 00114 EEventSend = EV_TXEMPTY, // Last character on output was sent 00115 } 00116 EEvent; 00117 00118 // Baudrate 00119 typedef enum 00120 { 00121 EBaudUnknown = -1, // Unknown 00122 EBaud110 = CBR_110, // 110 bits/sec 00123 EBaud300 = CBR_300, // 300 bits/sec 00124 EBaud600 = CBR_600, // 600 bits/sec 00125 EBaud1200 = CBR_1200, // 1200 bits/sec 00126 EBaud2400 = CBR_2400, // 2400 bits/sec 00127 EBaud4800 = CBR_4800, // 4800 bits/sec 00128 EBaud9600 = CBR_9600, // 9600 bits/sec 00129 EBaud14400 = CBR_14400, // 14400 bits/sec 00130 EBaud19200 = CBR_19200, // 19200 bits/sec (default) 00131 EBaud38400 = CBR_38400, // 38400 bits/sec 00132 EBaud56000 = CBR_56000, // 56000 bits/sec 00133 EBaud57600 = CBR_57600, // 57600 bits/sec 00134 EBaud115200 = CBR_115200, // 115200 bits/sec 00135 EBaud128000 = CBR_128000, // 128000 bits/sec 00136 EBaud256000 = CBR_256000, // 256000 bits/sec 00137 EBaud500000 = 500000, // 500000 bits/sec 00138 00139 // Added by ARH 14/05/2005 for use with 00140 // the 500kBps CSM SIO PCMCIA serial card 00141 // It has a non-standard crystal, so baud rates 00142 // are set differently 00143 EBaudCSM9600 = 2150, 00144 EBaudCSM19200 = 4301, 00145 EBaudCSM38400 = 8602, 00146 EBaudCSM500000 = 115000 00147 } 00148 EBaudrate; 00149 00150 // Data bits (5-8) 00151 typedef enum 00152 { 00153 EDataUnknown = -1, // Unknown 00154 EData5 = 5, // 5 bits per byte 00155 EData6 = 6, // 6 bits per byte 00156 EData7 = 7, // 7 bits per byte 00157 EData8 = 8 // 8 bits per byte (default) 00158 } 00159 EDataBits; 00160 00161 // Parity scheme 00162 typedef enum 00163 { 00164 EParUnknown = -1, // Unknown 00165 EParNone = NOPARITY, // No parity (default) 00166 EParOdd = ODDPARITY, // Odd parity 00167 EParEven = EVENPARITY, // Even parity 00168 EParMark = MARKPARITY, // Mark parity 00169 EParSpace = SPACEPARITY // Space parity 00170 } 00171 EParity; 00172 00173 // Stop bits 00174 typedef enum 00175 { 00176 EStopUnknown = -1, // Unknown 00177 EStop1 = ONESTOPBIT, // 1 stopbit (default) 00178 EStop1_5 = ONE5STOPBITS,// 1.5 stopbit 00179 EStop2 = TWOSTOPBITS // 2 stopbits 00180 } 00181 EStopBits; 00182 00183 // Handshaking 00184 typedef enum 00185 { 00186 EHandshakeUnknown = -1, // Unknown 00187 EHandshakeOff = 0, // No handshaking 00188 EHandshakeHardware = 1, // Hardware handshaking (RTS/CTS) 00189 EHandshakeSoftware = 2 // Software handshaking (XON/XOFF) 00190 } 00191 EHandshake; 00192 00193 // Timeout settings 00194 typedef enum 00195 { 00196 EReadTimeoutUnknown = -1, // Unknown 00197 EReadTimeoutNonblocking = 0, // Always return immediately 00198 EReadTimeoutBlocking = 1 // Block until everything is retrieved 00199 } 00200 EReadTimeout; 00201 00202 // Communication errors 00203 typedef enum 00204 { 00205 EErrorUnknown = 0, // Unknown 00206 EErrorBreak = CE_BREAK, // Break condition detected 00207 EErrorFrame = CE_FRAME, // Framing error 00208 EErrorIOE = CE_IOE, // I/O device error 00209 EErrorMode = CE_MODE, // Unsupported mode 00210 EErrorOverrun = CE_OVERRUN, // Character buffer overrun, next byte is lost 00211 EErrorRxOver = CE_RXOVER, // Input buffer overflow, byte lost 00212 EErrorParity = CE_RXPARITY,// Input parity error 00213 EErrorTxFull = CE_TXFULL // Output buffer full 00214 } 00215 EError; 00216 00217 // Port availability 00218 typedef enum 00219 { 00220 EPortUnknownError = -1, // Unknown error occurred 00221 EPortAvailable = 0, // Port is available 00222 EPortNotAvailable = 1, // Port is not present 00223 EPortInUse = 2 // Port is in use 00224 00225 } 00226 EPort; 00227 00228 // Construction 00229 public: 00230 CNTSerial(); 00231 virtual ~CNTSerial(); 00232 00233 // Operations 00234 public: 00235 // Check if pareticular COM-port is available. 00236 EPort CheckPort (LPCTSTR lpszDevice); 00237 00238 // Open the serial communications for a particular COM port. You 00239 // need to use the full devicename (i.e. "COM1") to open the port. 00240 // It's possible to specify the size of the input/output queues. 00241 virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 2048, DWORD dwOutQueue = 2048); 00242 00243 // Close the serial port. 00244 virtual LONG ClosePort (void); 00245 00246 // Setup the communication settings such as baudrate, databits, 00247 // parity and stopbits. The default settings are applied when the 00248 // device has been opened. Call this function if these settings do 00249 // not apply for your application. If you prefer to use integers 00250 // instead of the enumerated types then just cast the integer to 00251 // the required type. So the following two initializations are 00252 // equivalent: 00253 // 00254 // Setup(EBaud9600,EData8,EParNone,EStop1) 00255 // 00256 // or 00257 // 00258 // Setup(EBaudrate(9600),EDataBits(8),EParity(NOPARITY),EStopBits(ONESTOPBIT)) 00259 // 00260 // In the latter case, the types are not validated. So make sure 00261 // that you specify the appropriate values. 00262 virtual LONG Setup (EBaudrate eBaudrate = EBaud9600, 00263 EDataBits eDataBits = EData8, 00264 EParity eParity = EParNone, 00265 EStopBits eStopBits = EStop1); 00266 00267 // Set/clear the event character. When this byte is being received 00268 // on the serial port then the EEventRcvEv event is signalled, 00269 // when the mask has been set appropriately. If the fAdjustMask flag 00270 // has been set, then the event mask is automatically adjusted. 00271 virtual LONG SetEventChar (BYTE bEventChar, bool fAdjustMask = true); 00272 00273 // Set the event mask, which indicates what events should be 00274 // monitored. The WaitEvent method can only monitor events that 00275 // have been enabled. The default setting only monitors the 00276 // error events and data events. An application may choose to 00277 // monitor CTS. DSR, RLSD, etc as well. 00278 virtual LONG SetMask (DWORD dwMask = EEventBreak|EEventError|EEventRecv); 00279 00280 // The WaitEvent method waits for one of the events that are 00281 // enabled (see SetMask). 00282 virtual LONG WaitEvent (LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE); 00283 00284 // Setup the handshaking protocol. There are three forms of 00285 // handshaking: 00286 // 00287 // 1) No handshaking, so data is always send even if the receiver 00288 // cannot handle the data anymore. This can lead to data loss, 00289 // when the sender is able to transmit data faster then the 00290 // receiver can handle. 00291 // 2) Hardware handshaking, where the RTS/CTS lines are used to 00292 // indicate if data can be sent. This mode requires that both 00293 // ports and the cable support hardware handshaking. Hardware 00294 // handshaking is the most reliable and efficient form of 00295 // handshaking available, but is hardware dependant. 00296 // 3) Software handshaking, where the XON/XOFF characters are used 00297 // to throttle the data. A major drawback of this method is that 00298 // these characters cannot be used for data anymore. 00299 virtual LONG SetupHandshaking (EHandshake eHandshake); 00300 00301 // Read operations can be blocking or non-blocking. You can use 00302 // this method to setup wether to use blocking or non-blocking 00303 // reads. Non-blocking reads is the default, which is required 00304 // for most applications. 00305 // 00306 // 1) Blocking reads, which will cause the 'Read' method to block 00307 // until the requested number of bytes have been read. This is 00308 // useful if you know how many data you will receive. 00309 // 2) Non-blocking reads, which will read as many bytes into your 00310 // buffer and returns almost immediately. This is often the 00311 // preferred setting. 00312 virtual LONG SetupReadTimeouts (EReadTimeout eReadTimeout); 00313 00314 // Obtain communication settings 00315 virtual EBaudrate GetBaudrate (void); 00316 virtual EDataBits GetDataBits (void); 00317 virtual EParity GetParity (void); 00318 virtual EStopBits GetStopBits (void); 00319 virtual EHandshake GetHandshaking (void); 00320 virtual DWORD GetEventMask (void); 00321 virtual BYTE GetEventChar (void); 00322 00323 // Write data to the serial port. Note that we are only able to 00324 // send ANSI strings, because it probably doesn't make sense to 00325 // transmit Unicode strings to an application. 00326 virtual LONG Write (const void* pData, size_t iLen, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE); 00327 virtual LONG Write (LPCSTR pString, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE); 00328 00329 // Read data from the serial port. Refer to the description of 00330 // the 'SetupReadTimeouts' for an explanation about (non) blocking 00331 // reads and how to use this. 00332 virtual LONG NTRead (void* pData, size_t iLen, DWORD* pdwRead = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE); 00333 00334 // Determine what caused the event to trigger 00335 EEvent GetEventType (void); 00336 00337 // Obtain the error 00338 EError GetError (void); 00339 00340 // Obtain the COMM and event handle 00341 HANDLE GetCommHandle (void) { return m_hFile; } 00342 00343 // Check if com-port is opened 00344 bool IsOpen (void) const { return (m_hFile != 0); } 00345 00346 // Obtain last error status 00347 LONG GetLastError (void) const { return m_lLastError; } 00348 00349 // Obtain CTS/DSR/RING/RLSD settings 00350 bool GetCTS (void); 00351 bool GetDSR (void); 00352 bool GetRing (void); 00353 bool GetRLSD (void); 00354 00355 // Flush all buffers 00356 virtual int Flush (void); 00357 00358 protected: 00359 // Internal helper class which wraps DCB structure 00360 class CDCB : public DCB 00361 { 00362 public: 00363 CDCB() { DCBlength = sizeof(DCB); } 00364 }; 00365 00366 // Attributes 00367 protected: 00368 00369 LONG m_lLastError; // Last serial error 00370 HANDLE m_hFile; // File handle 00371 EEvent m_eEvent; // Event type 00372 HANDLE m_hevtOverlapped; // Event handle for internal overlapped operations 00373 }; 00374 00375 #endif // __SERIAL_H