1 #ifndef LIBR2C2_INTELLIBOX_H_
2 #define LIBR2C2_INTELLIBOX_H_
5 #include <msp/time/timestamp.h>
11 Driver for Uhlenbrock Intellibox. Uses the P50X binary protocol over RS232.
13 Motorola decoders with 27 speed steps are supported by manually generating the
14 commands necessary to reach the "half-steps". However, sending a rapid stream
15 of speed changes to the same locomotive seems to cause excessive lag, so we
16 cheat a bit; instead of sending the half-step command immediately, we send it
17 with a 500ms delay, but only if no new set_loco_speed calls have occurred. As
18 a downside from this accelerations and decelerations are still jerky.
20 class Intellibox: public Driver
31 CMD_TURNOUT_FREE=0x93,
32 CMD_TURNOUT_STATUS=0x94,
33 CMD_TURNOUT_GROUP_STATUS=0x95,
34 CMD_SENSOR_STATUS=0x98,
35 CMD_SENSOR_REPORT=0x99,
36 CMD_SENSOR_PARAM_SET=0x9D,
43 CMD_EVENT_TURNOUT=0xCA,
53 ERR_NO_LOK_SPACE=0x8, // No space in lok command buffer
54 ERR_NO_TURNOUT_SPACE, // No space in turnout command buffer
55 ERR_NO_DATA, // "no Lok status available (Lok is not in a slot)"
56 ERR_NO_SLOT, // "there is no slot available"
62 ERR_LOW_TURNOUT_SPACE=0x40,
81 int pending_half_step;
82 Msp::Time::TimeStamp half_step_delay;
94 Msp::Time::TimeStamp off_timeout;
102 Msp::Time::TimeStamp off_timeout;
111 unsigned char data[8];
118 std::map<unsigned, Locomotive> locos;
119 std::map<unsigned, Turnout> turnouts;
120 std::map<unsigned, Sensor> sensors;
122 std::list<CommandSlot> queue;
124 Msp::Time::TimeStamp next_event_query;
127 Intellibox(const std::string &);
129 virtual void set_power(bool);
130 virtual bool get_power() const { return power; }
131 virtual void halt(bool);
132 virtual bool is_halted() const { return halted; }
134 virtual const char *enumerate_protocols(unsigned) const;
135 virtual unsigned get_protocol_speed_steps(const std::string &) const;
136 virtual void add_loco(unsigned, const std::string &, const VehicleType &);
137 virtual void set_loco_speed(unsigned, unsigned);
138 virtual void set_loco_reverse(unsigned, bool);
139 virtual void set_loco_function(unsigned, unsigned, bool);
141 virtual void add_turnout(unsigned, const TrackType &);
142 virtual void set_turnout(unsigned, unsigned);
143 virtual unsigned get_turnout(unsigned) const;
145 virtual void add_sensor(unsigned);
146 virtual void set_sensor(unsigned, bool) { }
147 virtual bool get_sensor(unsigned) const;
150 virtual void flush();
153 Protocol map_protocol(const std::string &) const;
154 void command(Command);
155 void command(Command, const unsigned char *, unsigned);
156 void command(Command, unsigned, const unsigned char *, unsigned);
157 void loco_command(unsigned, unsigned, bool, unsigned, bool);
158 void turnout_command(unsigned, bool, bool);
159 void process_reply(const Msp::Time::TimeStamp &);
160 unsigned read_all(unsigned char *, unsigned);
161 unsigned read_status(Error *);
162 void error(Command, Error);