source: trunk/MagicSoft/Cosy/candrv/network.cc@ 1714

Last change on this file since 1714 was 1703, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 9.0 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of Stesy, the MAGIC Steering System
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz <mailto:tbretz@uni-sw.gwdg.de>, 2001
19!
20! Copyright: MAGIC Software Development, 2000-2001
21!
22!
23\* ======================================================================== */
24
25///////////////////////////////////////////////////////////////////////
26//
27// Network
28//
29// is a collection of nodes which coordinates the network
30//
31///////////////////////////////////////////////////////////////////////
32#include "network.h"
33
34#include <iostream.h> // cout
35#include <iomanip.h> // setw, setfill
36
37ClassImp(Network);
38
39// --------------------------------------------------------------------------
40//
41// Start the canopen module
42// Initialize all nodes (calling NodeDrv::Init()
43//
44void Network::Start()
45{
46 lout << "- Starting network." << endl;
47
48 VmodIcan::Start();
49 InitNodes();
50
51 lout << "- Network started." << endl;
52}
53
54// --------------------------------------------------------------------------
55//
56// Stop all nodes, stop the can module
57//
58void Network::Stop()
59{
60 lout << "- Stopping network." << endl;
61
62 StopNodes();
63 VmodIcan::Stop();
64
65 lout << "- Network stopped." << endl;
66}
67
68// --------------------------------------------------------------------------
69//
70// Initialize the network, set all nodes to NULL (n/a)
71//
72Network::Network(const char *dev, const int baud, MLog &out) : CanOpen(dev, baud, out)
73{
74 for (int i=0; i<32; i++)
75 fNodes[i] = NULL;
76
77 lout << "- Network initialized." << endl;
78}
79
80// --------------------------------------------------------------------------
81//
82// Distributes the received SDO messages to the addressed nodes.
83// Depending on the received command either HandleSDO, HandleSDOOK or
84// HandleSDOError called.
85// HandleSDO: Handles a received value
86// HandleSDOOK: Handles the acknoledgment of a trasmitted SDO
87// HandleSDOError: Handles error occursion (see CanOpen standard)
88//
89void Network::HandleSDO(BYTE_t node, BYTE_t cmd, WORD_t idx, BYTE_t subidx, LWORD_t data, timeval_t *tv)
90{
91 switch (cmd)
92 {
93 case kSDO_TX4: // answer to 0x40 with 4 bytes of data
94 if (fNodes[node])
95 {
96 fNodes[node]->HandleSDO(idx, subidx, data, tv);
97 return;
98 }
99 break;
100
101 case kSDO_TX3: // answer to 0x40 with 2 bytes of data
102 if (fNodes[node])
103 {
104 fNodes[node]->HandleSDO(idx, subidx, data>>16, tv);
105 return;
106 }
107 break;
108
109 case kSDO_TX1: // answer to 0x40 with 1 byte of data
110 if (fNodes[node])
111 {
112 fNodes[node]->HandleSDO(idx, subidx, data>>24, tv);
113 return;
114 }
115 break;
116
117 case kSDO_TX_OK: // answer to a SDO_TX message
118 if (fNodes[node])
119 {
120 fNodes[node]->HandleSDOOK(idx, subidx);
121 return;
122 }
123 break;
124
125 case kSDO_TX_ERROR: // error message (instead of 0x60)
126 if (fNodes[node])
127 {
128 fNodes[node]->HandleSDOError(data);
129 return;
130 }
131 break;
132 }
133 cout << dec << setfill('0');
134 cout << "Node=" << (int)node << " Cmd=0x" << hex << (int)cmd << ": ";
135 cout << "Sdo=" << idx << "/" << (int)subidx << ": 0x" << setw(8) << data;
136 cout << endl;
137}
138
139// --------------------------------------------------------------------------
140//
141// Distributes PDO1 messages to the correspoding node calling HandlePDO1
142//
143void Network::HandlePDO1(BYTE_t node, BYTE_t *data, timeval_t *tv)
144{
145 if (!fNodes[node])
146 {
147 cout << "Node " << dec << (int)node << ", PDO1: " << hex;
148 for (int i=0; i<8; i++)
149 cout << " 0x" << (int)data[i];
150 cout << endl;
151 return;
152 }
153
154 fNodes[node]->HandlePDO1(data, tv);
155}
156
157// --------------------------------------------------------------------------
158//
159// Distributes PDO2 messages to the correspoding node calling HandlePDO2
160//
161void Network::HandlePDO2(BYTE_t node, BYTE_t *data, timeval_t *tv)
162{
163 if (!fNodes[node])
164 {
165 cout << "Node " << dec << (int)node << ", PDO2: " << hex;
166 for (int i=0; i<8; i++)
167 cout << " 0x" << (int)data[i];
168 cout << endl;
169 return;
170 }
171
172 fNodes[node]->HandlePDO2(data, tv);
173}
174
175// --------------------------------------------------------------------------
176//
177// Distributes PDO3 messages to the correspoding node calling HandlePDO3
178//
179void Network::HandlePDO3(BYTE_t node, BYTE_t *data, timeval_t *tv)
180{
181 if (!fNodes[node])
182 {
183 cout << "Node " << dec << (int)node << ", PDO3: " << hex;
184 for (int i=0; i<8; i++)
185 cout << " 0x" << (int)data[i];
186 cout << endl;
187 return;
188 }
189
190 fNodes[node]->HandlePDO3(data, tv);
191}
192
193// --------------------------------------------------------------------------
194//
195// Distributes PDO4 messages to the correspoding node calling HandlePDO4
196//
197void Network::HandlePDO4(BYTE_t node, BYTE_t *data, timeval_t *tv)
198{
199 if (!fNodes[node])
200 {
201 cout << "Node " << dec << (int)node << ", PDO4: " << hex;
202 for (int i=0; i<8; i++)
203 cout << " 0x" << (int)data[i];
204 cout << endl;
205 return;
206 }
207
208 fNodes[node]->HandlePDO4(data, tv);
209}
210
211// --------------------------------------------------------------------------
212//
213// Sets a node to a given nodedrv. The id is requested from the drv object.
214//
215void Network::SetNode(NodeDrv *drv)
216{
217 const BYTE_t nodeid = drv->GetId();
218
219 if (nodeid>31)
220 {
221 cout << "SetNode - Error: Only node Numbers < 32 are allowed"<< endl;
222 return;
223 }
224
225 fNodes[nodeid] = drv;
226}
227
228// --------------------------------------------------------------------------
229//
230// Initializes all nodes calling InitDevice
231//
232void Network::InitNodes()
233{
234 for (int i=0; i<32; i++)
235 if (fNodes[i])
236 {
237 lout << "- Setting up Node #" << dec << i << " (";
238 lout << fNodes[i]->GetNodeName() << ")" << endl;
239 if (fNodes[i]->InitDevice(this))
240 fNodeInitialized[i] = TRUE;
241 else
242 lout << "- " << fNodes[i]->GetNodeName() << ": InitDevice failed." << endl;
243 }
244 lout << "- All Nodes setup." << endl;
245}
246
247// --------------------------------------------------------------------------
248//
249// Stop all nodes calling StopDevice
250//
251void Network::StopNodes()
252{
253 for (int i=0; i<32; i++)
254 if (fNodes[i] && fNodeInitialized[i])
255 {
256 lout << "- Stopping Node #" << dec << i << endl;
257 fNodes[i]->StopDevice();
258 }
259 lout << "- All Nodes stopped." << endl;
260}
261
262// --------------------------------------------------------------------------
263//
264// returns true if one of the nodes has the error-flag set (HasError).
265//
266bool Network::HasError() const
267{
268 bool rc = false;
269
270 for (int i=0; i<32; i++)
271 {
272 if (!fNodes[i])
273 continue;
274
275 if (!fNodes[i]->HasError())
276 continue;
277
278 rc = true;
279
280 if (fNodes[i]->GetError() <= 0)
281 continue;
282
283 lout << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName();
284 lout << "' has error #" << fNodes[i]->GetError() << endl;
285 }
286
287 return rc;
288}
289
290// --------------------------------------------------------------------------
291//
292// returns true if one of the nodes is a zombie node
293//
294bool Network::HasZombie() const
295{
296 for (int i=0; i<32; i++)
297 if (fNodes[i])
298 if (fNodes[i]->IsZombieNode())
299 return true;
300
301 return false;
302}
303
304// --------------------------------------------------------------------------
305//
306// try to reboot all zombie nodes to get them working again. all other
307// nodes are left untouched.
308//
309bool Network::RebootZombies()
310{
311 bool rc = true;
312
313 lout << "- Trying to reboot all Zombies..." << endl;
314 for (int i=0; i<32; i++)
315 if (fNodes[i])
316 if (fNodes[i]->IsZombieNode())
317 if (!fNodes[i]->Reboot())
318 {
319 lout << "- Failed to reboot " << fNodes[i]->GetNodeName() << "." << endl;
320 rc = false;
321 }
322
323 if (rc)
324 lout << "- All Zombies rebooted." << endl;
325
326 return rc;
327}
328
329// --------------------------------------------------------------------------
330//
331// Check the connections to all nodes. (This can also mean: Validate
332// the correct setup, etc)
333//
334void Network::CheckConnections()
335{
336 for (int i=0; i<32; i++)
337 if (fNodes[i])
338 fNodes[i]->CheckConnection();
339}
340
Note: See TracBrowser for help on using the repository browser.