/*! \file piserial.h * \brief Serial device */ /* PIP - Platform Independent Primitives COM Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com, Bychkov Andrey wapmobil@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PISERIAL_H #define PISERIAL_H #include "pitimer.h" #include "piiodevice.h" #ifndef WINDOWS # include # include # include # ifndef B50 # define B50 0000001 # endif # ifndef B75 # define B75 0000002 # endif # ifndef B1500000 # define B1500000 0010012 # endif # ifndef B2000000 # define B2000000 0010013 # endif # ifndef B2500000 # define B2500000 0010014 # endif # ifndef B3000000 # define B3000000 0010015 # endif # ifndef B3500000 # define B3500000 0010016 # endif # ifndef B4000000 # define B4000000 0010017 # endif #else # define TIOCM_LE 1 # define TIOCM_DTR 4 # define TIOCM_RTS 7 # define TIOCM_CTS 8 # define TIOCM_ST 3 # define TIOCM_SR 2 # define TIOCM_CAR 1 # define TIOCM_RNG 9 # define TIOCM_DSR 6 # define B50 50 # define B75 75 # define B110 110 # define B300 300 # define B600 600 # define B1200 1200 # define B2400 2400 # define B4800 4800 # define B9600 9600 # define B14400 14400 # define B19200 19200 # define B38400 38400 # define B57600 57600 # define B115200 115200 # define B128000 128000 # define B256000 256000 # define B1500000 1500000 # define B2000000 2000000 # define B2500000 2500000 # define B3000000 3000000 # define B3500000 3500000 # define B4000000 4000000 #endif #ifndef CRTSCTS # define CRTSCTS 020000000000 #endif class PIP_EXPORT PISerial: public PIIODevice { PIIODEVICE(PISerial) public: //! Contructs an empty %PISerial PISerial(); //! \brief Parameters of PISerial enum Parameters { ParityControl /*! Enable parity check and generate */ = 0x1, ParityOdd /*! Parity is odd instead of even */ = 0x2, TwoStopBits /*! Two stop bits instead of one */ = 0x4 }; //! \brief Speed of PISerial enum Speed { S50 /*! 50 baud */ = 50, S75 /*! 75 baud */ = 75, S110 /*! 110 baud */ = 110, S300 /*! 300 baud */ = 300, S600 /*! 600 baud */ = 600, S1200 /*! 1200 baud */ = 1200, S2400 /*! 2400 baud */ = 2400, S4800 /*! 4800 baud */ = 4800, S9600 /*! 9600 baud */ = 9600, S19200 /*! 19200 baud */ = 19200, S38400 /*! 38400 baud */ = 38400, S57600 /*! 57600 baud */ = 57600, S115200 /*! 115200 baud */ = 115200, S1500000 = 1500000, // Linux only S2000000 = 2000000, // Linux only S2500000 = 2500000, // Linux only S3000000 = 3000000, // Linux only S3500000 = 3500000, // Linux only S4000000 = 4000000 // Linux only }; //! Contructs %PISerial with device name "device", speed "speed" and parameters "params" PISerial(const PIString & device, PISerial::Speed speed = S115200, PIFlags params = 0); ~PISerial(); //! Set both input and output speed to "speed" void setSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); setProperty("inSpeed", (int)speed); applySettings();} //! Set output speed to "speed" void setOutSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); applySettings();} //! Set input speed to "speed" void setInSpeed(PISerial::Speed speed) {setProperty("inSpeed", (int)speed); applySettings();} //! Set device name to "dev" void setDevice(const PIString & dev) {setPath(dev); if (isOpened()) {close(); open();};} //! Set parameters to "parameters_" void setParameters(PIFlags parameters_) {setProperty("parameters", (int)parameters_); applySettings();} //! Set parameter "parameter" to "on" state void setParameter(PISerial::Parameters parameter, bool on = true); //! Returns if parameter "parameter" is set bool isParameterSet(PISerial::Parameters parameter) const; //! Returns parameters PIFlags parameters() const {return (PIFlags)(property("parameters").toInt());} //! Set data bits count. Valid range is from 5 to 8, befault is 8 void setDataBitsCount(int bits) {setProperty("dataBitsCount", bits); applySettings();} //! Returns data bits count int dataBitsCount() const {return property("dataBitsCount").toInt();} //! Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS) bool setPin(int number, bool on); //! Returns pin number "number" logic level. Valid numbers range is from 1 to 9 bool isPin(int number) const; bool setLE(bool on) {return setBit(TIOCM_LE, on, "LE");} // useless function, just formally bool setDTR(bool on) {return setBit(TIOCM_DTR, on, "DTR");} bool setRTS(bool on) {return setBit(TIOCM_RTS, on, "RTS");} bool setCTS(bool on) {return setBit(TIOCM_CTS, on, "CTS");} // useless function, just formally bool setST(bool on) {return setBit(TIOCM_ST, on, "ST");} // useless function, just formally bool setSR(bool on) {return setBit(TIOCM_SR, on, "SR");} // useless function, just formally bool setCAR(bool on) {return setBit(TIOCM_CAR, on, "CAR");} // useless function, just formally bool setRNG(bool on) {return setBit(TIOCM_RNG, on, "RNG");} // useless function, just formally bool setDSR(bool on) {return setBit(TIOCM_DSR, on, "DSR");} // useless function, just formally bool isLE() const {return isBit(TIOCM_LE, "LE");} bool isDTR() const {return isBit(TIOCM_DTR, "DTR");} bool isRTS() const {return isBit(TIOCM_RTS, "RTS");} bool isCTS() const {return isBit(TIOCM_CTS, "CTS");} bool isST() const {return isBit(TIOCM_ST, "ST");} bool isSR() const {return isBit(TIOCM_SR, "SR");} bool isCAR() const {return isBit(TIOCM_CAR, "CAR");} bool isRNG() const {return isBit(TIOCM_RNG, "RNG");} bool isDSR() const {return isBit(TIOCM_DSR, "DSR");} void setVTime(int t) {vtime = t; applySettings();} //! Set read is blocking for function read(void * read_to, int max_size) void setReadIsBlocking(bool yes); //! Returns device name PIString device() const {return path();} //! Returns output speed PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());} //! Returns input speed PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());} int VTime() const {return vtime;} //! Discard all buffered input and output data void flush() { #ifndef WINDOWS if (fd != -1) tcflush(fd, TCIOFLUSH); #endif } int read(void * read_to, int max_size); bool read(void * read_to, int max_size, double timeout_ms); PIString read(int size = -1, double timeout_ms = 1000.); PIByteArray readData(int size = -1, double timeout_ms = 1000.); //! \brief Write to device data "data" with maximum size "max_size" and wait for data written if "wait" is \b true. //! \returns sended bytes count int write(const void * data, int max_size, bool wait = false); //! \brief Write to device data "data" with maximum size "size" and wait for data written if "wait" is \b true. //! \returns \b true if sended bytes count = "size" bool send(const void * data, int size, bool wait = false) {return (write(data, size, wait) == size);} //! \brief Write to device string "data" and wait for data written if "wait" is \b true. //! \returns \b true if sended bytes count = size of string bool send(const PIString & data, bool wait = false) {return (write(data.data(), data.lengthAscii(), wait) == data.size_s());} //! \brief Write to device byte array "data" and wait for data written if "wait" is \b true. //! \returns \b true if sended bytes count = size of string bool send(const PIByteArray & data, bool wait = false) {return (write(data.data(), data.size_s(), wait) == data.size_s());} //! \brief Returns all available speeds for serial devices static PIVector availableSpeeds(); //! \brief Returns all available system devices. If "test" each device will be tried to open static PIStringList availableDevices(bool test = false); //! \ioparams //! \{ #ifdef DOXYGEN //! \brief device, default "" string device; //! \brief input/output speed, default 115200 int speed; //! \brief dataBitsCount, default 8 int dataBitsCount; //! \brief parityControl, default false bool parityControl; //! \brief parityOdd, default false bool parityOdd; //! \brief twoStopBits, default false bool twoStopBits; #endif //! \} protected: PIString fullPathPrefix() const {return "ser";} void configureFromFullPath(const PIString & full_path); bool configureDevice(const void * e_main, const void * e_parent = 0); int write(const void * data, int max_size) {return write(data, max_size, true);} //! Executes when any read function was successful. Default implementation does nothing virtual void received(const void * data, int size) {;} void _init(); void applySettings(); int convertSpeed(PISerial::Speed speed); bool setBit(int bit, bool on, const PIString & bname); bool isBit(int bit, const PIString & bname) const; bool openDevice(); bool closeDevice(); #ifdef WINDOWS DCB desc, sdesc; void * hCom; DWORD readed, mask; bool block_write; #else termios desc, sdesc; uint readed; #endif int fd, vtime; bool block_read; PITimer timer; }; #endif // PISERIAL_H