source: trunk/MagicSoft/Cosy/devdrv/dkc.cc@ 9435

Last change on this file since 9435 was 9435, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 22.0 KB
Line 
1#include "dkc.h"
2
3#include <sys/time.h> // timeval->tv_sec
4
5#include <TGLabel.h>
6
7#include "network.h"
8
9#include "MLogManip.h"
10
11#include "MString.h"
12
13ClassImp(Dkc);
14
15using namespace std;
16
17#define EXPERT
18
19Dkc::Dkc(const BYTE_t nodeid, const char *name)
20 : NodeDrv(nodeid, name), fMacId(2*nodeid+1),
21 fPdoPos1(0), fPdoPos2(0), fPosActive(0), fRpmActive(0),
22 fStatus(0), fStatusDKC(0), fStatusPdo3(0xff), fArmed(false),
23 fReport(NULL),fLabel(NULL),fUpdPos(0)
24{
25}
26
27Dkc::~Dkc()
28{
29}
30
31TString Dkc::EvalStatusDKC(UInt_t stat) const
32{
33 switch (stat)
34 {
35 case 0: return "offline";
36 case 0xa000:
37 case 0xa001:
38 case 0xa002:
39 case 0xa003: return MString::Format("Communication phase %d", stat&0xf);
40 case 0xa010: return "Drive HALT";
41 case 0xa012: return "Control and power section ready for operation";
42 case 0xa013: return "Ready for power on";
43 case 0xa100: return "Drive in Torque mode";
44 case 0xa101: return "Drive in Velocity mode";
45 case 0xa102: return "Position control mode with encoder 1";
46 case 0xa103: return "Position control mode with encoder 2";
47 case 0xa104: return "Position control mode with encoder 1, lagless";
48 case 0xa105: return "Position control mode with encoder 2, lagless";
49 case 0xa106: return "Drive controlled interpolated positioning with encoder 1";
50 case 0xa107: return "Drive controlled interpolated positioning with encoder 2";
51 case 0xa108: return "Drive controlled interpolated positioning with encoder 1, lagless";
52 case 0xa109: return "Drive controlled interpolated positioning with encoder 2, lagless";
53 //case 0xa146: return "Drive controlled interpolated relative positioning with encoder 1";
54 //case 0xa147: return "Drive controlled interpolated relative positioning with encoder 2";
55 //case 0xa148: return "Drive controlled interpolated relative positioning lagless with encoder 1";
56 //case 0xa149: return "Drive controlled interpolated relative positioning lagless with encoder 2";
57 case 0xa150: return "Drive controlled positioning with encoder 1";
58 case 0xa151: return "Drive controlled positioning with encoder 1, lagless";
59 case 0xa152: return "Drive controlled positioning with encoder 2";
60 case 0xa153: return "Drive controlled positioning with encoder 2, lagless";
61 case 0xa208: return "Jog mode positive";
62 case 0xa218: return "Jog mode negative";
63 case 0xa400: return "Automatic drive check and adjustment";
64 case 0xa401: return "Drive decelerating to standstill";
65 case 0xa800: return "Unknown operation mode";
66 case 0xc217: return "Motor encoder reading error";
67 case 0xc218: return "Shaft encoder reading error";
68 case 0xc220: return "Motor encoder initialization error";
69 case 0xc221: return "Shaft encoder initialization error";
70 case 0xc300: return "Command: set absolute measure";
71 case 0xc400: return "Switching to parameter mode";
72 case 0xc401: return "Drive active, switching mode not allowed";
73 case 0xc500: return "Error reset";
74 case 0xc600: return "Drive controlled homi*ng procedure ";
75 case 0xe225: return "Motor overload";
76 case 0xe249: return "Positioning command velocity exceeds limit bipolar";
77 case 0xe250: return "Drive overtemp warning";
78 case 0xe251: return "Motor overtemp warning";
79 case 0xe252: return "Bleeder overtemp warning";
80 case 0xe257: return "Continous current limit active";
81 case 0xe259: return "Command velocity limit active";
82 case 0xe264: return "Target position out of numerical range";
83 case 0xe829: return "Positive position limit exceeded";
84 case 0xe830: return "Negative position limit exceeded";
85 case 0xe831: return "Position limit reached during jog";
86 case 0xe834: return "Emergency-Stop";
87 case 0xe842: return "Both end-switches activated";
88 case 0xe843: return "Positive end-switch activated";
89 case 0xe844: return "Negative end-switch activated";
90 case 0xf218: return "Amplifier overtemp shutdown";
91 case 0xf219: return "Motor overtemp shutdown";
92 case 0xf220: return "Bleeder overload shutdown";
93 case 0xf221: return "Motor temperature surveillance defective";
94 case 0xf224: return "Maximum breaking time exceeded";
95 case 0xf228: return "Excessive control deviation";
96 case 0xf250: return "Overflow of target position preset memory";
97 case 0xf269: return "Error during release of the motor holding brake";
98 case 0xf276: return "Absolute encoder out of allowed window";
99 case 0xf409: return "Bus error on Profibus interface";
100 case 0xf434: return "Emergency-Stop";
101 case 0xf629: return "Positive position limit exceeded";
102 case 0xf630: return "Negative position limit exceeded";
103 case 0xf634: return "Emergency-Stop";
104 case 0xf643: return "Positive end-switch activated";
105 case 0xf644: return "Negative end-switch activated";
106 case 0xf870: return "24V DC error";
107 case 0xf878: return "Velocity loop error";
108 }
109 return "unknown";
110}
111
112TString Dkc::GetStatus(LWORD_t val) const
113{
114 const Int_t errnum = val&0xffff;
115 const Int_t errinf = val>>16;
116
117 if (errnum!=0xff)
118 return "";
119
120 // DKC offline. This is a fatal error
121 if (errinf==0)
122 return "offline.";
123
124 TString str;
125
126 const Int_t type = errinf&0xf000;
127 switch (type)
128 {
129 case 0xf000: str += "ERROR"; break;
130 case 0xe000: str += "WARNING"; break;
131 case 0xa000: str += "Status"; break;
132 case 0xc000:
133 case 0xd000: str += "Message"; break;
134 default: str += "Unknown"; break;
135 }
136
137 str += " (";
138 str += MString::Format("%X", errinf);
139 str += "): ";
140 str += EvalStatusDKC(errinf);
141 str += (type==0xf000 || type==0xe000 ? "!" : ".");
142
143 return str;
144}
145
146Bool_t Dkc::PrintStatus(LWORD_t val) const
147{
148 const Int_t errnum = val&0xffff;
149 const Int_t errinf = val>>16;
150
151 if (errnum!=0xff)
152 return errnum==0;
153
154 gLog << all << MTime(-1) << ": " << GetNodeName() << " " << GetStatus(val) << endl;
155
156 // errinf==0: DKC offline. This is a fatal error
157 return errinf==0 ? kFALSE : (errinf&0xf000)!=0xf000;
158}
159
160void Dkc::HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, const timeval_t &tv)
161{
162 // cout << "SdoRx: Idx=0x"<< hex << idx << "/" << (int)subidx;
163 // cout << ", val=0x" << val << endl;
164 switch (idx)
165 {
166 case 0x1000:
167 if (subidx==1)
168 {
169 gLog << inf2 << "- " << GetNodeName() << ": Node is" << (val?" ":" not ") << "armed." << endl;
170 fArmed = val==1;
171 }
172 return;
173
174 case 0x1003:
175 // FIXME, see Init
176 if (subidx!=2)
177 return;
178 gLog << inf2 << "- " << GetNodeName() << ": Error[0]=" << hex << val << dec << endl;
179 CheckErrorDKC(val);
180 return;
181
182 case 0x100a:
183 gLog << inf2 << "- " << GetNodeName() << ": Using Software Version V" << dec << (int)(val>>16) << "." << (int)(val&0xff) << endl;
184 fSoftVersion = val;
185 return;
186
187 case 0x100b:
188 // Do not display, this is used for CheckConnection
189 // lout << "Node ID: " << dec << val << endl;
190 return;
191
192 case 0x2002:
193 gLog << inf2 << GetNodeName() << ": Current velocity: " << dec << val << endl;
194 fVel = val;
195 return;
196
197 case 0x6004:
198 if (subidx==0)
199 {
200 fPdoPos1 = (LWORDS_t)val;
201 fPdoTime1.Set(tv);
202 fHasChangedPos1 = true;
203 }
204 if (subidx==1)
205 {
206 fPdoPos2 = (LWORDS_t)val;
207 fPdoTime2.Set(tv);
208 fHasChangedPos2 = true;
209 }
210 return;
211
212 case 0x6002:
213 gLog << inf2 << "- " << GetNodeName() << ": Velocity resolution = " << dec << val << " (1rpm)" << endl;
214 fVelRes = val;
215 return;
216
217 case 0x6003:
218 gLog << inf2 << "- " << GetNodeName() << ": Maximum velocity = " << dec << val << " (100%)" << endl;
219 fVelMax = val;
220 return;
221
222 case 0x6501:
223 gLog << inf2 << "- " << GetNodeName() << ": Position resolution = " << dec << val << " ticks/revolution" << endl;
224 fPosRes = val;
225 return;
226 }
227
228 NodeDrv::HandleSDO(idx, subidx, val, tv);
229
230 // cout << "Dkc: SDO, idx=0x"<< hex << idx << "/" << (int)subidx;
231 // cout << ", val=0x"<<val<<endl;
232}
233
234void Dkc::HandleSDOOK(WORD_t idx, BYTE_t subidx, LWORD_t data, const timeval_t &tv)
235{
236 // cout << "Node #" << dec << (int)GetId() << ": Sdo=" << hex << idx << "/" << (int)subidx << " set." << endl;
237
238 // If a real drive operation is requested from the MACS and
239 // the MACS is not correctly initialized the operation is
240 // rejected. (This is expecially harmfull if the NoWait state
241 // is set incorrectly)
242 if (data)
243 SetZombie();
244
245 switch (idx)
246 {
247 case 0x1000:
248 switch (subidx)
249 {
250 case 1:
251 //lout << ddev(MLog::eGui);
252 gLog << inf2 << "- " << GetNodeName() << ": State of node set." << endl;
253 //lout << edev(MLog::eGui);
254 return;
255 }
256 break;
257
258 case 0x2002:
259 //lout << ddev(MLog::eGui);
260 gLog << inf2 << "- " << GetNodeName() << ": Velocity set." << endl;
261 //lout << edev(MLog::eGui);
262 return;
263
264 case 0x2003:
265 //lout << ddev(MLog::eGui);
266 gLog << inf2 << "- " << GetNodeName() << ": Acceleration set." << endl;
267 //lout << edev(MLog::eGui);
268 return;
269
270 case 0x3006:
271 switch (subidx)
272 {
273 case 0:
274 //lout << ddev(MLog::eGui);
275 gLog << inf2 << "- " << GetNodeName() << ": RPM mode switched." << endl;
276 //lout << edev(MLog::eGui);
277 return;
278
279 case 1:
280 /*
281 lout << ddev(MLog::eGui);
282 lout << "- Velocity set (" << GetNodeName() << ")" << endl;
283 lout << edev(MLog::eGui);
284 */
285 return;
286 }
287 break;
288
289 case 0x4000:
290 HandleNodeguard(tv);
291 return;
292
293 case 0x6000:
294 //lout << ddev(MLog::eGui);
295 gLog << inf2 << "- " << GetNodeName() << ": Rotation direction set." << endl;
296 //lout << edev(MLog::eGui);
297 return;
298
299 case 0x6002:
300 //lout << ddev(MLog::eGui);
301 gLog << inf2 << "- " << GetNodeName() << ": Velocitz resolution set." << endl;
302 //lout << edev(MLog::eGui);
303 return;
304
305 case 0x6004:
306 switch (subidx)
307 {
308 case 0:
309 //lout << ddev(MLog::eGui);
310 gLog << inf2 << "- " << GetNodeName() << ": Absolute positioning started." << endl;
311 fPosActive = kTRUE; // Make sure that the status is set correctly already before the first PDO
312 //lout << edev(MLog::eGui);
313 return;
314
315 case 1:
316 //lout << ddev(MLog::eGui);
317 gLog << inf2 << "- " << GetNodeName() << ": Relative positioning started." << endl;
318 fPosActive = kTRUE; // Make sure that the status is set correctly already before the first PDO
319 //lout << edev(MLog::eGui);
320 return;
321 }
322 break;
323
324
325 }
326 NodeDrv::HandleSDOOK(idx, subidx, data, tv);
327}
328
329void Dkc::ReqVelRes()
330{
331 gLog << inf2 << "- " << GetNodeName() << ": Requesting velocity resolution (velres, 0x6002)." << endl;
332 RequestSDO(0x6002);
333 WaitForSdo(0x6002);
334}
335
336void Dkc::ReqVelMax()
337{
338 gLog << inf2 << "- " << GetNodeName() << ": Requesting maximum velocity (velmax, 0x6003)." << endl;
339 RequestSDO(0x6003);
340 WaitForSdo(0x6003);
341}
342
343void Dkc::ReqPosRes()
344{
345 gLog << inf2 << "- " << GetNodeName() << ": Requesting position resolution (posres, 0x6501)." << endl;
346 RequestSDO(0x6501);
347 WaitForSdo(0x6501);
348}
349
350void Dkc::StartNode()
351{
352 //
353 // Switch node from pre-operational state to operational state
354 // (This is not CANOpen compatible)
355 // After this the MACS will react on real movement commands.
356 //
357 gLog << inf2 << "- " << GetNodeName() << ": Starting Node." << endl;
358 SendSDO(0x1000, 1, (LWORD_t)1);
359 WaitForSdo(0x1000, 1);
360}
361
362void Dkc::Arm()
363{
364 StartNode();
365}
366
367void Dkc::Disarm()
368{
369 gLog << inf2 << "- " << GetNodeName() << ": Stopping Node." << endl;
370 SendSDO(0x1000, 1, (LWORD_t)0);
371 WaitForSdo(0x1000, 1);
372}
373
374void Dkc::CheckConnection()
375{
376 RequestSDO(0x100b);
377 WaitForSdo(0x100b);
378}
379
380void Dkc::Init()
381{
382 //
383 // Request current error status (FIXME: is the first entry in the
384 // error list)
385 //
386 gLog << inf2 << "- " << GetNodeName() << ": Requesting Error[0]." << endl;
387 RequestSDO(0x1003, 2);
388 WaitForSdo(0x1003, 2);
389
390 /*
391 if (HasError())
392 {
393 gLog << err << "Dkc::Init: " << GetNodeName() << " has error --> ZOMBIE!" << endl;
394 SetZombie();
395 }
396 if (IsZombieNode())
397 return;
398 */
399
400 SetRpmMode(FALSE);
401
402 ReqPosRes(); // Init fVelRes
403 ReqVelRes(); // Init fVelResVelRes
404 ReqVelMax(); // Init fVelMax
405
406#ifdef EXPERT
407 StartNode();
408#endif
409
410 gLog << inf2 << "- " << GetNodeName() << ": Checking armed status." << endl;
411 RequestSDO(0x1000, 1);
412 WaitForSdo(0x1000, 1);
413}
414
415void Dkc::StopDevice()
416{
417 //
418 // FIXME: This isn't called if the initialization isn't done completely!
419 //
420
421 SetRpmMode(FALSE);
422}
423
424void Dkc::ReqPos1()
425{
426 gLog << inf2 << "- " << GetNodeName() << ": Requesting position feedback 1." << endl;
427 RequestSDO(0x6004, 0);
428 WaitForSdo(0x6004, 0);
429}
430
431void Dkc::ReqPos2()
432{
433 gLog << inf2 << "- " << GetNodeName() << ": Requesting position feedback 2." << endl;
434 RequestSDO(0x6004, 1);
435 WaitForSdo(0x6004, 1);
436}
437
438void Dkc::ReqVel()
439{
440 gLog << inf2 << "- " << GetNodeName() << ": Requesting Velocity." << endl;
441 RequestSDO(0x2002);
442 WaitForSdo(0x2002);
443}
444
445void Dkc::SetVelocity(LWORD_t vel)
446{
447 gLog << dbg << "- Setting velocity to: " << vel << endl;
448 SendSDO(0x2002, vel); // velocity
449 WaitForSdo(0x2002);
450}
451
452void Dkc::SetVelocityRel(Double_t vel)
453{
454 gLog << dbg << "- Setting velocity to: " << vel*100 << "%" << endl;
455 SendSDO(0x2002, (LWORD_t)(vel*fVelMax+0.5)); // velocity
456 WaitForSdo(0x2002);
457}
458
459void Dkc::SetAcceleration(LWORD_t acc)
460{
461 gLog << dbg << "- Setting acceleration to: " << acc << endl;
462 SendSDO(0x2003, 0, acc); // acceleration
463 WaitForSdo(0x2003, 0);
464}
465/*
466void Dkc::SetDeceleration(LWORD_t dec)
467{
468 gLog << dbg << "- Setting deceleration to: " << dec << endl;
469 SendSDO(0x2003, 1, dec);
470 WaitForSdo(0x2003, 1);
471}
472*/
473void Dkc::SetRpmMode(BYTE_t mode)
474{
475 //
476 // SetRpmMode(FALSE) stop the motor, but lets the position control unit on
477 //
478 SendSDO(0x3006, 0, mode ? string('s','t','r','t') : string('s','t','o','p'));
479 WaitForSdo(0x3006, 0);
480}
481
482void Dkc::SetRpmVelocity(LWORDS_t cvel)
483{
484 SendSDO(0x3006, 1, (LWORD_t)cvel);
485 WaitForSdo(0x3006, 1);
486}
487
488void Dkc::StartRelPos(LWORDS_t pos)
489{
490 if (!fArmed)
491 {
492 gLog << err << GetNodeName() << ": ERROR - Moving without being armed is not allowed." << endl;
493 SetZombie();
494 return;
495 }
496
497 gLog << dbg << GetNodeName() << ": Starting relative positioning by " << (LWORDS_t)pos << " ticks." << endl;
498 SendSDO(0x6004, 1, (LWORD_t)pos);
499 fPosActive = kTRUE; // Make sure that the status is set correctly already before the first PDO
500}
501
502void Dkc::StartAbsPos(LWORDS_t pos)
503{
504 if (!fArmed)
505 {
506 gLog << err << GetNodeName() << ": ERROR - Moving without being armed is not allowed." << endl;
507 SetZombie();
508 return;
509 }
510
511 gLog << dbg << GetNodeName() << ": Starting absolute positioning to " << (LWORDS_t)pos << " ticks." << endl;
512 SendSDO(0x6004, 0, (LWORD_t)pos);
513 fPosActive = kTRUE; // Make sure that the status is set correctly already before the first PDO
514}
515
516void Dkc::StartAbsPosRev(Double_t pos)
517{
518 if (!fArmed)
519 {
520 gLog << err << GetNodeName() << ": ERROR - Moving without being armed is not allowed." << endl;
521 SetZombie();
522 return;
523 }
524
525 const LWORD_t p = (LWORD_t)(pos*fPosRes+.5);
526
527 gLog << dbg << GetNodeName() << ": Starting absolute positioning to " << p << " ticks." << endl;
528 SendSDO(0x6004, 0, p);
529 fPosActive = kTRUE; // Make sure that the status is set correctly already before the first PDO
530}
531
532void Dkc::StartVelSync()
533{
534 //
535 // The syncronization mode is disabled by a 'MOTOR STOP'
536 // or by a positioning command (POSA, ...)
537 //
538 gLog << inf2 << "- " << GetNodeName() << ": Starting RPM Sync Mode." << endl;
539 SendSDO(0x3007, 0, string('s', 'y', 'n', 'c'));
540 WaitForSdo(0x3007, 0);
541}
542
543void Dkc::StartPosSync()
544{
545 //
546 // The syncronization mode is disabled by a 'MOTOR STOP'
547 // or by a positioning command (POSA, ...)
548 //
549 gLog << inf2 << "- " << GetNodeName() << ": Starting Position Sync Mode." << endl;
550 SendSDO(0x3007, 1, string('s', 'y', 'n', 'c'));
551 WaitForSdo(0x3007, 1);
552}
553
554void Dkc::SendMsg(BYTE_t data[6])
555{
556 GetNetwork()->SendCanFrame(fMacId, 0, 0, data[0], data[1], data[2], data[3], data[4], data[5]);
557}
558
559void Dkc::SendMsg(BYTE_t d0, BYTE_t d1, BYTE_t d2,
560 BYTE_t d3, BYTE_t d4, BYTE_t d5)
561{
562 GetNetwork()->SendCanFrame(fMacId, 0, 0, d0, d1, d2, d3, d4, d5);
563}
564
565void Dkc::HandlePDO1(const BYTE_t *data, const timeval_t &tv)
566{
567 // FIXME!!!! Only 0x4000 should do this to be
568 // CanOpen conform
569 //HandleNodeguard(tv);
570
571 fPdoPos1 = (data[3]<<24) | (data[2]<<16) | (data[1]<<8) | data[0];
572 fPdoTime1.Set(tv);
573 fHasChangedPos1 = true;
574
575 fPdoPos2 = (data[7]<<24) | (data[6]<<16) | (data[5]<<8) | data[4];
576 fPdoTime2.Set(tv);
577 fHasChangedPos2 = true;
578
579 if (fReport)
580 {
581 fReport->Lock("ShaftEncoder::HandlePDOType0");
582 *fReport << "FEEDBACK " << (int)GetId() << " " << fPdoTime1 << " PDO0 " << GetNodeName() << " " << fPdoPos1 << " " << fPdoPos2 << endl;
583 fReport->UnLock("ShaftEncoder::HandlePDOType0");
584 }
585}
586
587void Dkc::HandlePDO3(const BYTE_t *data, const timeval_t &tv)
588{
589 fArmed = data[2]&0x01;
590
591 if (fStatus!=data[3])
592 {
593 // data[3]&0x01; // motor not moving
594 fPosActive = data[3]&0x02; // positioning active
595 fRpmActive = data[3]&0x04; // RPM mode switched on
596 // data[3]&0x08; // - unused -
597 // data[3]&0x10; // - unused -
598 // data[3]&0x20; // - unused -
599 //fInControl = data[3]&0x40; // motor uncontrolled
600 // data[3]&0x80; // axis resetted (after errclr, motor stop, motor on)
601
602 fStatus = data[3];
603 }
604
605 if (fStatusPdo3!=data[0])
606 {
607 gLog << inf << MTime(-1) << ": " << GetNodeName() << " - PDO1 = ";
608 const Bool_t ready = data[0]&0x01;
609 const Bool_t fuse = data[0]&0x02;
610 const Bool_t emcy = data[0]&0x04;
611 const Bool_t vltg = data[0]&0x08;
612 const Bool_t mode = data[0]&0x10;
613 const Bool_t rf = data[0]&0x20;
614 const Bool_t brake = data[0]&0x40;
615 const Bool_t power = data[0]&0x80;
616 if (ready) gLog << "DKC-Ready ";
617 if (fuse) gLog << "FuseOk ";
618 if (emcy) gLog << "EmcyOk ";
619 if (vltg) gLog << "OvervoltOk ";
620 if (mode) gLog << "SwitchToManualMode ";
621 if (rf) gLog << "RF ";
622 if (brake) gLog << "BrakeOpen ";
623 if (power) gLog << "PowerOn ";
624 gLog << endl;
625
626 fStatusPdo3 = data[0];
627 }
628}
629
630void Dkc::CheckErrorDKC(LWORD_t val)
631{
632 fStatusDKC = val;
633
634 const Bool_t rc = PrintStatus(val);
635 SetError(rc ? 0 : val);
636 if (!rc)
637 SetZombie();
638}
639
640void Dkc::HandlePDO2(const BYTE_t *data, const timeval_t &tv)
641{
642 LWORDS_t errnum = (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | data[3];
643 LWORDS_t errinf = (data[4]<<24) | (data[5]<<16) | (data[6]<<8) | data[7];
644
645 // Check if the DKC changed its status message
646 if (errnum==0xff && (errinf&0xf000)<=0xe000)
647 {
648 CheckErrorDKC(errnum, errinf);
649 return;
650 }
651
652 // Check if MACS report error occursion.
653 // errnum==0 gives a sudden information that something happened. Now the
654 // microcontroller is running inside its interrupt procedure which
655 // stopped the normal program. The interrupt procedure should try to clear
656 // the error state of the hardware. This should never create a new error!
657 //
658 if (!errnum)
659 {
660 gLog << err << "- " << GetNodeName() << ": reports Error occursion." << endl;
661 gLog << "Dkc::HandlePDO2: " << GetNodeName() << " --> ZOMBIE!" << endl;
662 SetZombie();
663 SetError(-1);
664 return;
665 }
666
667 //
668 // Now the error is handled by the hardware now it is the software part
669 // to react on it. The Error flag now is set to the correct value.
670 //
671 if (GetError()>0)
672 {
673 gLog << warn << GetNodeName() << ": WARNING! Previous error #" << GetError() << " unhandled (not cleared) by software." << endl;
674
675 //
676 // If the error is unhadled and/or not cleared, don't try it again.
677 //
678 if (GetError()==errnum)
679 return;
680 }
681
682 SetError(errnum);
683
684 gLog << err << GetNodeName() << " reports: ";
685 switch (errnum)
686 {
687 case 0xff:
688 EvalStatus(errnum, errinf);
689 return;
690
691 default:
692 gLog << "Error Nr. " << dec << errnum << ", " << errinf << endl;
693 }
694}
695
696// FIXME? Handling of fIsZombie?
697void Dkc::HandleError()
698{
699 //
700 // If there is no error we must not handle anything
701 //
702 if (!HasError())
703 return;
704
705 //
706 // If the program got into the: HandleError state before the hardware
707 // has finished handeling the error we have to wait for the hardware
708 // handeling the error
709 //
710 // FIXME: Timeout???
711 //
712// while (GetError()<0)
713// usleep(1);
714
715 //
716 // After this software and hardware should be in a state so that
717 // we can go on working 'as usual' Eg. Initialize a Display Update
718 //
719 gLog << inf << GetNodeName() << " Handling Error #" << dec << GetError() << endl;
720 switch (GetError())
721 {
722 case 0xff:
723 gLog << err << "DKC error! Go and check what is going on!" << endl;
724 return;
725
726 default:
727 gLog << "- " << GetNodeName() << ": Cannot handle error #" << GetError() << endl;
728
729 }
730}
731
732void Dkc::DisplayVal()
733{
734 const LWORDS_t pos = GetPdoPos2();
735 if (IsZombieNode())
736 {
737 if (fLabel)
738 fLabel->SetText(new TGString(""));
739 fUpdPos = ~pos;
740 return;
741 }
742
743 char text[21]="";
744 if (pos!=fUpdPos && fLabel)
745 {
746 sprintf(text, "%ld", pos);
747 fLabel->SetText(new TGString(text));
748 fUpdPos = pos;
749 }
750}
Note: See TracBrowser for help on using the repository browser.