X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Farducontrol.h;h=c170e4203c9c2eb3de864de49d958a0a10b6e794;hb=23e1a988da2efae47e39d93babe7e37b1c0ca554;hp=2431cf927ae8d59b7dfc11a411b7e99e7159e83d;hpb=77f1712e7f8913af3ce33efc0e1e4ebbe0e5f93a;p=r2c2.git diff --git a/source/libr2c2/arducontrol.h b/source/libr2c2/arducontrol.h index 2431cf9..c170e42 100644 --- a/source/libr2c2/arducontrol.h +++ b/source/libr2c2/arducontrol.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -12,6 +14,17 @@ namespace R2C2 { class ArduControl: public Driver { +public: + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(ArduControl &); + + private: + void mfx_announce_serial(unsigned); + void mfx_locomotive(unsigned); + }; + private: enum Command { @@ -75,7 +88,8 @@ private: enum GeneralCommand { - POWER + POWER, + NEW_LOCO }; enum Protocol @@ -103,6 +117,7 @@ private: bool set(T v) { if(v==pending) return false; pending = v; ++serial; return true; } bool commit(unsigned short s) { if(s!=serial) return false; current = pending; return true; } + void rollback() { pending = current; ++serial; } operator T() const { return current; } }; @@ -130,6 +145,17 @@ private: unsigned create_speed_func_command(unsigned, char *) const; }; + struct MfxInfo: public DetectedLocomotive + { + class Loader: public Msp::DataFile::ObjectLoader + { + public: + Loader(MfxInfo &); + }; + + unsigned id; + }; + struct Accessory { enum Kind @@ -147,11 +173,13 @@ private: Kind kind; unsigned address; unsigned bits; + unsigned valid_states; ControlledVariable 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; }; @@ -182,15 +210,53 @@ private: PendingCommand(Accessory &, Accessory::Command, unsigned = 0); }; + template + class Queue + { + private: + std::list items; + Msp::Mutex mutex; + + public: + void push(const T &); + bool pop(T &); + 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 + { + private: + Queue queue; + + public: + CommandQueueTask(); + + virtual bool get_work(PendingCommand &); + + void push(const PendingCommand &); + bool empty() const { return queue.empty(); } }; class RefreshTask: public Task @@ -238,7 +304,6 @@ private: { private: unsigned serial; - Msp::Time::TimeStamp next; public: MfxAnnounceTask(); @@ -246,6 +311,7 @@ private: virtual bool get_work(PendingCommand &); void set_serial(unsigned); + unsigned get_serial() const { return serial; } }; class MfxSearchTask: public Task @@ -253,16 +319,40 @@ private: private: ArduControl &control; unsigned next_address; - Msp::Time::TimeStamp next; unsigned size; unsigned bits; unsigned misses; + Queue 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 MonitorTask: public Task + { + private: + float voltage; + float current; + float base_level; + float peak_level; + unsigned next_type; + + public: + MonitorTask(); + + virtual bool get_work(PendingCommand &); + virtual void process_reply(const char *, unsigned); + + float get_voltage() const { return voltage; } + float get_current() const { return current; } + void reset_peak(); + float get_peak() const { return peak_level-base_level; } }; class ControlThread: public Msp::Thread @@ -280,47 +370,54 @@ private: virtual void main(); void init_baud_rate(); bool get_work(PendingCommand &); - unsigned do_command(const PendingCommand &); + unsigned do_command(const PendingCommand &, const Msp::Time::TimeDelta &); unsigned process_reply(const char *, unsigned); + void set_power(bool); }; typedef std::map LocomotiveMap; + typedef std::vector MfxInfoArray; typedef std::map AccessoryMap; typedef std::list AccessoryPtrList; typedef std::map SensorMap; Msp::IO::Serial serial; unsigned debug; + Msp::FS::Path state_file; ControlledVariable power; + bool halted; LocomotiveMap locomotives; + MfxInfoArray mfx_info; AccessoryMap accessories; AccessoryPtrList accessory_queue; Accessory *active_accessory; + unsigned char active_index; Msp::Time::TimeStamp off_timeout; - std::list command_queue; - std::list completed_commands; SensorMap sensors; - Msp::Mutex mutex; + Msp::Time::TimeDelta command_timeout; + CommandQueueTask command_queue; + Queue completed_commands; RefreshTask refresh; S88Task s88; MfxAnnounceTask mfx_announce; MfxSearchTask mfx_search; + MonitorTask monitor; ControlThread thread; static ProtocolInfo protocol_info[2]; public: - ArduControl(const std::string &); + ArduControl(const Options &); ~ArduControl(); virtual void set_power(bool); virtual bool get_power() const { return power; } virtual void halt(bool); - virtual bool is_halted() const { return false; } + virtual bool is_halted() const { return halted; } virtual const char *enumerate_protocols(unsigned) const; private: @@ -328,8 +425,11 @@ private: public: virtual unsigned get_protocol_speed_steps(const std::string &) const; - virtual const DetectedLocomotive *enumerate_detected_locos(unsigned) const { return 0; } + 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); @@ -346,10 +446,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); @@ -359,12 +460,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