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;
95 Msp::Time::TimeStamp off_timeout;
103 Msp::Time::TimeStamp off_timeout;
112 unsigned char data[8];
116 Msp::IO::Serial serial;
119 std::map<unsigned, Locomotive> locos;
120 std::map<unsigned, Turnout> turnouts;
121 std::map<unsigned, Sensor> sensors;
123 std::list<CommandSlot> queue;
125 Msp::Time::TimeStamp next_event_query;
128 Intellibox(const std::string &);
130 virtual void set_power(bool);
131 virtual bool get_power() const { return power; }
132 virtual void halt(bool);
133 virtual bool is_halted() const { return halted; }
135 virtual const char *enumerate_protocols(unsigned) const;
136 virtual unsigned get_protocol_speed_steps(const std::string &) const;
137 virtual void add_loco(unsigned, const std::string &, const VehicleType &);
138 virtual void set_loco_speed(unsigned, unsigned);
139 virtual void set_loco_reverse(unsigned, bool);
140 virtual void set_loco_function(unsigned, unsigned, bool);
142 virtual void add_turnout(unsigned, const TrackType &);
143 virtual void set_turnout(unsigned, unsigned);
144 virtual unsigned get_turnout(unsigned) const;
146 virtual void add_sensor(unsigned);
147 virtual void set_sensor(unsigned, bool) { }
148 virtual bool get_sensor(unsigned) const;
151 virtual void flush();
154 Protocol map_protocol(const std::string &) const;
155 void command(Command);
156 void command(Command, const unsigned char *, unsigned);
157 void command(Command, unsigned, const unsigned char *, unsigned);
158 void loco_command(unsigned, unsigned, bool, unsigned, bool);
159 void turnout_command(unsigned, bool, bool);
160 void process_reply(const Msp::Time::TimeStamp &);
161 unsigned read_all(unsigned char *, unsigned);
162 unsigned read_status(Error *);
163 void error(Command, Error);