]> git.tdb.fi Git - r2c2.git/blob - source/libmarklin/intellibox.h
Halt all trains in various unexpected situations
[r2c2.git] / source / libmarklin / intellibox.h
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #ifndef LIBMARKLIN_INTELLIBOX_H_
9 #define LIBMARKLIN_INTELLIBOX_H_
10
11 #include <map>
12 #include <msp/time/timestamp.h>
13 #include "driver.h"
14
15 namespace Marklin {
16
17 class Intellibox: public Driver
18 {
19 private:
20         enum Command
21         {
22                 CMD_LOK=0x80,
23                 CMD_LOK_STATUS=0x84,
24                 CMD_LOK_CONFIG=0x85,
25                 CMD_FUNC=0x88,
26                 CMD_FUNC_STATUS=0x8C,
27                 CMD_TURNOUT=0x90,
28                 CMD_TURNOUT_FREE=0x93,
29                 CMD_TURNOUT_STATUS=0x94,
30                 CMD_TURNOUT_GROUP_STATUS=0x95,
31                 CMD_SENSOR_STATUS=0x98,
32                 CMD_SENSOR_REPORT=0x99,
33                 CMD_SENSOR_PARAM_SET=0x9D,
34                 CMD_STATUS=0xA2,
35                 CMD_POWER_OFF=0xA6,
36                 CMD_POWER_ON=0xA7,
37                 CMD_NOP=0xC4,
38                 CMD_EVENT=0xC8,
39                 CMD_EVENT_LOK=0xC9,
40                 CMD_EVENT_TURNOUT=0xCA,
41                 CMD_EVENT_SENSOR=0xCB
42         };
43
44         enum Error
45         {
46                 ERR_NO_ERROR=0,
47                 ERR_SYS_ERROR,
48                 ERR_BAD_PARAM,
49                 ERR_POWER_OFF=0x6,
50                 ERR_NO_LOK_SPACE=0x8,  // No space in lok command buffer
51                 ERR_NO_TURNOUT_SPACE,  // No space in turnout command buffer
52                 ERR_NO_DATA,           // "no Lok status available (Lok is not in a slot)"
53                 ERR_NO_SLOT,           // "there is no slot available"
54                 ERR_BAD_LOK_ADDR,
55                 ERR_LOK_BUSY,
56                 ERR_BAD_TURNOUT_ADDR,
57                 ERR_BAD_SO_VALUE,
58                 ERR_NO_I2C_SPACE,
59                 ERR_LOW_TURNOUT_SPACE=0x40,
60                 ERR_LOK_HALTED,
61                 ERR_LOK_POWER_OFF,
62         };
63
64         struct Locomotive
65         {
66                 unsigned speed;
67                 bool reverse;
68                 unsigned funcs;
69
70                 Locomotive();
71         };
72
73         struct Turnout
74         {
75                 bool state;
76                 bool active;
77                 bool pending;
78                 Msp::Time::TimeStamp off_timeout;
79
80                 Turnout();
81         };
82
83         struct Sensor
84         {
85                 bool state;
86                 Msp::Time::TimeStamp off_timeout;
87
88                 Sensor();
89         };
90
91         struct CommandSlot
92         {
93                 Command cmd;
94                 unsigned addr;
95                 unsigned char data[8];
96                 unsigned length;
97         };
98
99         int serial_fd;
100         bool power;
101         bool halted;
102         std::map<unsigned, Locomotive> locos;
103         std::map<unsigned, Turnout> turnouts;
104         std::map<unsigned, Sensor> sensors;
105         bool update_sensors;
106         std::list<CommandSlot> queue;
107         bool command_sent;
108         Msp::Time::TimeStamp next_event_query;
109
110 public:
111         Intellibox(const std::string &);
112
113         virtual void set_power(bool);
114         virtual bool get_power() const { return power; }
115         virtual void halt(bool);
116         virtual bool is_halted() const { return halted; }
117
118         virtual void add_loco(unsigned);
119         virtual void set_loco_speed(unsigned, unsigned);
120         virtual void set_loco_reverse(unsigned, bool);
121         virtual void set_loco_function(unsigned, unsigned, bool);
122
123         virtual void add_turnout(unsigned);
124         virtual void set_turnout(unsigned, bool);
125         virtual bool get_turnout(unsigned) const;
126
127         virtual void add_sensor(unsigned);
128         virtual void set_sensor(unsigned, bool) { }
129         virtual bool get_sensor(unsigned) const;
130
131         virtual void tick();
132         virtual void flush();
133
134 private:
135         void command(Command);
136         void command(Command, const unsigned char *, unsigned);
137         void command(Command, unsigned, const unsigned char *, unsigned);
138         void loco_command(unsigned, unsigned, bool, unsigned);
139         void turnout_command(unsigned, bool, bool);
140         void process_reply(const Msp::Time::TimeStamp &);
141         unsigned read_all(unsigned char *, unsigned);
142 };
143
144 } // namespace Marklin
145
146 #endif