]> git.tdb.fi Git - r2c2.git/blob - source/serial/serial.cpp
Add a program for serial port control and associated Arduino firmware
[r2c2.git] / source / serial / serial.cpp
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 #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 Marklin;
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         rx_fill(0)
24 {
25         DataFile::load(catalogue, "locos.dat");
26
27         client.use_event_dispatcher(event_disp);
28         client.signal_train_added.connect(sigc::mem_fun(this, &Serial::train_added));
29         client.signal_error.connect(sigc::mem_fun(this, &Serial::error));
30
31         string addr_str = argv[1];
32         if(addr_str.find(':')==string::npos)
33                 addr_str += ":8315";
34         Net::SockAddr *addr = Net::resolve(addr_str);
35         client.connect(*addr);
36         delete addr;
37
38         serial_port.set_parameters("9600,8N1");
39         event_disp.add(serial_port);
40         serial_port.signal_data_available.connect(sigc::mem_fun(this, &Serial::data_available));
41 }
42
43 void Serial::tick()
44 {
45         event_disp.tick();
46 }
47
48 void Serial::train_added(NetTrain &t)
49 {
50         if(!train)
51                 set_train(&t);
52 }
53
54 void Serial::error(const string &e)
55 {
56         IO::print("%s\n", e);
57 }
58
59 void Serial::set_train(NetTrain *t)
60 {
61         train = t;
62         serial_port.write(format("A%02d", train->get_address()));
63 }
64
65 void Serial::next_train()
66 {
67         const map<unsigned, NetTrain *> &trains = client.get_trains();
68
69         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
70         ++i;
71         if(i==trains.end())
72                 i = trains.begin();
73
74         set_train(i->second);
75 }
76
77 void Serial::prev_train()
78 {
79         const map<unsigned, NetTrain *> &trains = client.get_trains();
80
81         map<unsigned, NetTrain *>::const_iterator i = trains.find(train->get_address());
82         if(i==trains.begin())
83                 i = trains.end();
84         --i;
85
86         set_train(i->second);
87 }
88
89 void Serial::data_available()
90 {
91         char c;
92         serial_port.read(&c, 1);
93         if(rx_fill==0)
94         {
95                 if(c=='S' || c=='H' || c=='L')
96                         rx_buf[rx_fill++] = c;
97                 else if(c=='R')
98                 {
99                         IO::print("Reverse\n");
100                         train->set_reverse(!train->get_reverse());
101                 }
102                 else if(c=='N')
103                         next_train();
104                 else if(c=='P')
105                         prev_train();
106         }
107         else
108         {
109                 rx_buf[rx_fill++] = c;
110                 if(rx_buf[0]=='H' && rx_fill==2)
111                 {
112                         train->set_function(rx_buf[1]-'0', true);
113                         IO::print("Func %d on\n", rx_buf[1]-'0');
114                         rx_fill = 0;
115                 }
116                 else if(rx_buf[0]=='L' && rx_fill==2)
117                 {
118                         train->set_function(rx_buf[1]-'0', false);
119                         IO::print("Func %d off\n", rx_buf[1]-'0');
120                         rx_fill = 0;
121                 }
122                 else if(rx_buf[0]=='S' && rx_fill==3)
123                 {
124                         unsigned speed = (rx_buf[1]-'0')*10+(rx_buf[2]-'0');
125                         IO::print("Set speed %d\n", speed);
126                         train->set_speed(speed);
127                         rx_fill = 0;
128                 }
129         }
130 }