3 This file is part of R²C²
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #ifndef LIBR2C2_INTELLIBOX_H_
9 #define LIBR2C2_INTELLIBOX_H_
12 #include <msp/time/timestamp.h>
18 Driver for Uhlenbrock Intellibox. Uses the P50X binary protocol over RS232.
20 Motorola decoders with 27 speed steps are supported by manually generating the
21 commands necessary to reach the "half-steps". However, sending a rapid stream
22 of speed changes to the same locomotive seems to cause excessive lag, so we
23 cheat a bit; instead of sending the half-step command immediately, we send it
24 with a 500ms delay, but only if no new set_loco_speed calls have occurred. As
25 a downside from this accelerations and decelerations are still jerky.
27 class Intellibox: public Driver
38 CMD_TURNOUT_FREE=0x93,
39 CMD_TURNOUT_STATUS=0x94,
40 CMD_TURNOUT_GROUP_STATUS=0x95,
41 CMD_SENSOR_STATUS=0x98,
42 CMD_SENSOR_REPORT=0x99,
43 CMD_SENSOR_PARAM_SET=0x9D,
50 CMD_EVENT_TURNOUT=0xCA,
60 ERR_NO_LOK_SPACE=0x8, // No space in lok command buffer
61 ERR_NO_TURNOUT_SPACE, // No space in turnout command buffer
62 ERR_NO_DATA, // "no Lok status available (Lok is not in a slot)"
63 ERR_NO_SLOT, // "there is no slot available"
69 ERR_LOW_TURNOUT_SPACE=0x40,
86 int pending_half_step;
87 Msp::Time::TimeStamp half_step_delay;
97 Msp::Time::TimeStamp off_timeout;
105 Msp::Time::TimeStamp off_timeout;
114 unsigned char data[8];
121 std::map<unsigned, Locomotive> locos;
122 std::map<unsigned, Turnout> turnouts;
123 std::map<unsigned, Sensor> sensors;
125 std::list<CommandSlot> queue;
127 Msp::Time::TimeStamp next_event_query;
130 Intellibox(const std::string &);
132 virtual void set_power(bool);
133 virtual bool get_power() const { return power; }
134 virtual void halt(bool);
135 virtual bool is_halted() const { return halted; }
137 virtual const char *enumerate_protocols(unsigned) const;
138 virtual unsigned get_protocol_speed_steps(const std::string &) const;
139 virtual void add_loco(unsigned, const std::string &);
140 virtual void set_loco_speed(unsigned, unsigned);
141 virtual void set_loco_reverse(unsigned, bool);
142 virtual void set_loco_function(unsigned, unsigned, bool);
144 virtual void add_turnout(unsigned);
145 virtual void set_turnout(unsigned, bool);
146 virtual bool get_turnout(unsigned) const;
148 virtual void add_sensor(unsigned);
149 virtual void set_sensor(unsigned, bool) { }
150 virtual bool get_sensor(unsigned) const;
153 virtual void flush();
156 Protocol map_protocol(const std::string &) const;
157 void command(Command);
158 void command(Command, const unsigned char *, unsigned);
159 void command(Command, unsigned, const unsigned char *, unsigned);
160 void loco_command(unsigned, unsigned, bool, unsigned);
161 void turnout_command(unsigned, bool, bool);
162 void process_reply(const Msp::Time::TimeStamp &);
163 unsigned read_all(unsigned char *, unsigned);
164 unsigned read_status(Error *);
165 void error(Command, Error);