source: trunk/FACT++/src/biasctrl.cc@ 11913

Last change on this file since 11913 was 11860, checked in by tbretz, 13 years ago
Implemented reading referencevoltages from file -- preliminary.
File size: 24.3 KB
Line 
1#include <functional>
2
3#include "Dim.h"
4#include "Event.h"
5#include "Shell.h"
6#include "StateMachineDim.h"
7#include "ConnectionUSB.h"
8#include "Configuration.h"
9#include "Console.h"
10#include "Converter.h"
11
12#include "tools.h"
13
14#include "LocalControl.h"
15
16namespace ba = boost::asio;
17namespace bs = boost::system;
18namespace dummy = ba::placeholders;
19
20using namespace std::placeholders;
21using namespace std;
22
23// ------------------------------------------------------------------------
24
25class ConnectionBias : public ConnectionUSB
26{
27 vector<uint8_t> fBuffer;
28
29 bool fIsVerbose;
30
31 enum
32 {
33 kNumBoards = 13,
34 kNumChannelsPerBoard = 32,
35 kNumChannels = kNumBoards*kNumChannelsPerBoard
36 };
37
38 enum Command_t
39 {
40 kCmdReset = 0,
41 kCmdRead = 1,
42 kCmdGlobalSet = 2,
43 kCmdChannelSet = 3,
44 kCmdPrint = 4
45 };
46
47 // Resistance in Ohm for voltage correction
48#define RESISTOR float(1000)
49
50protected:
51
52 vector<uint16_t> fVolt; // Voltage in DAC units (12bit = 90V)
53 vector<uint16_t> fRefVolt;
54
55 vector<int16_t> fCurrent; // Current in ADC units (12bit = 5mA)
56 vector<int16_t> fRefCurrent;
57
58 vector<bool> fPresent;
59
60 int fWrapCounter;
61
62
63 virtual void UpdateA()
64 {
65 }
66
67 virtual void UpdateV()
68 {
69 }
70
71private:
72 void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int type)
73 {
74 if (type==kCmdPrint && bytes_received==0 && !err)
75 {
76 Print();
77 return;
78 }
79
80 // Do not schedule a new read if the connection failed.
81 if (bytes_received==0 || err)
82 {
83 if (err==ba::error::eof)
84 Warn("Connection closed by remote host (BIAS).");
85
86 // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
87 // 125: Operation canceled
88 if (err && err!=ba::error::eof && // Connection closed by remote host
89 err!=ba::error::basic_errors::not_connected && // Connection closed by remote host
90 err!=ba::error::basic_errors::operation_aborted) // Connection closed by us
91 {
92 ostringstream str;
93 str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
94 Error(str);
95 }
96 PostClose(err!=ba::error::basic_errors::operation_aborted);
97 return;
98 }
99
100 if (bytes_received%3)
101 {
102 Error("Number of received bytes not a multiple of 3, can't read data.");
103 PostClose(true);
104 return;
105 }
106
107 if (fIsVerbose)
108 {
109 //Out() << endl << kBold << "Data received (size=" << bytes_received << "):" << endl;
110 //Out() << Converter::GetHex<uint8_t>(fBuffer, 32) << endl;
111 // FIXME: Check why more is printed than expected
112 }
113
114 const uint16_t command = type&0xf;
115 const uint16_t id = type>>4;
116 const uint16_t status = (fBuffer[0]>>7)&1;
117 const uint16_t wrap = (fBuffer[0]>>4)&7;
118 const uint16_t ddd = ((uint16_t(fBuffer[0])&0xf)<<8) | fBuffer[1];
119 const uint16_t error = (fBuffer[2]>>4)&0xf;
120 const uint16_t board = fBuffer[2]&0xf;
121
122 if (fWrapCounter>=0 && (fWrapCounter+1)%8 != wrap)
123 {
124 Error("Corrupted answer (wrap counter not as it ought to be.");
125 return;
126 }
127 fWrapCounter = wrap;
128
129 if (error==0x8) // No device
130 {
131 ostringstream out;
132 out << "HV down requested!";
133 Fatal(out);
134
135 GlobalSetDac(0);
136
137 // Resynchronize input and output
138 // SystemReset and status request
139 PostClose(true);
140
141 return;
142 }
143
144 if (command==kCmdReset)
145 {
146 if (status==0 && ddd==0 && error==0 && board==0)
147 {
148 Message("Reset successfully executed.");
149 return;
150 }
151
152 Warn("Answer to 'reset' command contains unexpected data.");
153 return;
154 }
155
156 if (command==kCmdGlobalSet)
157 {
158 if (status==0 && ddd==0 && error==0 && board==0)
159 {
160 Message("GlobalSet successfully executed.");
161 return;
162 }
163
164 Warn("Answer to 'global set' command contains unexpected data.");
165 return;
166 }
167
168 if (command==kCmdRead || command==kCmdChannelSet)
169 {
170 if (error==0x7 || error==0xf)
171 {
172 fPresent[board] = false;
173 fCurrent[id] = 0x8000;
174 return;
175 }
176
177 if (board!=id/kNumChannelsPerBoard)
178 {
179 ostringstream out;
180 out << "Talked to board " << id/kNumChannelsPerBoard << " but board " << board << " answered.";
181 Error(out);
182 return;
183 }
184
185 fCurrent[id] = status ? -ddd : ddd;
186 fPresent[board] = true;
187
188 UpdateA();
189
190 return;
191 }
192 }
193
194 // This is called when a connection was established
195 void ConnectionEstablished()
196 {
197 fWrapCounter = -1;
198 fBuffer.resize(3);
199
200 SystemReset();
201 ReadAllChannels();
202 }
203
204 void HandleReadTimeout(const bs::error_code &error)
205 {
206 if (error==ba::error::basic_errors::operation_aborted)
207 return;
208
209 if (error)
210 {
211 ostringstream str;
212 str << "Read timeout of " << URL() << ": " << error.message() << " (" << error << ")";// << endl;
213 Error(str);
214
215 PostClose();
216 return;
217 }
218
219 if (!is_open())
220 {
221 // For example: Here we could schedule a new accept if we
222 // would not want to allow two connections at the same time.
223 return;
224 }
225
226 // Check whether the deadline has passed. We compare the deadline
227 // against the current time since a new asynchronous operation
228 // may have moved the deadline before this actor had a chance
229 // to run.
230 if (fInTimeout.expires_at() > ba::deadline_timer::traits_type::now())
231 return;
232
233 Error("Timeout reading data from "+URL());
234
235 PostClose();
236 }
237
238 vector<char> GetCmd(uint16_t id, Command_t cmd, uint16_t dac=0)
239 {
240 const unsigned int board = id/kNumChannelsPerBoard;
241 const unsigned int channel = id%kNumChannelsPerBoard;
242
243 return GetCmd(board, channel, cmd, dac);
244 }
245
246 vector<char> GetCmd(uint16_t board, uint16_t channel, Command_t cmd, uint16_t dac=0)
247 {
248 vector<char> data(3);
249
250 /*
251 if (board>kNumBoards)
252 return;
253 if (channel>kNumChannelsPerBoard)
254 return;
255 if (dac>0xfff)
256 return;
257 */
258
259 data[0] = (cmd<<5) | (board<<1) | (((channel&16)>>4) & 1);
260 data[1] = (channel<<4) | (dac>>8);
261 data[2] = dac&0xff;
262
263 return data;
264 }
265
266 /*
267 void SetChannels(const map<uint16_t, uint16_t> &vals)
268 {
269 if (vals.empty())
270 return;
271
272 // Build and execute commands
273 for (map<uint16_t, uint16_t>::const_iterator it=vals.begin();
274 it!=vals.end(); it++)
275 {
276 // If DAC value unchanged, do not send command
277 if (fVolt[it->first] == it->second)
278 continue;
279
280 const vector<char> cmd = GetCmd(it->first, kCmdChannelSet, it->second);
281 PostMessage(cmd);
282 AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(it->first<<4));
283 }
284 }*/
285
286 /*
287 // ***** Synchronize board *****
288 bool Crate::Synch()
289 {
290 //############################################################
291 int Trial = 0;
292 vector<unsigned char> Data;
293
294 while(++Trial <= 3) {
295 Data = Communicate(string(1, 0));
296 if (Data.size() == 3) return true;
297 }
298 return false;
299 //############################################################
300 }
301 */
302
303public:
304 ConnectionBias(ba::io_service& ioservice, MessageImp &imp) : ConnectionUSB(ioservice, imp()),
305 fIsVerbose(true),
306 fVolt(kNumChannels),
307 fRefVolt(kNumChannels),
308 fCurrent(kNumChannels),
309 fRefCurrent(kNumChannels),
310 fPresent(kNumBoards)
311 {
312 SetLogStream(&imp);
313 }
314
315 void SystemReset()
316 {
317 Message("Sending system reset.");
318 PostMessage(GetCmd(0, kCmdReset));
319 AsyncRead(ba::buffer(fBuffer), kCmdReset);
320 }
321
322 void ReadChannel(int ch)
323 {
324 PostMessage(GetCmd(ch, kCmdRead));
325 AsyncRead(ba::buffer(fBuffer), kCmdRead|(ch<<4));
326 }
327
328
329 void ReadAllChannels()
330 {
331 Message("Requesting full system status.");
332
333 // Prepare command to read all channels
334 for (int i=0; i<kNumChannels; i++)
335 ReadChannel(i);
336
337 //vector<char> buf;
338 //AsyncRead(ba::buffer(buf), kCmdPrint);
339 }
340
341 bool GlobalSetDac(uint16_t dac)
342 {
343 if (dac>0xfff)
344 return false;
345
346 PostMessage(GetCmd(0, kCmdGlobalSet, dac));
347 AsyncRead(ba::buffer(fBuffer), kCmdGlobalSet);
348
349 ReadAllChannels();
350
351 fVolt.assign(kNumChannels, dac);
352 UpdateV();
353
354 return true;
355 }
356
357 bool GlobalSet(double voltage)
358 {
359 return GlobalSetDac(voltage*4096/90);
360 }
361
362 bool ChannelSetDac(uint16_t ch, uint16_t dac)
363 {
364 if (dac>0xfff)
365 return false;
366
367 if (ch>=kNumChannels)
368 return false;
369
370 if (fVolt[ch]==dac)
371 return true;
372
373 PostMessage(GetCmd(ch, kCmdChannelSet, dac));
374 AsyncRead(ba::buffer(fBuffer), kCmdChannelSet|(ch<<4));
375
376 ReadChannel(ch);
377
378 fVolt[ch] = dac;
379 UpdateV();
380
381 return true;
382 }
383
384 bool ChannelSet(uint16_t ch, double voltage)
385 {
386 return ChannelSetDac(ch, voltage*4096/90);
387 }
388
389 void SetVoltage(int ch, int32_t dac)
390 {
391 if (dac<0)
392 dac = 0;
393
394 if (dac>0xfff)
395 dac = 0xfff;
396
397 ChannelSetDac(ch, dac);
398 }
399
400 // ***** Correct voltages according to current *****
401 void AdaptVoltages()
402 {
403 for (int i=0; i<kNumChannels; i++)
404 {
405 if (fRefVolt[i]==0 || fCurrent[i]<0 || fRefCurrent[i]<0)
406 continue;
407
408 // Calculate difference and convert ADC units to Amp
409 // const double diffcur = (fRefCurrent[i]-fCurrent[i])*5000/4096
410 //const int32_t diffcur = int32_t(fRefCurrent[i]-fCurrent[i])*5000;
411
412 // Calculate voltage difference
413 // #define RESISTOR 1000 // Ohm
414 //const double diffvolt = diffcur*RESISTOR/1e6;
415
416 // Calculate new vlaue by onverting voltage difference to DAC units
417 //const int32_t dac = fRefVolt[i] + diffvolt*4096/90.0;
418 SetVoltage(i, fRefVolt[i] + (fRefCurrent[i]-fCurrent[i])/18);
419 }
420 }
421
422 void SetReferenceCurrent()
423 {
424 fRefCurrent = fCurrent;
425 }
426
427 bool SetReferenceVoltage(const vector<float> &volt)
428 {
429 if (volt.size()!=kNumChannels)
430 {
431 ostringstream out;
432 out << "SetReferenceVoltage - Given vector has " << volt.size() << " elements - expected " << kNumChannels << endl;
433 Error(out);
434 return false;
435 }
436
437 for (size_t i=0; i<volt.size(); i++)
438 fRefVolt[i] = volt[i]*4096/90;
439
440 return true;
441 }
442
443 void ApplyReferenceVoltage()
444 {
445 for (size_t i=0; i<fRefVolt.size(); i++)
446 SetVoltage(i, fRefVolt[i]);
447 }
448
449 void SetVerbose(bool b)
450 {
451 fIsVerbose = b;
452 }
453
454 void PrintLine(int b, int ch)
455 {
456 Out() << setw(2) << b << "|";
457
458 for (int c=ch; c<ch+8; c++)
459 {
460 const int id = c+kNumChannelsPerBoard*b;
461 Out() << " " << setw(7) << abs(fCurrent[id])*5000/4096.;
462 if (fCurrent[id]<0)
463 Out() << "!";
464 else
465 Out() << " ";
466 }
467 Out() << endl;
468
469 }
470 void Print()
471 {
472 Out() << dec << setprecision(2) << fixed;
473 for (int b=0; b<kNumBoards; b++)
474 {
475 if (!fPresent[b])
476 {
477 Out() << setw(2) << b << "-" << endl;
478 continue;
479 }
480
481 PrintLine(b, 0);
482 PrintLine(b, 8);
483 PrintLine(b, 16);
484 PrintLine(b, 24);
485 }
486 }
487};
488
489// ------------------------------------------------------------------------
490
491#include "DimDescriptionService.h"
492
493class ConnectionDimBias : public ConnectionBias
494{
495private:
496
497 DimDescribedService fDimCurrent;
498 DimDescribedService fDimVoltage;
499
500 void UpdateA()
501 {
502 fDimCurrent.Update(fCurrent);
503 }
504
505 void UpdateV()
506 {
507 fDimVoltage.Update(fVolt);
508 }
509
510public:
511 ConnectionDimBias(ba::io_service& ioservice, MessageImp &imp) :
512 ConnectionBias(ioservice, imp),
513 fDimCurrent("BIAS_CONTROL/CURRENT", "S:416", ""),
514 fDimVoltage("BIAS_CONTROL/VOLTAGE", "S:416", "")
515 {
516 }
517
518 // A B [C] [D] E [F] G H [I] J K [L] M N O P Q R [S] T U V W [X] Y Z
519};
520
521// ------------------------------------------------------------------------
522
523template <class T, class S>
524class StateMachineBias : public T, public ba::io_service, public ba::io_service::work
525{
526 int Wrap(boost::function<void()> f)
527 {
528 f();
529 return T::GetCurrentState();
530 }
531
532 function<int(const EventImp &)> Wrapper(function<void()> func)
533 {
534 return bind(&StateMachineBias::Wrap, this, func);
535 }
536
537 bool CheckEventSize(size_t has, const char *name, size_t size)
538 {
539 if (has==size)
540 return true;
541
542 ostringstream msg;
543 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
544 T::Fatal(msg);
545 return false;
546 }
547
548private:
549 S fBias;
550
551 enum states_t
552 {
553 kStateDisconnected = 1,
554 kStateConnected = 2,
555 };
556
557 int SetGlobal(const EventImp &evt)
558 {
559 if (!CheckEventSize(evt.GetSize(), "SetGlobal", 4))
560 return false;
561
562 if (!fBias.GlobalSet(evt.GetFloat()))
563 T::Error("Supplied voltage out of range (0-90)");
564
565 return T::GetCurrentState();
566 }
567
568 int SetGlobalDac(const EventImp &evt)
569 {
570 if (!CheckEventSize(evt.GetSize(), "SetGlobalDac", 2))
571 return false;
572
573 if (!fBias.GlobalSetDac(evt.GetUShort()))
574 T::Error("Supplied voltage out of range (0-90)");
575
576 return T::GetCurrentState();
577 }
578
579 int SetChannel(const EventImp &evt)
580 {
581 if (!CheckEventSize(evt.GetSize(), "SetChannel", 6))
582 return false;
583
584 if (!fBias.ChannelSet(evt.GetUShort(), evt.Get<float>(2)))
585 T::Error("Value out of range");
586
587 return T::GetCurrentState();
588 }
589
590 int SetChannelDac(const EventImp &evt)
591 {
592 if (!CheckEventSize(evt.GetSize(), "SetChannelDac", 4))
593 return false;
594
595 if (!fBias.ChannelSetDac(evt.Get<uint16_t>(), evt.Get<uint16_t>(2)))
596 T::Error("Value out of range");
597
598 return T::GetCurrentState();
599 }
600
601
602 int Disconnect()
603 {
604 // Close all connections
605 fBias.PostClose(false);
606
607 /*
608 // Now wait until all connection have been closed and
609 // all pending handlers have been processed
610 poll();
611 */
612
613 return T::GetCurrentState();
614 }
615
616 int Reconnect(const EventImp &evt)
617 {
618 // Close all connections to supress the warning in SetEndpoint
619 fBias.PostClose(false);
620
621 // Now wait until all connection have been closed and
622 // all pending handlers have been processed
623 poll();
624
625 if (evt.GetBool())
626 fBias.SetEndpoint(evt.GetString());
627
628 // Now we can reopen the connection
629 fBias.PostClose(true);
630
631 return T::GetCurrentState();
632 }
633
634 int Execute()
635 {
636 // Dispatch (execute) at most one handler from the queue. In contrary
637 // to run_one(), it doesn't wait until a handler is available
638 // which can be dispatched, so poll_one() might return with 0
639 // handlers dispatched. The handlers are always dispatched/executed
640 // synchronously, i.e. within the call to poll_one()
641 poll_one();
642
643 return fBias.IsConnected() ? kStateConnected : kStateDisconnected;
644 }
645
646 int SetVerbosity(const EventImp &evt)
647 {
648 if (!CheckEventSize(evt.GetSize(), "SetVerbosity", 1))
649 return T::kSM_FatalError;
650
651 fBias.SetVerbose(evt.GetBool());
652
653 return T::GetCurrentState();
654 }
655
656public:
657 StateMachineBias(ostream &out=cout) :
658 T(out, "BIAS_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
659 fBias(*this, *this)
660 {
661 // ba::io_service::work is a kind of keep_alive for the loop.
662 // It prevents the io_service to go to stopped state, which
663 // would prevent any consecutive calls to run()
664 // or poll() to do nothing. reset() could also revoke to the
665 // previous state but this might introduce some overhead of
666 // deletion and creation of threads and more.
667
668 // State names
669 AddStateName(kStateDisconnected, "Disconnected",
670 "Bias-power supply not connected via USB.");
671
672 AddStateName(kStateConnected, "Connected",
673 "USB connection to bias-power supply established.");
674
675 // Verbosity commands
676 T::AddEvent("SET_VERBOSE", "B")
677 (bind(&StateMachineBias::SetVerbosity, this, _1))
678 ("set verbosity state"
679 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
680
681 // Conenction commands
682 AddEvent("DISCONNECT", kStateConnected)
683 (bind(&StateMachineBias::Disconnect, this))
684 ("disconnect from ethernet");
685
686 AddEvent("RECONNECT", "O", kStateDisconnected, kStateConnected)
687 (bind(&StateMachineBias::Reconnect, this, _1))
688 ("(Re)connect ethernet connection to FTM, a new address can be given"
689 "|[host][string]:new ethernet address in the form <host:port>");
690
691
692 AddEvent("REQUEST_STATUS", kStateConnected)
693 (Wrapper(bind(&ConnectionBias::ReadAllChannels, &fBias)))
694 ("");
695
696 AddEvent("SET_GLOBAL_VOLTAGE", "F:1", kStateConnected)
697 (bind(&StateMachineBias::SetGlobal, this, _1))
698 ("");
699
700 AddEvent("SET_GLOBAL_DAC", "S:1", kStateConnected)
701 (bind(&StateMachineBias::SetGlobalDac, this, _1))
702 ("");
703
704 AddEvent("SET_CHANNEL_VOLTAGE", "S:1;F:1", kStateConnected)
705 (bind(&StateMachineBias::SetChannel, this, _1))
706 ("");
707
708 AddEvent("SET_CHANNEL_DAC", "S:1;S:1", kStateConnected)
709 (bind(&StateMachineBias::SetChannelDac, this, _1))
710 ("");
711
712 AddEvent("RESET", kStateConnected)
713 (Wrapper(bind(&ConnectionBias::SystemReset, &fBias)))
714 ("");
715
716 AddEvent("SET_REFERENCE_CURRENT", kStateConnected)
717 (Wrapper(bind(&ConnectionBias::SetReferenceCurrent, &fBias)))
718 ("");
719
720 AddEvent("APPLY_REFERENCE_VOLTAGE", kStateConnected)
721 (Wrapper(bind(&ConnectionBias::ApplyReferenceVoltage, &fBias)))
722 ("");
723
724 AddEvent("ADAPT_VOLTAGES", kStateConnected)
725 (Wrapper(bind(&ConnectionBias::AdaptVoltages, &fBias)))
726 ("");
727
728 AddEvent("PRINT", kStateConnected)
729 (Wrapper(bind(&ConnectionBias::Print, &fBias)))
730 ("");
731 }
732
733 int EvalOptions(Configuration &conf)
734 {
735 fBias.SetVerbose(!conf.Get<bool>("quiet"));
736
737 fBias.SetEndpoint(conf.Get<string>("dev"));
738 T::Message("Setting device to "+fBias.URL());
739
740 // --------------------------------------------------------------------------
741
742 ifstream fin("FACTmapV5.txt");
743
744 int l = 0;
745
746 vector<float> vec(ConnectionBias::kNumChannels);
747
748 string buf;
749 while (getline(fin, buf, '\n'))
750 {
751 if (l>1439)
752 break;
753
754 buf = Tools::Trim(buf);
755 if (buf[0]=='#')
756 continue;
757
758 stringstream str(buf);
759
760 int idummy, board, channel;
761 float fdummy, volt;
762
763 str >> idummy >> idummy >> idummy >> idummy >> idummy;
764 str >> volt;
765 str >> board;
766 str >> channel;
767 str >> fdummy >> fdummy >> fdummy;
768
769 if (channel+32*board>=ConnectionBias::kNumChannels)
770 {
771 T::Error("Invalid board/channel read from FACTmapV5.txt.");
772 return 1;
773 }
774
775 vec[channel+32*board] = volt;
776 l++;
777 }
778
779 if (l!=1440)
780 {
781 T::Error("Reading reference voltages from FACTmapV5.txt failed.");
782 return 2;
783 }
784
785 if (!fBias.SetReferenceVoltage(vec))
786 {
787 T::Error("Setting reference voltages failed.");
788 return 3;
789 }
790
791 // --------------------------------------------------------------------------
792
793 fBias.Connect();
794
795 return -1;
796 }
797};
798
799// ------------------------------------------------------------------------
800
801#include "Main.h"
802
803template<class T, class S, class R>
804int RunShell(Configuration &conf)
805{
806 return Main::execute<T, StateMachineBias<S, R>>(conf);
807}
808
809void SetupConfiguration(Configuration &conf)
810{
811 po::options_description control("BIAS control options");
812 control.add_options()
813 ("no-dim,d", po_bool(), "Disable dim services")
814 ("dev", var<string>("FTE00FOH"), "Device address of USB port to bias-power supply")
815 ("quiet,q", po_bool(), "Disable printing contents of all received messages (except dynamic data) in clear text.")
816 ;
817
818 conf.AddOptions(control);
819}
820
821/*
822 Extract usage clause(s) [if any] for SYNOPSIS.
823 Translators: "Usage" and "or" here are patterns (regular expressions) which
824 are used to match the usage synopsis in program output. An example from cp
825 (GNU coreutils) which contains both strings:
826 Usage: cp [OPTION]... [-T] SOURCE DEST
827 or: cp [OPTION]... SOURCE... DIRECTORY
828 or: cp [OPTION]... -t DIRECTORY SOURCE...
829 */
830void PrintUsage()
831{
832 cout <<
833 "The biasctrl controls the bias-power supply boards.\n"
834 "\n"
835 "The default is that the program is started without user intercation. "
836 "All actions are supposed to arrive as DimCommands. Using the -c "
837 "option, a local shell can be initialized. With h or help a short "
838 "help message about the usuage can be brought to the screen.\n"
839 "\n"
840 "Usage: biasctrl [-c type] [OPTIONS]\n"
841 " or: biasctrl [OPTIONS]\n";
842 cout << endl;
843}
844
845void PrintHelp()
846{
847 /* Additional help text which is printed after the configuration
848 options goes here */
849
850 /*
851 cout << "bla bla bla" << endl << endl;
852 cout << endl;
853 cout << "Environment:" << endl;
854 cout << "environment" << endl;
855 cout << endl;
856 cout << "Examples:" << endl;
857 cout << "test exam" << endl;
858 cout << endl;
859 cout << "Files:" << endl;
860 cout << "files" << endl;
861 cout << endl;
862 */
863}
864
865int main(int argc, const char* argv[])
866{
867 Configuration conf(argv[0]);
868 conf.SetPrintUsage(PrintUsage);
869 Main::SetupConfiguration(conf);
870 SetupConfiguration(conf);
871
872 if (!conf.DoParse(argc, argv, PrintHelp))
873 return -1;
874
875 //try
876 {
877 // No console access at all
878 if (!conf.Has("console"))
879 {
880 if (conf.Get<bool>("no-dim"))
881 return RunShell<LocalStream, StateMachine, ConnectionBias>(conf);
882 else
883 return RunShell<LocalStream, StateMachineDim, ConnectionDimBias>(conf);
884 }
885 // Cosole access w/ and w/o Dim
886 if (conf.Get<bool>("no-dim"))
887 {
888 if (conf.Get<int>("console")==0)
889 return RunShell<LocalShell, StateMachine, ConnectionBias>(conf);
890 else
891 return RunShell<LocalConsole, StateMachine, ConnectionBias>(conf);
892 }
893 else
894 {
895 if (conf.Get<int>("console")==0)
896 return RunShell<LocalShell, StateMachineDim, ConnectionDimBias>(conf);
897 else
898 return RunShell<LocalConsole, StateMachineDim, ConnectionDimBias>(conf);
899 }
900 }
901 /*catch (std::exception& e)
902 {
903 cerr << "Exception: " << e.what() << endl;
904 return -1;
905 }*/
906
907 return 0;
908}
Note: See TracBrowser for help on using the repository browser.