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