]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/arducontrol.h
Restructure ArduControl driver into more manageable units
[r2c2.git] / source / libr2c2 / arducontrol.h
index f0c14f948219afce5bea6c4e2a2559d8a606f375..d794d00cd83150e4a6bcbb9c455d5faaaf049c1a 100644 (file)
@@ -17,6 +17,7 @@ private:
        {
                POWER_ON = 0x01,
                POWER_OFF = 0x02,
+               READ_POWER_STATE = 0x03,
                READ_TRACK_CURRENT = 0x08,
                SET_OVERCURRENT_LIMIT = 0x09,
                READ_INPUT_VOLTAGE = 0x0A,
@@ -25,6 +26,14 @@ private:
                MOTOROLA_SPEED_DIRECTION = 0x13,
                MOTOROLA_SPEED_FUNCTION = 0x14,
                MOTOROLA_SOLENOID = 0x15,
+               MFX_SET_STATION_ID = 0x21,
+               MFX_ANNOUNCE = 0x22,
+               MFX_SEARCH = 0x23,
+               MFX_ASSIGN_ADDRESS = 0x24,
+               MFX_PING = 0x25,
+               MFX_SPEED = 0x28,
+               MFX_SPEED_FUNCS8 = 0x29,
+               MFX_SPEED_FUNCS16 = 0x2A,
                S88_READ = 0x30,
                COMMAND_OK = 0x80,
                RECEIVE_OVERRUN = 0x81,
@@ -35,7 +44,9 @@ private:
                OVERCURRENT = 0xA0,
                TRACK_CURRENT = 0xC0,
                INPUT_VOLTAGE = 0xC1,
-               S88_DATA = 0xD0
+               POWER_STATE = 0xC2,
+               S88_DATA = 0xD0,
+               MFX_FEEDBACK = 0xD1
        };
 
        struct Tag
@@ -66,8 +77,15 @@ private:
 
        enum Protocol
        {
-               NONE,
-               MM
+               MM,
+               MFX
+       };
+
+       struct ProtocolInfo
+       {
+               unsigned max_address;
+               unsigned max_speed;
+               unsigned max_func;
        };
 
        template<typename T>
@@ -148,11 +166,90 @@ 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:
+               ArduControl &control;
+               Locomotive *loco;
+               unsigned phase;
+
+       public:
+               RefreshTask(ArduControl &);
+
+               virtual bool get_work(PendingCommand &);
+       };
+
+       class S88Task: public Task
+       {
+       private:
+               ArduControl &control;
+               unsigned octets_remaining;
+
+       public:
+               S88Task(ArduControl &);
+
+               virtual bool get_work(PendingCommand &);
+               virtual void process_reply(const char *, unsigned);
+       };
+
+       class MfxAnnounceTask: public Task
+       {
+       private:
+               ArduControl &control;
+               Msp::Time::TimeStamp next;
+
+       public:
+               MfxAnnounceTask(ArduControl &);
+
+               virtual bool get_work(PendingCommand &);
+       };
+
+       class MfxSearchTask: public Task
+       {
+       private:
+               ArduControl &control;
+               Msp::Time::TimeStamp next;
+               unsigned size;
+               unsigned bits;
+               bool pending;
+
+       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 &);
@@ -160,18 +257,9 @@ 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);
+               bool get_work(PendingCommand &);
+               unsigned do_command(const PendingCommand &);
+               unsigned process_reply(const char *, unsigned);
        };
 
        typedef std::map<unsigned, Locomotive> LocomotiveMap;
@@ -181,7 +269,7 @@ private:
        typedef std::map<unsigned, Sensor> SensorMap;
 
        Msp::IO::Serial serial;
-       bool debug;
+       unsigned debug;
 
        ControlledVariable<bool> power;
 
@@ -193,15 +281,20 @@ private:
        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;
        ControlThread thread;
 
+       static ProtocolInfo protocol_info[2];
+
 public:
        ArduControl(const std::string &);
        ~ArduControl();
@@ -255,8 +348,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();
 };