X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Farducontrol.cpp;h=1bb48d47f88eac60a301fc32720abccf33c83809;hb=f2de56825be33196785c82a1418056f9e7a34461;hp=2361d8540d561ccff6477836b36fc41ebba114dc;hpb=d5d8ee8bb873ad9833be0729d9d7336c093fef4e;p=r2c2.git diff --git a/source/libr2c2/arducontrol.cpp b/source/libr2c2/arducontrol.cpp index 2361d85..1bb48d4 100644 --- a/source/libr2c2/arducontrol.cpp +++ b/source/libr2c2/arducontrol.cpp @@ -18,11 +18,12 @@ ArduControl::ProtocolInfo ArduControl::protocol_info[2] = { 0x3FFF, 126, 15 } // MFX }; -ArduControl::ArduControl(const string &dev): - serial(dev), - debug(1), +ArduControl::ArduControl(const Options &opts): + serial(opts.get(string(), "ttyUSB0")), + debug(opts.get("debug")), state_file("arducontrol.state"), power(false), + halted(false), active_accessory(0), s88(*this), mfx_search(*this), @@ -67,8 +68,19 @@ void ArduControl::set_power(bool p) } } -void ArduControl::halt(bool) +void ArduControl::halt(bool h) { + if(h==halted) + return; + + halted = h; + if(halted) + { + for(LocomotiveMap::const_iterator i=locomotives.begin(); i!=locomotives.end(); ++i) + set_loco_speed(i->first, 0); + } + + signal_halt.emit(halted); } const char *ArduControl::enumerate_protocols(unsigned i) const @@ -146,6 +158,9 @@ void ArduControl::set_loco_speed(unsigned id, unsigned speed) if(speed>protocol_info[loco.proto].max_speed) throw invalid_argument("ArduControl::set_loco_speed"); + if(speed && halted) + return; + if(loco.speed.set(speed)) { PendingCommand cmd(loco, Locomotive::SPEED); @@ -357,9 +372,7 @@ void ArduControl::tick() Accessory &acc = i->second; if(tag.command==Accessory::ACTIVATE) - { off_timeout = Time::now()+acc.active_time; - } else if(tag.command==Accessory::DEACTIVATE) { if(acc.state.commit(tag.serial)) @@ -391,7 +404,7 @@ void ArduControl::tick() } } - while(!active_accessory && !accessory_queue.empty()) + while(power && !active_accessory && !accessory_queue.empty()) { Accessory &acc = *accessory_queue.front(); @@ -403,9 +416,12 @@ void ArduControl::tick() unsigned lowest_bit = changes&~(changes-1); unsigned i; for(i=0; (lowest_bit>>i)>1; ++i) ; + active_index = i; acc.state.set(acc.state^lowest_bit); PendingCommand cmd(acc, Accessory::ACTIVATE, i); command_queue.push(cmd); + + monitor.reset_peak(); } else accessory_queue.pop_front(); @@ -416,8 +432,23 @@ void ArduControl::tick() Time::TimeStamp t = Time::now(); if(t>off_timeout) { + Accessory &acc = *active_accessory; + + if(acc.kind==Accessory::TURNOUT && monitor.get_peak()<0.5f) + { + unsigned bit = 1<::pop(T &item) return true; } +template +bool ArduControl::Queue::empty() const +{ + return items.empty(); +} + ArduControl::RefreshTask::RefreshTask(): next(cycle.end()), @@ -721,11 +762,17 @@ void ArduControl::RefreshTask::advance() ArduControl::S88Task::S88Task(ArduControl &c): control(c), n_octets(0), - octets_remaining(0) + octets_remaining(0), + delay(0) { } bool ArduControl::S88Task::get_work(PendingCommand &cmd) { + if(delay) + { + --delay; + return false; + } if(octets_remaining || !n_octets) return false; @@ -734,6 +781,8 @@ bool ArduControl::S88Task::get_work(PendingCommand &cmd) cmd.command[1] = octets_remaining; cmd.length = 2; + delay = 4; + return true; } @@ -899,10 +948,58 @@ bool ArduControl::MfxSearchTask::pop_info(MfxInfo &info) } +ArduControl::MonitorTask::MonitorTask(): + voltage(0), + current(0), + base_level(0), + peak_level(0), + next_type(0) +{ } + +bool ArduControl::MonitorTask::get_work(PendingCommand &cmd) +{ + Time::TimeStamp t = Time::now(); + if(t(reply[1])<<8) | static_cast(reply[2]))/1000.0f; + else if(type==TRACK_CURRENT && length==5) + { + current = ((static_cast(reply[1])<<8) | static_cast(reply[2]))/1000.0f; + float peak = ((static_cast(reply[3])<<8) | static_cast(reply[4]))/1000.0f; + peak_level = max(peak_level, peak); + base_level = min(base_level, current); + } +} + +void ArduControl::MonitorTask::reset_peak() +{ + base_level = current; + peak_level = current; +} + + ArduControl::ControlThread::ControlThread(ArduControl &c): control(c), done(false) { + tasks.push_back(&control.monitor); tasks.push_back(&control.mfx_announce); tasks.push_back(&control.mfx_search); tasks.push_back(&control.s88); @@ -961,6 +1058,8 @@ void ArduControl::ControlThread::init_baud_rate() if(!rate) { + if(control.debug>=1) + IO::print("ArduControl detection failed\n"); done = true; return; }