Serial.H

00001 /*!@file Devices/Serial.H  class for interfacing with a serial port */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Chin-Kai Chang<chinkaic@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/Serial.H $
00035 // $Id: Serial.H 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 #ifndef __SERIAL_H__
00039 #define __SERIAL_H__
00040 
00041 
00042 #include <fcntl.h>
00043 #include <stdio.h>
00044 #include <sys/stat.h>
00045 #include <sys/types.h>
00046 #include <termios.h>
00047 #include <unistd.h>
00048 #include <string>
00049 #include <vector>
00050 //! enum for different serial errors that could occur
00051 enum serialError
00052   {
00053     serialErrSuccess = 0,
00054     serialErrOpenNoTty,//1
00055     serialErrOpenFailed,//2
00056     serialErrSpeedInvalid,//3
00057     serialErrFlowInvalid,//4
00058     serialErrParityInvalid,//5
00059     serialErrCharsizeInvalid,//6
00060     serialErrStopbitsInvalid,//7
00061     serialErrOptionInvalid,//8
00062     serialErrResourceFailure,//9
00063     serialErrOutput,//10
00064     serialErrInput,//11
00065     serialErrTimeout,//12
00066     serialErrExtended,//13
00067     serialErrReadFailed,//14
00068     serialErrReadTimedOut,//15
00069     serialErrWriteFailed,//16
00070     serialErrFcntlFailed,//17
00071     serialErrTcGetAttrFailed,//18
00072     serialErrTcSetAttrFailed//19
00073   };
00074 
00075 //! Interface to a serial port
00076 /*! The port will be open at start() time; see ModelComponent.H for
00077   details. Because typically one may use several serial ports with
00078   different configs, this ModelComponent does not export any
00079   command-line option (there would be too many otherwise if many ports
00080   are used). Typically, thus, the port can be configured either via
00081   config files or using the various access functions provided in this
00082   class. */
00083 class Serial {
00084 public:
00085   //! Constructor
00086 //      Serial( const std::string& descrName, const std::string& tagName);
00087         Serial();
00088 
00089   //! destructor
00090   ~Serial(void);
00091 
00092   //! Close the serial port device file
00093   void closePort();
00094 
00095   //! Enable the serial port
00096   /*! enablePort will do all of the work of actually setting the config properties
00097       that have been requested, as well as opening the device file, etc...
00098    */
00099   void enablePort(std::string DeviceName);
00100 
00101   //! Configure the port before it is started.
00102   /*! This will update our internal ModelParam values to the specified
00103       ones; thus this should be called before start(). In contrast,
00104       the setXXX functions below are for reconfiguration at runtime,
00105       once the port is already open and running. This function is
00106       provided as a shortcut to set a bunch of ModelParam values in
00107       one simple call.
00108     @param dev device name (e.g., "/dev/ttyS0")
00109     @param speed speed in bauds. See setSpeed() for valid values
00110     @param format a 3-char string for charbits, parity, and stop bits; for
00111            example "8N1"; parity should be "N", "E" or "O".
00112     @param flowSoft use software flow control if true
00113     @param flowHard use hardware flow control if true
00114     @param tout read timeout in 1/10000s or 0 for no timeout */
00115   void configure(const char *dev = "", const int speed = 9600,
00116                  const char *format = "8N1",
00117                  const bool flowSoft = false, const bool flowHard = false,
00118                  const int = 0);
00119 
00120         //! Configure the serial port to search for a device
00121         void configureSearch(const std::string DeviceDescription, const int speed = 115200,
00122                                                                  const std::string SearchPrefix = "ttyUSB",
00123                  const char *format = "8N1",
00124                  const bool flowSoft = false, const bool flowHard = false,
00125                  const int = 0);
00126 
00127 
00128   //! Set serial port speed for both input and output.
00129   /*! This function is to change the speed while already started.
00130       @param speed to select. 0 signifies modem "hang up" and possible
00131              values are 0, 110, 300, 600, 1200, 2400, 4800, 9600,
00132              19200, 38400, 57600, 115200.
00133       @return 0 or serialErrSuccess on success. The perror() method
00134              can be used to print a longer description of the error. */
00135   serialError setSpeed(const int speed);
00136 
00137   //! Set the serial port flow control on Input as well as Ouput
00138   /*! This function is to change the flow control while already started.
00139     @param useHard use hardware flow control if true
00140     @param useSoft use software flow control if true
00141     @return 0 or serialErrSuccess on success */
00142   serialError setFlowControl(const bool useHard, const bool useSoft);
00143 
00144   //! Set character size.
00145   /*! This function is to change the char size while already started.
00146     @return 0 on success.
00147     @param bits character size to use; valid values are 5, 6, 7, 8. */
00148   serialError setCharBits(const int bits);
00149 
00150   //! Set parity mode.
00151   /*! This function is to change the parity while already started.
00152     @param useParity use some parity if true
00153     @param oddParity parity is odd if true, otherwise even
00154     @return 0 on success. */
00155   serialError setParity(const bool useParity, const bool oddParity);
00156 
00157   //! Set number of stop bits.
00158   /*! This function is to change the stop bits while started.
00159     @return 0 on success.
00160     @param bits stop bits (only values 1 and 2 are valid). */
00161   serialError setStopBits(const int bits);
00162 
00163   //! Set the access to blocking or not
00164   /*! If blocking, a write will block until all data has actually been
00165     sent through; otherwise it will return immediately while the data
00166     is being transmitted. */
00167   serialError setBlocking(const bool blocking);
00168 
00169   //! Set the DTR mode off momentarily.
00170   /*! @param millisec number of milliseconds. */
00171   void toggleDTR(const time_t millisec);
00172 
00173   //! transmit continuous stream of zero-valued bits for specific duration.
00174   void sendBreak(void);
00175 
00176   //! attempt to read up to nbytes from serial port into the buffer
00177   /*! @param buffer holds bytes after read
00178       @nbytes number of bytes to attempt to read
00179       @return 0 on a timeout, -1 on error, number of bytes actually read
00180       on a success */
00181   int read(void* buffer, const int nbytes);
00182 
00183   //! Attempt to read a serial frame
00184   /*! The frame returned by the device should have the following format:
00185       [start byte] [optional number of data bytes] [data...] ... [...data] [end byte]
00186       @param frameStart holds the byte signifying the start of the frame
00187       @param frameEnd holds the byte signifying the end of the frame
00188       @param frameLength optionally specifies the number of bytes in the frame. If this is -1,
00189                          then the second byte of the frame is assumed to contain the total number of
00190                          bytes in the frame.
00191       @param timeout the number of seconds to wait before giving up (default of -1 is no timeout)
00192       @return the data contained in the frame */
00193   //TODO: Implement parity checking in the stop byte
00194   std::vector<unsigned char> readFrame(
00195       const unsigned char frameStart,
00196       const unsigned char frameEnd = 255,
00197       const int frameLength = -1,
00198       const double timeout = -1
00199       );
00200 
00201   //! attempts to get the next character from the serial port
00202   /*!  for comptability with dirk's code  */
00203   char read(void);
00204 
00205   //! write bytes to the port
00206   /*! @param buffer begin writing from the location buffer.
00207       @param nbytes number of bytes to write
00208       @return -1 on failure, number of bytes written on success */
00209   int write(const void* buffer, const int nbytes);
00210 
00211         //! write a single byte to the port - a simple wrapper around write(const void* buffer, const int nbytes)
00212         /*! @param character the single byte to write
00213             @return -1 on failure, 1 on successs.*/
00214         int write(const unsigned char character);
00215 
00216   //! print a verbal message indicating the last error.
00217   void perror(void);
00218 
00219   void flush(void);
00220 
00221         //Accessor Functions
00222         std::string getDeviceDescriptor() { return itsDeviceDescription; };
00223         std::string getDevName() { return itsCmdDevName; };
00224         bool isSerialOk() { return (serialErrno==0); };
00225         int getSerialErrno() { return serialErrno; };
00226 
00227   //! open the port and get started
00228   void start();
00229 
00230   //! close the port and get stopped
00231   void stop();
00232 protected:
00233   std::string itsCmdDevName;           //!< device name passed from cmd line
00234 
00235   std::string itsDeviceDescription; //!< device description to seach for
00236   std::string itsSearchPrefix;      //!< device name prefix (e.g. ttyUSB)
00237   int         itsBaud;                                       //!< Baudrate
00238   int         itsCharBits;                                   //!< number of useful bits per char
00239   int         itsStopBits;                                   //!< number of stop bits
00240   bool        itsUseParity;                                 //!< use parity if true
00241   bool        itsParityOdd;                                 //!< parity is odd if true, otherwise even
00242   bool        itsFlowHard;                                  //!< use hardware flow control if true
00243   bool        itsFlowSoft;                                  //!< use software flow control if true
00244   int         itsRdTout;                                     //!< read timeout in 1/10000s
00245   bool        itsBlocking;                                  //!< use blocking mode
00246   bool        itsSerialOk;                                  //!< Port opened success if true
00247 
00248 
00249 private:
00250   int dev; // descriptor associated with the device file
00251   std::string itsDevName; //the device name
00252   serialError serialErrno; // error id of the last error
00253   termios savedState; // saved state to restore in the destructor
00254 
00255   // set our errno
00256   serialError error(const serialError serialErrorNum);
00257 
00258   // open the serial port. This is called from the constructor, so there is
00259   //    no need to explicitly call this
00260   // @return -1 on error
00261   int openPort(std::string DeviceName);
00262 };
00263 
00264 #endif
00265 
00266 // ######################################################################
00267 /* So things look consistent in everyone's emacs... */
00268 /* Local Variables: */
00269 /* indent-tabs-mode: nil */
00270 /* End: */
Generated on Sun May 8 08:04:45 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3