X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Fintellibox.cpp;h=1dc2e7049c7cc2e94f3c34597872b35de5f29dd7;hb=9b05c573a38639827697fe393d55b7c76f5bde45;hp=bbe6781cd6b85d8090c3ed534989dec4460e4713;hpb=975ea87cc7be179618b06291cb2506a2523cad1f;p=r2c2.git diff --git a/source/libmarklin/intellibox.cpp b/source/libmarklin/intellibox.cpp index bbe6781..1dc2e70 100644 --- a/source/libmarklin/intellibox.cpp +++ b/source/libmarklin/intellibox.cpp @@ -96,21 +96,27 @@ void Intellibox::halt(bool h) const char *Intellibox::enumerate_protocols(unsigned i) const { - if(i==0) + if(i==MM) return "MM"; + else if(i==MM_27) + return "MM-27"; return 0; } -unsigned Intellibox::get_protocol_speed_steps(const string &proto) const +unsigned Intellibox::get_protocol_speed_steps(const string &proto_name) const { - if(proto=="MM") + Protocol proto = map_protocol(proto_name); + if(proto==MM) return 14; - else - throw InvalidParameterValue("Unknown protocol"); + else if(proto==MM_27) + return 27; + return 0; } -void Intellibox::add_loco(unsigned addr, const string &proto) +void Intellibox::add_loco(unsigned addr, const string &proto_name) { + Protocol proto = map_protocol(proto_name); + if(!locos.count(addr)) { locos[addr].protocol = proto; @@ -126,12 +132,47 @@ void Intellibox::set_loco_speed(unsigned addr, unsigned speed) { Locomotive &loco = locos[addr]; if(speed==loco.speed) + { + if(loco.pending_half_step) + { + loco.pending_half_step = 0; + loco.half_step_delay = Time::TimeStamp(); + signal_loco_speed.emit(addr, speed, loco.reverse); + } return; + } if(speed && halted) return; + if(loco.protocol==MM_27) + { + if(speed>27) + speed = 27; + + if(speed>loco.speed && !(speed&1)) + { + loco.pending_half_step = -1; + speed |= 1; + } + else if(speed14) + speed = 14; + + loco_command(addr, speed, loco.reverse, loco.funcs|0x100); + } loco.speed = speed; - loco_command(addr, speed, loco.reverse, loco.funcs|0x100); } void Intellibox::set_loco_reverse(unsigned addr, bool rev) @@ -216,6 +257,15 @@ void Intellibox::tick() command(CMD_EVENT); } + for(map::iterator i=locos.begin(); i!=locos.end(); ++i) + if(i->second.protocol==MM_27 && i->second.pending_half_step && i->second.half_step_delay && t>i->second.half_step_delay) + { + i->second.speed += i->second.pending_half_step; + i->second.pending_half_step = 0; + i->second.half_step_delay = Time::TimeStamp(); + loco_command(i->first, (i->second.speed+1)/2, i->second.reverse, i->second.funcs|0x100); + } + for(map::iterator i=turnouts.begin(); i!=turnouts.end(); ++i) if(i->second.active && i->second.off_timeout && t>i->second.off_timeout) { @@ -284,6 +334,16 @@ void Intellibox::flush() command_sent = false; } +Intellibox::Protocol Intellibox::map_protocol(const string &name) const +{ + if(name=="MM") + return MM; + else if(name=="MM-27") + return MM_27; + else + throw InvalidParameterValue("Unknown protocol"); +} + void Intellibox::command(Command cmd) { command(cmd, 0, 0); @@ -438,7 +498,9 @@ void Intellibox::process_reply(const Time::TimeStamp &t) { unsigned addr = queue.front().addr; Locomotive &loco = locos[addr]; - signal_loco_speed.emit(addr, loco.speed, loco.reverse); + signal_loco_speed.emit(addr, loco.speed+loco.pending_half_step, loco.reverse); + if(loco.pending_half_step) + loco.half_step_delay = Time::now()+500*Time::msec; } else error(cmd, err);