namespace Marklin {
+/**
+Driver for Uhlenbrock Intellibox. Uses the P50X binary protocol over RS232.
+
+Motorola decoders with 27 speed steps are supported by manually generating the
+commands necessary to reach the "half-steps". However, sending a rapid stream
+of speed changes to the same locomotive seems to cause excessive lag, so we
+cheat a bit; instead of sending the half-step command immediately, we send it
+with a 500ms delay, but only if no new set_loco_speed calls have occurred. As
+a downside from this accelerations and decelerations are still jerky.
+*/
class Intellibox: public Driver
{
private:
ERR_LOK_POWER_OFF,
};
+ enum Protocol
+ {
+ MM,
+ MM_27
+ };
+
struct Locomotive
{
+ Protocol protocol;
unsigned speed;
bool reverse;
unsigned funcs;
+ int pending_half_step;
+ Msp::Time::TimeStamp half_step_delay;
Locomotive();
};
int serial_fd;
bool power;
+ bool halted;
std::map<unsigned, Locomotive> locos;
std::map<unsigned, Turnout> turnouts;
std::map<unsigned, Sensor> sensors;
virtual void set_power(bool);
virtual bool get_power() const { return power; }
+ virtual void halt(bool);
+ virtual bool is_halted() const { return halted; }
- virtual void add_loco(unsigned);
+ virtual const char *enumerate_protocols(unsigned) const;
+ virtual unsigned get_protocol_speed_steps(const std::string &) const;
+ virtual void add_loco(unsigned, const std::string &);
virtual void set_loco_speed(unsigned, unsigned);
virtual void set_loco_reverse(unsigned, bool);
virtual void set_loco_function(unsigned, unsigned, bool);
virtual void flush();
private:
+ Protocol map_protocol(const std::string &) const;
void command(Command);
void command(Command, const unsigned char *, unsigned);
void command(Command, unsigned, const unsigned char *, unsigned);
void turnout_command(unsigned, bool, bool);
void process_reply(const Msp::Time::TimeStamp &);
unsigned read_all(unsigned char *, unsigned);
+ unsigned read_status(Error *);
+ void error(Command, Error);
};
} // namespace Marklin