+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
#include <msp/time/timer.h>
#include <msp/time/units.h>
#include "command.h"
#include "constants.h"
#include "control.h"
#include "locomotive.h"
+#include "reply.h"
using namespace std;
using namespace Msp;
namespace Marklin {
-Locomotive::Locomotive(Control &c, unsigned a):
+Locomotive::Locomotive(const LocoType &t, Control &c, unsigned a):
+ type(t),
control(c),
addr(a),
speed(0),
void Locomotive::set_speed(unsigned spd)
{
- speed=min(spd, 14U);
+ spd = min(spd, 14U);
+ signal_speed_changing.emit(spd);
+ speed = spd;
send_command(false);
signal_speed_changed.emit(speed);
}
else
{
- reverse=rev;
+ reverse = rev;
send_command(false);
+ signal_reverse_changed.emit(reverse);
}
}
void Locomotive::set_function(unsigned func, bool state)
{
if(state)
- funcs|=1<<func;
+ funcs |= 1<<func;
else
- funcs&=~(1<<func);
+ funcs &= ~(1<<func);
send_command(true);
+
+ signal_function_changed.emit(func, state);
}
void Locomotive::refresh_status()
{
- char cmd[3];
- cmd[0]=CMD_LOK_STATUS;
- cmd[1]=addr&0xFF;
- cmd[2]=(addr>>8)&0xFF;
- control.command(string(cmd, 3)).signal_done.connect(sigc::mem_fun(this, &Locomotive::status_reply));
+ unsigned char data[2];
+ data[0] = addr&0xFF;
+ data[1] = (addr>>8)&0xFF;
+ control.command(CMD_LOK_STATUS, data, 2).signal_done.connect(sigc::mem_fun(this, &Locomotive::status_reply));
}
void Locomotive::send_command(bool setf)
{
- char cmd[16];
- cmd[0]=CMD_LOK;
- cmd[1]=addr&0xFF;
- cmd[2]=(addr>>8)&0xFF;
+ unsigned char data[4];
+ data[0] = addr&0xFF;
+ data[1] = (addr>>8)&0xFF;
if(speed==0)
- cmd[3]=0;
+ data[2] = 0;
else if(speed==1)
- cmd[3]=2;
+ data[2] = 2;
else
- cmd[3]=(speed*19-18)/2;
+ data[2] = (speed*19-18)/2;
- cmd[4]=(reverse?0:0x20) | ((funcs&1)?0x10:0);
+ data[3] = (reverse ? 0 : 0x20) | ((funcs&1) ? 0x10 : 0);
if(setf)
{
- cmd[4]|=0x80;
+ data[3] |= 0x80;
for(unsigned i=0; i<4; ++i)
if((funcs>>i)&2)
- cmd[4]|=(1<<i);
+ data[3] |= (1<<i);
}
- control.command(string(cmd,5));
+ control.command(CMD_LOK, data, 4);
}
-void Locomotive::status_reply(Error err, const string &reply)
+void Locomotive::status_reply(const Reply &reply)
{
- if(err==ERR_NO_ERROR)
+ if(reply.get_error()==ERR_NO_ERROR)
{
- if((unsigned char)reply[0]<=1)
- speed=0;
+ const unsigned char *data = reply.get_data();
+
+ if(data[0]<=1)
+ speed = 0;
else
- speed=(unsigned char)reply[0]*2/19+1;
- reverse=(reply[1]&0x20)?false:true;
- funcs=(reply[1]&0xF)<<1;
- if(reply[1]&0x10)
- funcs|=1;
+ speed = data[0]*2/19+1;
+
+ reverse = (data[1]&0x20) ? false : true;
+ funcs = (data[1]&0xF)<<1;
+ if(data[1]&0x10)
+ funcs |= 1;
+
+ for(unsigned i=0; i<5; ++i)
+ signal_function_changed.emit(i, (funcs>>i)&1);
}
}
bool Locomotive::reverse_timeout()
{
- reverse=!reverse;
+ reverse = !reverse;
send_command(true);
+ signal_reverse_changed.emit(reverse);
return false;
}