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,
88 int pending_half_step;
89 Msp::Time::TimeStamp half_step_delay;
101 Msp::Time::TimeStamp off_timeout;
109 Msp::Time::TimeStamp off_timeout;
118 unsigned char data[8];
125 std::map<unsigned, Locomotive> locos;
126 std::map<unsigned, Turnout> turnouts;
127 std::map<unsigned, Sensor> sensors;
129 std::list<CommandSlot> queue;
131 Msp::Time::TimeStamp next_event_query;
134 Intellibox(const std::string &);
136 virtual void set_power(bool);
137 virtual bool get_power() const { return power; }
138 virtual void halt(bool);
139 virtual bool is_halted() const { return halted; }
141 virtual const char *enumerate_protocols(unsigned) const;
142 virtual unsigned get_protocol_speed_steps(const std::string &) const;
143 virtual void add_loco(unsigned, const std::string &, const VehicleType &);
144 virtual void set_loco_speed(unsigned, unsigned);
145 virtual void set_loco_reverse(unsigned, bool);
146 virtual void set_loco_function(unsigned, unsigned, bool);
148 virtual void add_turnout(unsigned, const TrackType &);
149 virtual void set_turnout(unsigned, unsigned);
150 virtual unsigned get_turnout(unsigned) const;
152 virtual void add_sensor(unsigned);
153 virtual void set_sensor(unsigned, bool) { }
154 virtual bool get_sensor(unsigned) const;
157 virtual void flush();
160 Protocol map_protocol(const std::string &) const;
161 void command(Command);
162 void command(Command, const unsigned char *, unsigned);
163 void command(Command, unsigned, const unsigned char *, unsigned);
164 void loco_command(unsigned, unsigned, bool, unsigned, bool);
165 void turnout_command(unsigned, bool, bool);
166 void process_reply(const Msp::Time::TimeStamp &);
167 unsigned read_all(unsigned char *, unsigned);
168 unsigned read_status(Error *);
169 void error(Command, Error);