1 #ifndef LIBR2C2_INTELLIBOX_H_
2 #define LIBR2C2_INTELLIBOX_H_
5 #include <msp/io/serial.h>
6 #include <msp/time/timestamp.h>
12 Driver for Uhlenbrock Intellibox. Uses the P50X binary protocol over RS232.
14 Motorola decoders with 27 speed steps are supported by manually generating the
15 commands necessary to reach the "half-steps". However, sending a rapid stream
16 of speed changes to the same locomotive seems to cause excessive lag, so we
17 cheat a bit; instead of sending the half-step command immediately, we send it
18 with a 500ms delay, but only if no new set_loco_speed calls have occurred. As
19 a downside from this accelerations and decelerations are still jerky.
21 class Intellibox: public Driver
32 CMD_TURNOUT_FREE=0x93,
33 CMD_TURNOUT_STATUS=0x94,
34 CMD_TURNOUT_GROUP_STATUS=0x95,
35 CMD_SENSOR_STATUS=0x98,
36 CMD_SENSOR_REPORT=0x99,
37 CMD_SENSOR_PARAM_SET=0x9D,
44 CMD_EVENT_TURNOUT=0xCA,
54 ERR_NO_LOK_SPACE=0x8, // No space in lok command buffer
55 ERR_NO_TURNOUT_SPACE, // No space in turnout command buffer
56 ERR_NO_DATA, // "no Lok status available (Lok is not in a slot)"
57 ERR_NO_SLOT, // "there is no slot available"
63 ERR_LOW_TURNOUT_SPACE=0x40,
82 int pending_half_step;
83 Msp::Time::TimeStamp half_step_delay;
88 // These are used for signals as well, but Intellibox calls them turnouts.
96 Msp::Time::TimeStamp off_timeout;
105 Msp::Time::TimeStamp off_timeout;
114 unsigned char data[8];
118 Msp::IO::Serial serial;
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 unsigned add_loco(unsigned, const std::string &, const VehicleType &);
140 virtual void remove_loco(unsigned);
141 virtual void set_loco_speed(unsigned, unsigned);
142 virtual void set_loco_reverse(unsigned, bool);
143 virtual void set_loco_function(unsigned, unsigned, bool);
145 virtual unsigned add_turnout(unsigned, const TrackType &);
146 virtual void remove_turnout(unsigned);
148 unsigned add_turnout(unsigned, unsigned, bool);
149 void turnout_state_changed(unsigned, const Turnout &) const;
151 virtual void set_turnout(unsigned, unsigned);
152 virtual unsigned get_turnout(unsigned) const;
154 virtual unsigned add_signal(unsigned, const SignalType &);
155 virtual void remove_signal(unsigned);
156 virtual void set_signal(unsigned, unsigned);
157 virtual unsigned get_signal(unsigned) const;
160 virtual unsigned add_sensor(unsigned);
161 virtual void remove_sensor(unsigned);
162 virtual void set_sensor(unsigned, bool) { }
163 virtual bool get_sensor(unsigned) const;
166 virtual void flush();
169 Protocol map_protocol(const std::string &) const;
170 void command(Command);
171 void command(Command, const unsigned char *, unsigned);
172 void command(Command, unsigned, const unsigned char *, unsigned);
173 void loco_command(unsigned, unsigned, bool, unsigned, bool);
174 void turnout_command(unsigned, bool, bool);
175 void process_reply(const Msp::Time::TimeStamp &);
176 unsigned read_all(unsigned char *, unsigned);
177 unsigned read_status(Error *);
178 void error(Command, Error);