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
00014
00015 static const uint FRAME_SIZE = 6;
00016
00017
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
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 }
00249
00250 #endif // MSP_HPP