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

Last change on this file since 1702 was 1702, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 8.6 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 fNodes[i]->InitDevice(this);
240 if (!fNodes[i]->IsZombieNode())
241 fNodeInitialized[i] = TRUE;
242 /*else
243 fNodes[i]=NULL;*/
244 }
245 lout << "- All Nodes setup." << endl;
246}
247
248// --------------------------------------------------------------------------
249//
250// Stop all nodes calling StopDevice
251//
252void Network::StopNodes()
253{
254 for (int i=0; i<32; i++)
255 if (fNodes[i] && fNodeInitialized[i])
256 {
257 lout << "- Stopping Node #" << dec << i << endl;
258 fNodes[i]->StopDevice();
259 }
260 lout << "- All Nodes stopped." << endl;
261}
262
263// --------------------------------------------------------------------------
264//
265// returns true if one of the nodes has the error-flag set (HasError).
266//
267bool Network::HasError() const
268{
269 bool rc = false;
270
271 for (int i=0; i<32; i++)
272 {
273 if (!fNodes[i])
274 continue;
275
276 if (!fNodes[i]->HasError())
277 continue;
278
279 rc = true;
280
281 if (fNodes[i]->GetError() <= 0)
282 continue;
283
284 lout << "- Node #" << dec << i << " '" << fNodes[i]->GetNodeName();
285 lout << "' has error #" << fNodes[i]->GetError() << endl;
286 }
287
288 return rc;
289}
290
291// --------------------------------------------------------------------------
292//
293// returns true if one of the nodes is a zombie node
294//
295bool Network::HasZombie() const
296{
297 for (int i=0; i<32; i++)
298 if (fNodes[i])
299 if (fNodes[i]->IsZombieNode())
300 return true;
301
302 return false;
303}
304
305// --------------------------------------------------------------------------
306//
307// try to reboot all zombie nodes to get them working again. all other
308// nodes are left untouched.
309//
310bool Network::RebootZombies()
311{
312 lout << "- Trying to reboot all Zombies..." << endl;
313 for (int i=0; i<32; i++)
314 if (fNodes[i])
315 if (fNodes[i]->IsZombieNode())
316 if (!fNodes[i]->Reboot())
317 {
318 lout << "- Failed to reboot " << fNodes[i]->GetNodeName() << "." << endl;
319 return false;
320 }
321
322 lout << "- All Zombies rebooted." << endl;
323
324 return true;
325}
Note: See TracBrowser for help on using the repository browser.