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

Tekkotsu Hardware Abstraction Layer 4.0
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4