3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #include <msp/time/timer.h>
9 #include <msp/time/units.h>
11 #include "constants.h"
13 #include "locomotive.h"
22 Locomotive::Locomotive(const LocoType &t, Control &c, unsigned a):
30 control.add_locomotive(*this);
35 void Locomotive::set_speed(unsigned spd)
40 signal_speed_changing.emit(spd);
45 signal_speed_changed.emit(speed);
48 void Locomotive::set_reverse(bool rev)
55 control.set_timer((500+speed*150)*Time::msec).signal_timeout.connect(sigc::mem_fun(this, &Locomotive::reverse_timeout));
62 signal_reverse_changed.emit(reverse);
66 void Locomotive::set_function(unsigned func, bool state)
75 signal_function_changed.emit(func, state);
78 void Locomotive::refresh_status()
80 unsigned char data[2];
82 data[1] = (addr>>8)&0xFF;
83 control.command(CMD_LOK_STATUS, data, 2).signal_done.connect(sigc::mem_fun(this, &Locomotive::status_reply));
86 void Locomotive::send_command(bool setf)
88 unsigned char data[4];
90 data[1] = (addr>>8)&0xFF;
97 data[2] = (speed*19-18)/2;
99 data[3] = (reverse ? 0 : 0x20) | ((funcs&1) ? 0x10 : 0);
104 for(unsigned i=0; i<4; ++i)
108 control.command(CMD_LOK, data, 4);
110 if(setf && type.get_max_function()>4)
116 for(unsigned i=0; i<4; ++i)
119 control.command(CMD_LOK, data, 4);
123 void Locomotive::status_reply(const Reply &reply)
125 if(reply.get_error()==ERR_NO_ERROR)
127 const unsigned char *data = reply.get_data();
132 speed = data[0]*2/19+1;
134 reverse = (data[1]&0x20) ? false : true;
135 funcs = (data[1]&0xF)<<1;
139 for(unsigned i=0; i<5; ++i)
140 signal_function_changed.emit(i, (funcs>>i)&1);
144 bool Locomotive::reverse_timeout()
148 signal_reverse_changed.emit(reverse);
152 } // namespace Marklin