MSP.hpp
Go to the documentation of this file.
00001 #ifndef MSP_HPP
00002 #define MSP_HPP
00003 
00004 #include "types.hpp"
00005 
00006 #include <asio.hpp>
00007 #include <stdexcept>
00008 #include <chrono>
00009 #include <mutex>
00010 
00011 namespace msp {
00012 
00013 // size of header+crc, e.g. amount of bytes in MSP message that do not belong to payload
00014 // preamble (2) + direction (1) + size (1) + command (1) + crc (1) = 6
00015 static const uint FRAME_SIZE = 6;
00016 
00017 // exception to throw when header contains wrong data
00018 class MalformedHeader : public std::runtime_error {
00019 public:
00020     MalformedHeader(const uint8_t exp, const uint8_t rcv)
00021         : std::runtime_error(
00022               "Malformed header: "
00023               "expected "+std::to_string(exp)+" ("+std::string(1,char(exp))+"), "
00024               "received "+std::to_string(rcv)+" ("+std::string(1,char(rcv))+")") {}
00025 };
00026 
00027 class UnknownMsgId : public std::runtime_error {
00028 private:
00029     const uint8_t msg_id;
00030 public:
00031     UnknownMsgId(uint8_t id) : runtime_error(
00032         "Unknown MSP id! FC refused to process message with id: "+std::to_string(id)), msg_id(id)
00033     { }
00034 
00035     const uint8_t &getInvalidID() const { return msg_id; }
00036 };
00037 
00038 // exception to throw if reported CRC does not match with computed
00039 class WrongCRC : public std::runtime_error {
00040 public:
00041     WrongCRC(const uint8_t msg_id, const uint8_t exp, const uint8_t rcv)
00042         : std::runtime_error(
00043               "CRC not matching: "
00044               "Message "+std::to_string(uint(msg_id))+", "
00045               "expected CRC "+std::to_string(exp)+", "
00046               "received CRC "+std::to_string(rcv))
00047     { }
00048 };
00049 
00050 class NoData : public std::runtime_error {
00051 public:
00052     NoData() : std::runtime_error("No data available!") { }
00053 };
00054 
00055 class NoConnection : public std::runtime_error {
00056 public:
00057     NoConnection(const std::string &device, const std::string &msg)
00058         : runtime_error("Device not available: "+device+" ("+msg+")")
00059     { }
00060 };
00061 
00065 struct DataID {
00066     ByteVector data;    
00067     uint8_t id;         
00068 
00074     DataID(const ByteVector data, const uint8_t id) : data(data), id(id) {}
00075 };
00076 
00080 class MSP {
00081 public:
00082 
00086     MSP();
00087 
00093     MSP(const std::string &device, const uint baudrate=115200);
00094 
00101     bool connect(const std::string &device, const uint baudrate=115200);
00102 
00109     bool request(msp::Request &request);
00110 
00116     bool request_block(msp::Request &request);
00117 
00125     bool request_wait(msp::Request &request, const uint wait_ms, const uint min_payload_size = 0);
00126 
00133     bool respond(const msp::Response &response);
00134 
00140     bool respond_block(const msp::Response &response);
00141 
00149     bool sendData(const uint8_t id, const ByteVector &data = ByteVector(0));
00150 
00158     bool sendData(const msp::ID id, const ByteVector &data = ByteVector(0)) {
00159         return sendData(uint8_t(id), data);
00160     }
00161 
00168     bool send(const msp::Response &response) {
00169         return sendData(response.id(), response.encode());
00170     }
00171 
00176     DataID receiveData();
00177 
00185     void setWait(unsigned int wait_us) {
00186         wait = wait_us;
00187     }
00188 
00189 private:
00196     uint8_t crc(const uint8_t id, const ByteVector &data);
00197 
00204     bool write(const std::vector<uint8_t> &data);
00205 
00211     size_t read(std::vector<uint8_t> &data);
00212 
00218     std::vector<uint8_t> read(std::size_t n_bytes);
00219 
00224     uint8_t read() {
00225         return read(1).front();
00226     }
00227 
00233     int hasData();
00234 
00238     void clear();
00239 
00240     std::string device;
00241     asio::io_service io;     
00242     asio::serial_port port;  
00243     std::mutex lock_write;
00244     std::mutex lock_read;
00245     unsigned int wait;  
00246 };
00247 
00248 } // namespace msp
00249 
00250 #endif // MSP_HPP


msp
Author(s): Christian Rauch
autogenerated on Mon Oct 9 2017 03:02:13