]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/arducontrol.h
Add two new telemetry values to the arducontrol driver
[r2c2.git] / source / libr2c2 / arducontrol.h
index 8d27a2f572d74e561acdbc0266dc20561a777f8c..fffaf8cc36854d691860e8064548fcd589579aac 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef LIBR2C2_ARDUCONTROL_H_
 #define LIBR2C2_ARDUCONTROL_H_
 
+#include <deque>
 #include <msp/core/mutex.h>
 #include <msp/core/thread.h>
 #include <msp/datafile/objectloader.h>
@@ -44,6 +45,7 @@ private:
                MFX_SEARCH = 0x23,
                MFX_ASSIGN_ADDRESS = 0x24,
                MFX_PING = 0x25,
+               MFX_READ = 0x26,
                MFX_SPEED = 0x28,
                MFX_SPEED_FUNCS8 = 0x29,
                MFX_SPEED_FUNCS16 = 0x2A,
@@ -62,7 +64,8 @@ private:
                POWER_STATE = 0xC2,
                S88_DATA = 0xD0,
                MFX_SEARCH_FEEDBACK = 0xD1,
-               MFX_PING_FEEDBACK = 0xD2
+               MFX_PING_FEEDBACK = 0xD2,
+               MFX_READ_FEEDBACK = 0xD3
        };
 
        struct Tag
@@ -173,12 +176,13 @@ private:
                Kind kind;
                unsigned address;
                unsigned bits;
+               unsigned valid_states;
                ControlledVariable<unsigned> state;
                unsigned uncertain;
                unsigned target;
                Msp::Time::TimeDelta active_time;
 
-               Accessory(Kind, unsigned, unsigned);
+               Accessory(Kind, unsigned, unsigned, unsigned);
 
                unsigned create_state_command(unsigned, bool, char *) const;
        };
@@ -213,24 +217,36 @@ private:
        class Queue
        {
        private:
-               std::list<T> items;
+               std::deque<T> items;
                Msp::Mutex mutex;
 
        public:
                void push(const T &);
                bool pop(T &);
+               unsigned size() const;
                bool empty() const;
        };
 
        class Task
        {
        protected:
-               Task() { }
+               std::string name;
+               unsigned priority;
+               Msp::Time::TimeStamp sleep_timeout;
+
+               Task(const std::string &, unsigned = 0);
        public:
                virtual ~Task() { }
 
+               const std::string &get_name() const { return name; }
+
                virtual bool get_work(PendingCommand &) = 0;
                virtual void process_reply(const char *, unsigned) { }
+
+               unsigned get_priority() const { return priority; }
+               const Msp::Time::TimeStamp &get_sleep_timeout() const { return sleep_timeout; }
+       protected:
+               void sleep(const Msp::Time::TimeDelta &);
        };
 
        class CommandQueueTask: public Task
@@ -239,7 +255,13 @@ private:
                Queue<PendingCommand> queue;
 
        public:
+               CommandQueueTask();
+
                virtual bool get_work(PendingCommand &);
+
+               void push(const PendingCommand &);
+               unsigned size() const { return queue.size(); }
+               bool empty() const { return queue.empty(); }
        };
 
        class RefreshTask: public Task
@@ -272,7 +294,8 @@ private:
                ArduControl &control;
                unsigned n_octets;
                unsigned octets_remaining;
-               unsigned delay;
+               Msp::Time::TimeStamp last_poll;
+               Msp::Time::TimeDelta latency;
 
        public:
                S88Task(ArduControl &);
@@ -282,13 +305,14 @@ private:
 
                void set_n_octets(unsigned);
                void grow_n_octets(unsigned);
+
+               const Msp::Time::TimeDelta &get_latency() const { return latency; }
        };
 
        class MfxAnnounceTask: public Task
        {
        private:
                unsigned serial;
-               Msp::Time::TimeStamp next;
 
        public:
                MfxAnnounceTask();
@@ -304,12 +328,18 @@ private:
        private:
                ArduControl &control;
                unsigned next_address;
-               Msp::Time::TimeStamp next;
                unsigned size;
                unsigned bits;
                unsigned misses;
                Queue<MfxInfo> queue;
 
+               MfxInfo *pending_info;
+               unsigned read_array;
+               unsigned read_offset;
+               unsigned read_length;
+               char read_data[0x40];
+               unsigned block_size;
+
        public:
                MfxSearchTask(ArduControl &);
 
@@ -327,7 +357,6 @@ private:
                float current;
                float base_level;
                float peak_level;
-               Msp::Time::TimeStamp next_poll;
                unsigned next_type;
 
        public:
@@ -348,10 +377,15 @@ private:
                ArduControl &control;
                bool done;
                std::vector<Task *> tasks;
+               unsigned cmd_rate;
+               unsigned cmd_count;
+               Msp::Time::TimeStamp cmd_rate_start;
 
        public:
                ControlThread(ArduControl &);
 
+               unsigned get_command_rate() const { return cmd_rate; }
+
                void exit();
        private:
                virtual void main();
@@ -386,7 +420,7 @@ private:
        SensorMap sensors;
 
        Msp::Time::TimeDelta command_timeout;
-       Queue<PendingCommand> command_queue;
+       CommandQueueTask command_queue;
        Queue<Tag> completed_commands;
        RefreshTask refresh;
        S88Task s88;
@@ -396,6 +430,7 @@ private:
        ControlThread thread;
 
        static ProtocolInfo protocol_info[2];
+       static TelemetryInfo telemetry_info[6];
 
 public:
        ArduControl(const Options &);
@@ -416,6 +451,7 @@ public:
        virtual unsigned add_loco(unsigned, const std::string &, const VehicleType &);
 private:
        MfxInfoArray::iterator add_mfx_info(const MfxInfo &);
+       MfxInfo *find_mfx_info(unsigned);
 public:
        virtual void remove_loco(unsigned);
        virtual void set_loco_speed(unsigned, unsigned);
@@ -433,10 +469,11 @@ public:
        virtual unsigned get_signal(unsigned) const;
 
 private:
-       unsigned add_accessory(Accessory::Kind, unsigned, unsigned);
+       unsigned add_accessory(Accessory::Kind, unsigned, unsigned, unsigned);
        void remove_accessory(Accessory::Kind, unsigned);
        void set_accessory(Accessory::Kind, unsigned, unsigned);
        unsigned get_accessory(Accessory::Kind, unsigned) const;
+       void activate_accessory_by_mask(Accessory &, unsigned);
 
 public:
        virtual unsigned add_sensor(unsigned);
@@ -444,6 +481,9 @@ public:
        virtual void set_sensor(unsigned, bool) { }
        virtual bool get_sensor(unsigned) const;
 
+       virtual const TelemetryInfo *enumerate_telemetry(unsigned) const;
+       virtual float get_telemetry_value(const std::string &) const;
+
        virtual void tick();
        virtual void flush();
 private: