00001
00002 #ifndef INCLUDED_SerialCommPort_h_
00003 #define INCLUDED_SerialCommPort_h_
00004
00005 #include "FileSystemCommPort.h"
00006 #include <fcntl.h>
00007
00008
00009
00010
00011
00012
00013 class SerialCommPort : public FileSystemCommPort {
00014 public:
00015
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
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) {
00046
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
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
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;
00097
00098 protected:
00099
00100 int fd;
00101
00102
00103 virtual void setupSerial();
00104
00105 void dispError(const char* where, int ret, int err);
00106
00107
00108 static const std::string autoRegisterSerialCommPort;
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #endif