]> git.tdb.fi Git - r2c2.git/blob - source/serial/serial.cpp
Rename the project to R²C²
[r2c2.git] / source / serial / serial.cpp
1 /* $Id$
2
3 This file is part of R²C²
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/net/resolve.h>
9 #include "serial.h"
10
11 #include <msp/io/print.h>
12
13 using namespace std;
14 using namespace Msp;
15 using namespace R2C2;
16         
17 Application::RegApp<Serial> Serial::reg;
18
19 Serial::Serial(int, char **argv):
20         client(catalogue),
21         serial_port(argv[2]),
22         train(0),
23         reverse(false),
24         rx_fill(0)
25 {
26         DataFile::load(catalogue, "locos.dat");
27
28         client.use_event_dispatcher(event_disp);
29         client.signal_train_added.connect(sigc::mem_fun(this, &Serial::train_added));
30         client.signal_error.connect(sigc::mem_fun(this, &Serial::error));
31
32         string addr_str = argv[1];
33         if(addr_str.find(':')==string::npos)
34                 addr_str += ":8315";
35         Net::SockAddr *addr = Net::resolve(addr_str);
36         client.connect(*addr);
37         delete addr;
38
39         serial_port.set_parameters("9600,8N1");
40         event_disp.add(serial_port);
41         serial_port.signal_data_available.connect(sigc::mem_fun(this, &Serial::data_available));
42 }
43
44 void Serial::tick()
45 {
46         event_disp.tick();
47 }
48
49 void Serial::train_added(NetTrain &t)
50 {
51         if(!train)
52                 set_train(&t);
53 }
54
55 void Serial::error(const string &e)
56 {
57         IO::print("%s\n", e);
58 }
59
60 void Serial::set_train(NetTrain *t)
61 {
62         train = t;
63         serial_port.write(format("A%02d", train->get_address()));
64 }
65
66 void Serial::next_train()
67 {
68         const map<unsigned, NetTrain *> &trains = client.get_trains();
69
70         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
71         ++i;
72         if(i==trains.end())
73                 i = trains.begin();
74
75         set_train(i->second);
76 }
77
78 void Serial::prev_train()
79 {
80         const map<unsigned, NetTrain *> &trains = client.get_trains();
81
82         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
83         if(i==trains.begin())
84                 i = trains.end();
85         --i;
86
87         set_train(i->second);
88 }
89
90 void Serial::data_available()
91 {
92         char c;
93         serial_port.read(&c, 1);
94         if(rx_fill==0)
95         {
96                 if(c=='S' || c=='H' || c=='L')
97                         rx_buf[rx_fill++] = c;
98                 else if(c=='R')
99                 {
100                         IO::print("Reverse\n");
101                         reverse = !reverse;
102                         train->set_control("speed", 0);
103                 }
104                 else if(c=='N')
105                         next_train();
106                 else if(c=='P')
107                         prev_train();
108         }
109         else
110         {
111                 rx_buf[rx_fill++] = c;
112                 if(rx_buf[0]=='H' && rx_fill==2)
113                 {
114                         train->set_function(rx_buf[1]-'0', true);
115                         IO::print("Func %d on\n", rx_buf[1]-'0');
116                         rx_fill = 0;
117                 }
118                 else if(rx_buf[0]=='L' && rx_fill==2)
119                 {
120                         train->set_function(rx_buf[1]-'0', false);
121                         IO::print("Func %d off\n", rx_buf[1]-'0');
122                         rx_fill = 0;
123                 }
124                 else if(rx_buf[0]=='S' && rx_fill==3)
125                 {
126                         // XXX The firmware is still coded for speed step based control
127                         float speed = ((rx_buf[1]-'0')*10+(rx_buf[2]-'0'))*10/3.6*catalogue.get_scale();
128                         IO::print("Set speed %g\n", speed);
129                         train->set_control("speed", speed);
130                         rx_fill = 0;
131                 }
132         }
133 }