Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SerialCommPort.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_SerialCommPort_h_
00003 #define INCLUDED_SerialCommPort_h_
00004 
00005 #include "FileSystemCommPort.h"
00006 #include <fcntl.h>
00007 #include <termios.h>
00008 
00009 //! Provides CommPort interface to serial port devices -- essentially just a FileSystemCommPort, but can apply terminal IO settings
00010 /*! You could use FileSystemCommPort instead of this class, and thus
00011  *  rely on a prior manual call to stty.  However, other programs (or rebooting)
00012  *  will reset those parameters, so it's nice to use this class to ensure the
00013  *  desired settings are reapplied each time the device is opened. */
00014 class SerialCommPort : public FileSystemCommPort {
00015 public:
00016   //! constructor
00017   explicit SerialCommPort(const std::string& name)
00018   : FileSystemCommPort(autoRegisterSerialCommPort,name),
00019   baudRate(57600), dataBits(8), stopBits(1), parity(NONE,parityNames), sttyConfig(),
00020   fd(-1)
00021   {
00022     if(bauds.size()==0)
00023       initBauds();
00024     addEntry("Baud",baudRate,"Communication frequency (bits per second)");
00025     addEntry("DataBits",dataBits,"Number of data bits to send at a time (5-8)");
00026     addEntry("StopBits",stopBits,"Number of stop bits to send between data bits (1-2)");
00027     addEntry("Parity",parity,"Parity bit can be sent for error checking\n"+parity.getDescription());
00028     addEntry("TTYFlags",sttyConfig,"Additional configuration string to pass to stty\n(may not work when using non-standard baud rates on OS X)");
00029     baudRate.addPrimitiveListener(this);
00030     dataBits.addPrimitiveListener(this);
00031     stopBits.addPrimitiveListener(this);
00032     parity.addPrimitiveListener(this);
00033     sttyConfig.addPrimitiveListener(this);
00034   }
00035   
00036   //! destructor
00037   ~SerialCommPort() {
00038     baudRate.removePrimitiveListener(this);
00039     dataBits.removePrimitiveListener(this);
00040     stopBits.removePrimitiveListener(this);
00041     parity.removePrimitiveListener(this);
00042     sttyConfig.removePrimitiveListener(this);
00043   }
00044 
00045   virtual std::string getClassName() const { return autoRegisterSerialCommPort; }
00046   
00047   virtual bool open() {
00048     if(openedCnt==0) { // just do it on initial call
00049       // open serial port, need to keep it open through the FileSystemCommPort opening
00050       fd = ::open(path.c_str(), O_RDWR | O_NONBLOCK);
00051       setupSerial();
00052     }
00053     return FileSystemCommPort::open();
00054   }
00055   
00056   virtual bool close() {
00057     bool ans = FileSystemCommPort::close();
00058     if(openedCnt==0) {
00059 			::close(fd);
00060       fd=-1;
00061     }
00062     return ans;
00063   }
00064   
00065   //! watches #sttyConfig, reapplies the settings if changed
00066   virtual void plistValueChanged(const plist::PrimitiveBase& pl) {
00067     if(&pl==&sttyConfig) {
00068       setupSerial();
00069     } else if(&pl==&baudRate) {
00070       setupSerial();
00071     } else if(&pl==&dataBits) {
00072       if(dataBits<5 || dataBits>8) {
00073         std::cerr << "Cannot set DataBits to " << dataBits << ", reset to " << dataBits.getPreviousValue() << std::endl;
00074         dataBits=dataBits.getPreviousValue();
00075         return;
00076       }
00077       setupSerial();
00078     } else if(&pl==&stopBits) {
00079       if(stopBits<1 || stopBits>2) {
00080         std::cerr << "Cannot set StopBits to " << stopBits << ", reset to " << stopBits.getPreviousValue() << std::endl;
00081         stopBits=stopBits.getPreviousValue();
00082         return;
00083       }
00084       setupSerial();
00085     } else if(&pl==&parity) {
00086       setupSerial();
00087     } else {
00088       // path or mode changed... if opened, will be called if changing path...
00089       FileSystemCommPort::plistValueChanged(pl);
00090     }
00091   }
00092   
00093   plist::Primitive<unsigned int> baudRate;
00094   plist::Primitive<unsigned int> dataBits;
00095   plist::Primitive<unsigned int> stopBits;
00096   enum parity_t { EVEN, ODD, NONE };
00097   static const char * const parityNames[];
00098   plist::NamedEnumeration<parity_t> parity;
00099   plist::Primitive<std::string> sttyConfig; //!< Configuration string to pass to stty
00100   
00101 protected:
00102   //! file descriptor for serial port -- needed for tcsetattr and ioctl interfaces
00103   int fd;
00104   
00105   //! performs serial port initialization (if fd is non-negative)
00106   virtual void setupSerial();
00107   
00108   void dispError(const char* where, int ret, int err);
00109 
00110   //! initializes #bauds with all of the symbolic baud rate settings available on host platform
00111   static void initBauds();
00112 
00113   //! table of valid baud rates
00114   static std::map<int,speed_t> bauds;
00115     
00116   //! holds the class name, set via registration with the CommPort registry
00117   static const std::string autoRegisterSerialCommPort;
00118 };
00119 
00120 /*! @file
00121 * @brief Describes SerialCommPort, which provides CommPort interface to serial port devices -- essentially just a FileSystemCommPort, but can apply terminal IO settings
00122 * @author Ethan Tira-Thompson (ejt) (Creator)
00123 */
00124 
00125 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:39 2016 by Doxygen 1.6.3