]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/arducontrol.h
Remember discovered MFX locomotives across runs
[r2c2.git] / source / libr2c2 / arducontrol.h
index e354ecf0fed0c6f88824167ee8b7138399475863..1f45534a1ca472ee22cfbd40159fe2be806cf7a7 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <msp/core/mutex.h>
 #include <msp/core/thread.h>
+#include <msp/datafile/objectloader.h>
+#include <msp/fs/path.h>
 #include <msp/io/serial.h>
 #include <msp/time/timedelta.h>
 #include <msp/time/timestamp.h>
@@ -12,6 +14,17 @@ namespace R2C2 {
 
 class ArduControl: public Driver
 {
+public:
+       class Loader: public Msp::DataFile::ObjectLoader<ArduControl>
+       {
+       public:
+               Loader(ArduControl &);
+
+       private:
+               void mfx_announce_serial(unsigned);
+               void mfx_locomotive(unsigned);
+       };
+
 private:
        enum Command
        {
@@ -35,6 +48,7 @@ private:
                MFX_SPEED_FUNCS8 = 0x29,
                MFX_SPEED_FUNCS16 = 0x2A,
                S88_READ = 0x30,
+               SET_BAUD_RATE = 0x70,
                COMMAND_OK = 0x80,
                RECEIVE_OVERRUN = 0x81,
                FRAMING_ERROR = 0x82,
@@ -42,11 +56,13 @@ private:
                LENGTH_ERROR = 0x84,
                INVALID_VALUE = 0x85,
                OVERCURRENT = 0xA0,
+               BAUD_CHANGE_FAILED = 0xA1,
                TRACK_CURRENT = 0xC0,
                INPUT_VOLTAGE = 0xC1,
                POWER_STATE = 0xC2,
                S88_DATA = 0xD0,
-               MFX_FEEDBACK = 0xD1
+               MFX_SEARCH_FEEDBACK = 0xD1,
+               MFX_PING_FEEDBACK = 0xD2
        };
 
        struct Tag
@@ -72,7 +88,8 @@ private:
 
        enum GeneralCommand
        {
-               POWER
+               POWER,
+               NEW_LOCO
        };
 
        enum Protocol
@@ -127,6 +144,17 @@ private:
                unsigned create_speed_func_command(unsigned, char *) const;
        };
 
+       struct MfxInfo: public DetectedLocomotive
+       {
+               class Loader: public Msp::DataFile::ObjectLoader<MfxInfo>
+               {
+               public:
+                       Loader(MfxInfo &);
+               };
+
+               unsigned id;
+       };
+
        struct Accessory
        {
                enum Kind
@@ -179,6 +207,18 @@ private:
                PendingCommand(Accessory &, Accessory::Command, unsigned = 0);
        };
 
+       template<typename T>
+       class Queue
+       {
+       private:
+               std::list<T> items;
+               Msp::Mutex mutex;
+
+       public:
+               void push(const T &);
+               bool pop(T &);
+       };
+
        class Task
        {
        protected:
@@ -190,6 +230,15 @@ private:
                virtual void process_reply(const char *, unsigned) { }
        };
 
+       class CommandQueueTask: public Task
+       {
+       private:
+               Queue<PendingCommand> queue;
+
+       public:
+               virtual bool get_work(PendingCommand &);
+       };
+
        class RefreshTask: public Task
        {
        private:
@@ -243,6 +292,7 @@ private:
                virtual bool get_work(PendingCommand &);
 
                void set_serial(unsigned);
+               unsigned get_serial() const { return serial; }
        };
 
        class MfxSearchTask: public Task
@@ -253,13 +303,17 @@ private:
                Msp::Time::TimeStamp next;
                unsigned size;
                unsigned bits;
-               bool pending;
+               unsigned misses;
+               Queue<MfxInfo> queue;
 
        public:
                MfxSearchTask(ArduControl &);
 
                virtual bool get_work(PendingCommand &);
                virtual void process_reply(const char *, unsigned);
+
+               void set_next_address(unsigned);
+               bool pop_info(MfxInfo &);
        };
 
        class ControlThread: public Msp::Thread
@@ -275,32 +329,36 @@ private:
                void exit();
        private:
                virtual void main();
+               void init_baud_rate();
                bool get_work(PendingCommand &);
                unsigned do_command(const PendingCommand &);
                unsigned process_reply(const char *, unsigned);
        };
 
        typedef std::map<unsigned, Locomotive> LocomotiveMap;
+       typedef std::vector<MfxInfo> MfxInfoArray;
        typedef std::map<unsigned, Accessory> AccessoryMap;
        typedef std::list<Accessory *> AccessoryPtrList;
        typedef std::map<unsigned, Sensor> SensorMap;
 
        Msp::IO::Serial serial;
        unsigned debug;
+       Msp::FS::Path state_file;
 
        ControlledVariable<bool> power;
 
        LocomotiveMap locomotives;
+       MfxInfoArray mfx_info;
        AccessoryMap accessories;
        AccessoryPtrList accessory_queue;
        Accessory *active_accessory;
        Msp::Time::TimeStamp off_timeout;
-       std::list<PendingCommand> command_queue;
-       std::list<Tag> completed_commands;
 
        SensorMap sensors;
 
        Msp::Mutex mutex;
+       Queue<PendingCommand> command_queue;
+       Queue<Tag> completed_commands;
        RefreshTask refresh;
        S88Task s88;
        MfxAnnounceTask mfx_announce;
@@ -324,7 +382,11 @@ private:
 public:
        virtual unsigned get_protocol_speed_steps(const std::string &) const;
 
+       virtual const DetectedLocomotive *enumerate_detected_locos(unsigned) const;
        virtual unsigned add_loco(unsigned, const std::string &, const VehicleType &);
+private:
+       MfxInfoArray::iterator add_mfx_info(const MfxInfo &);
+public:
        virtual void remove_loco(unsigned);
        virtual void set_loco_speed(unsigned, unsigned);
        virtual void set_loco_reverse(unsigned, bool);
@@ -354,12 +416,8 @@ public:
 
        virtual void tick();
        virtual void flush();
-
 private:
-       void push_command(const PendingCommand &);
-       bool pop_command(PendingCommand &);
-       void push_completed_tag(const Tag &);
-       Tag pop_completed_tag();
+       void save_state() const;
 };
 
 } // namespace R2C2