-/* $Id$
-
-This file is part of R²C²
-Copyright © 2010 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
#include <fcntl.h>
#include <termios.h>
#include <sys/poll.h>
{
Turnout &turnout = turnouts[addr];
unsigned mask = (1<<turnout.bits)-1;
- if(((state^turnout.state)&mask)==0 || ((state^turnout.pending)&mask)==0)
+ if(((state^turnout.state)&mask)==0 || ((state^turnout.pending)&mask)==0 || !turnout.synced)
{
turnout.state = state;
turnout.pending = state;
for(unsigned i=0; i<turnout.bits; ++i)
if((state^turnout.state)&(1<<i))
- turnout_command(addr+i, state&(1<<i), true);
+ turnout_command(addr+i, !(state&(1<<i)), true);
}
unsigned Intellibox::get_turnout(unsigned addr) const
{
i->second.active = false;
i->second.off_timeout = Time::TimeStamp();
- turnout_command(i->first, i->second.state, false);
+ for(unsigned j=0; j<i->second.bits; ++j)
+ turnout_command(i->first+j, !(i->second.state&(1<<j)), false);
}
for(map<unsigned, Sensor>::iterator i=sensors.begin(); i!=sensors.end(); ++i)
void Intellibox::flush()
{
- Time::TimeStamp t = Time::now();
for(list<CommandSlot>::iterator i=queue.begin(); i!=queue.end(); ++i)
{
write(serial_fd, i->data, i->length);
read_all(data, 2);
unsigned addr = data[0]+((data[1]&7)<<8);
+ unsigned mask = 1;
+ for(; !turnouts[addr].bits; --addr, mask<<=1) ;
Turnout &turnout = turnouts[addr];
- turnout.state = (data[1]&0x80)!=0;
+
+ unsigned bit = !(data[1]&0x80);
+ turnout.state = (turnout.state&~mask) | (bit*mask);
turnout.pending = turnout.state;
signal_turnout.emit(addr, turnout.state);
}
unsigned addr = queue.front().addr;
unsigned mask = 1;
- while(!turnouts[addr].bits)
- {
- --addr;
- mask <<= 1;
- }
+ for(; !turnouts[addr].bits; --addr, mask<<=1) ;
Turnout &turnout = turnouts[addr];
if(err==ERR_NO_ERROR)
unsigned addr = queue.front().addr;
unsigned mask = 1;
- while(!turnouts[addr].bits)
- {
- --addr;
- mask <<= 1;
- }
+ for(; !turnouts[addr].bits; --addr, mask<<=1) ;
Turnout &turnout = turnouts[addr];
- bool state = data&0x04;
- if(state!=((turnout.state&mask)!=0))
+ bool bit = !(data&0x04);
+ if(bit!=((turnout.state&mask)!=0))
{
- turnout.state = (turnout.state&~mask) | (state ? mask : 0);
+ turnout.state = (turnout.state&~mask) | (bit*mask);
turnout.pending = turnout.state;
signal_turnout.emit(addr, turnout.state);
}
+
+ turnout.synced = true;
}
else
error(cmd, err);
unsigned speed = (data[0]<=1 ? 0 : data[0]*2/19+1);
bool reverse = !(data[1]&0x20);
- if(speed!=loco.speed || reverse!=loco.reverse)
- {
- loco.speed = speed;
- loco.reverse = reverse;
- signal_loco_speed.emit(addr, loco.speed, loco.reverse);
- }
+ bool speed_changed = (speed!=loco.speed || reverse!=loco.reverse);
+
+ loco.speed = speed;
+ loco.reverse = reverse;
unsigned funcs = (data[1]&0xF)<<1;
if(data[1]&0x10)
funcs |= 1;
- if(funcs!=loco.funcs)
- {
- unsigned changed = loco.funcs^funcs;
- loco.funcs = funcs;
- for(unsigned i=0; i<5; ++i)
- if(changed&(1<<i))
- signal_loco_function.emit(addr, i, loco.funcs&(1<<i));
- }
+ unsigned funcs_changed = loco.funcs^funcs;
+ loco.funcs = funcs;
+
+ if(speed_changed)
+ signal_loco_speed.emit(addr, loco.speed, loco.reverse);
+ for(unsigned i=0; i<5; ++i)
+ if(funcs_changed&(1<<i))
+ signal_loco_function.emit(addr, i, loco.funcs&(1<<i));
}
else
error(cmd, err);
bits(1),
state(0),
active(false),
- pending(false)
+ synced(false),
+ pending(0)
{ }