]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/arducontrol.h
Add interface for importing detected locomotives from the driver
[r2c2.git] / source / libr2c2 / arducontrol.h
index 3a86ceeacc09790bbfc1c7afa04ac6dab29093ff..2431cf927ae8d59b7dfc11a411b7e99e7159e83d 100644 (file)
@@ -35,6 +35,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 +43,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
@@ -166,11 +169,108 @@ private:
                Sensor(unsigned);
        };
 
+       struct PendingCommand
+       {
+               Tag tag;
+               char command[15];
+               unsigned char length;
+               unsigned repeat_count;
+
+               PendingCommand();
+               PendingCommand(GeneralCommand);
+               PendingCommand(Locomotive &, Locomotive::Command, unsigned = 0);
+               PendingCommand(Accessory &, Accessory::Command, unsigned = 0);
+       };
+
+       class Task
+       {
+       protected:
+               Task() { }
+       public:
+               virtual ~Task() { }
+
+               virtual bool get_work(PendingCommand &) = 0;
+               virtual void process_reply(const char *, unsigned) { }
+       };
+
+       class RefreshTask: public Task
+       {
+       private:
+               typedef std::list<Locomotive *> LocomotivePtrList;
+
+               LocomotivePtrList cycle;
+               LocomotivePtrList::iterator next;
+               unsigned round;
+               Locomotive *loco;
+               unsigned phase;
+               Msp::Mutex mutex;
+
+       public:
+               RefreshTask();
+
+               virtual bool get_work(PendingCommand &);
+
+               void add_loco(Locomotive &);
+               void remove_loco(Locomotive &);
+       private:
+               Locomotive *get_next_loco();
+               void advance();
+       };
+
+       class S88Task: public Task
+       {
+       private:
+               ArduControl &control;
+               unsigned n_octets;
+               unsigned octets_remaining;
+
+       public:
+               S88Task(ArduControl &);
+
+               virtual bool get_work(PendingCommand &);
+               virtual void process_reply(const char *, unsigned);
+
+               void set_n_octets(unsigned);
+               void grow_n_octets(unsigned);
+       };
+
+       class MfxAnnounceTask: public Task
+       {
+       private:
+               unsigned serial;
+               Msp::Time::TimeStamp next;
+
+       public:
+               MfxAnnounceTask();
+
+               virtual bool get_work(PendingCommand &);
+
+               void set_serial(unsigned);
+       };
+
+       class MfxSearchTask: public Task
+       {
+       private:
+               ArduControl &control;
+               unsigned next_address;
+               Msp::Time::TimeStamp next;
+               unsigned size;
+               unsigned bits;
+               unsigned misses;
+
+       public:
+               MfxSearchTask(ArduControl &);
+
+               virtual bool get_work(PendingCommand &);
+               virtual void process_reply(const char *, unsigned);
+       };
+
        class ControlThread: public Msp::Thread
        {
        private:
                ArduControl &control;
                bool done;
+               std::vector<Task *> tasks;
 
        public:
                ControlThread(ArduControl &);
@@ -178,22 +278,13 @@ private:
                void exit();
        private:
                virtual void main();
-       };
-
-       struct QueuedCommand
-       {
-               Tag tag;
-               char command[15];
-               unsigned char length;
-
-               QueuedCommand();
-               QueuedCommand(GeneralCommand);
-               QueuedCommand(Locomotive &, Locomotive::Command, unsigned = 0);
-               QueuedCommand(Accessory &, Accessory::Command, unsigned = 0);
+               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::list<Locomotive *> LocomotivePtrList;
        typedef std::map<unsigned, Accessory> AccessoryMap;
        typedef std::list<Accessory *> AccessoryPtrList;
        typedef std::map<unsigned, Sensor> SensorMap;
@@ -204,23 +295,20 @@ private:
        ControlledVariable<bool> power;
 
        LocomotiveMap locomotives;
-       LocomotivePtrList refresh_cycle;
-       LocomotivePtrList::iterator next_refresh;
-       unsigned refresh_counter;
        AccessoryMap accessories;
        AccessoryPtrList accessory_queue;
        Accessory *active_accessory;
        Msp::Time::TimeStamp off_timeout;
-       std::list<QueuedCommand> command_queue;
+       std::list<PendingCommand> command_queue;
        std::list<Tag> completed_commands;
 
        SensorMap sensors;
-       unsigned n_s88_octets;
-
-       unsigned mfx_announce_serial;
-       unsigned next_mfx_address;
 
        Msp::Mutex mutex;
+       RefreshTask refresh;
+       S88Task s88;
+       MfxAnnounceTask mfx_announce;
+       MfxSearchTask mfx_search;
        ControlThread thread;
 
        static ProtocolInfo protocol_info[2];
@@ -240,18 +328,13 @@ private:
 public:
        virtual unsigned get_protocol_speed_steps(const std::string &) const;
 
+       virtual const DetectedLocomotive *enumerate_detected_locos(unsigned) const { return 0; }
        virtual unsigned add_loco(unsigned, const std::string &, const VehicleType &);
        virtual void remove_loco(unsigned);
        virtual void set_loco_speed(unsigned, unsigned);
        virtual void set_loco_reverse(unsigned, bool);
        virtual void set_loco_function(unsigned, unsigned, bool);
-private:
-       void add_loco_to_refresh(Locomotive &);
-       void remove_loco_from_refresh(Locomotive &);
-       Locomotive *get_loco_to_refresh();
-       void advance_next_refresh();
 
-public:
        virtual unsigned add_turnout(unsigned, const TrackType &);
        virtual void remove_turnout(unsigned);
        virtual void set_turnout(unsigned, unsigned);
@@ -278,8 +361,8 @@ public:
        virtual void flush();
 
 private:
-       void push_command(const QueuedCommand &);
-       bool pop_command(QueuedCommand &);
+       void push_command(const PendingCommand &);
+       bool pop_command(PendingCommand &);
        void push_completed_tag(const Tag &);
        Tag pop_completed_tag();
 };