source: hvcontrol/src/ProcessIO.cc@ 100

Last change on this file since 100 was 100, checked in by ogrimm, 15 years ago
Number of HV boards (almost) unlimited.
File size: 21.8 KB
Line 
1
2/********************************************************************\
3
4 ProcessIO.cc
5
6 Main class processing user input
7
8 Sebastian Commichau, Sabrina Stark-Schneebeli, Oliver Grimm
9
10\********************************************************************/
11
12#include "ProcessIO.h"
13
14static char* state_str[] = {"active", "stopped", "n.a."};
15
16
17ProcessIO::ProcessIO(const char *ConfigFile) {
18
19 // Get program start time
20 time (&StartTime);
21
22 // Create instances
23 config = new HVConfig(ConfigFile);
24 calib = new HVCalib(config);
25 pm = new PixelMap(config->fPixMapTable);
26
27 // Initialize status variables
28 state = active;
29 Exit = false;
30 Verbose = false;
31 CmdFromSocket = false;
32 Socket = -1;
33
34 NumHVBoards = 0;
35 FirstBoard = 0;
36 LastBoard = -1;
37 FirstChain = 0;
38 LastChain = NUM_CHAINS-1;
39
40 if (config->fStatusRefreshRate >= MIN_RATE && config->fStatusRefreshRate <= MAX_RATE)
41 fStatusRefreshRate = config->fStatusRefreshRate;
42 else fStatusRefreshRate = 1.;
43
44 // Open HV devices
45 fHVBoard = new HVBoard* [config->NumHVBoards];
46 for (int i=0; i<config->NumHVBoards; i++) {
47 fHVBoard[NumHVBoards] = new HVBoard(i, config->fUSBDevice[i], this);
48 if(fHVBoard[NumHVBoards]->fDescriptor >= 0) {
49 printf("Synchronized and reset HV board %d (%s)\n",i,config->fUSBDevice[i]);
50 NumHVBoards++;
51 }
52 else {
53 printf("Failed to synchronize to HV board %d (%s)\n",i,config->fUSBDevice[i]);
54 delete fHVBoard[NumHVBoards];
55 }
56 }
57 LastBoard = NumHVBoards-1;
58
59 // Open log file
60 if ((Logfile = fopen(config->fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", config->fLogFile);
61 PrintMessage(MsgToLog,"********** Logging started **********\n");
62
63 // Create instance of slow data class
64 SlowDataClass = new SlowData("HV", config->fSlowDir);
65 if (SlowDataClass->ErrorCode != 0) {
66 PrintMessage("Warning: Could not open slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode));
67 }
68 SlowDataClass->NewEntry("Value-Info", "Issued if new HV value set successfull: Board-Num HV-Board-Name Chain Channel DAC-Target Converted-Value");
69 SlowDataClass->NewEntry("Error-Info", "Issued if error occurs when trying to set new HV value: Board-Num HV-Board-Name Chain Channel Attempted-DAC-Target Converted-Value");
70}
71
72
73ProcessIO::~ProcessIO() {
74
75 delete SlowDataClass;
76
77 for (int i=0; i<NumHVBoards; i++) delete fHVBoard[i];
78 delete[] fHVBoard;
79
80 delete pm; delete calib; delete config;
81
82 if(Logfile != NULL) {
83 if(fclose(Logfile) != 0) perror("Error closing logfile");
84 }
85}
86
87
88// Process user input
89void ProcessIO::CommandControl(char *Command) {
90
91 if (strlen(Command)==0) return; // Ignore empty commands
92
93 if(Command[0]=='.') { // Shell command
94 system(&(Command[1]));
95 return;
96 }
97
98 for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = ""; // All pointers point initially to empty string
99 NParam = ParseInput(Command, Param);
100
101 // Adress HV board
102 if (Match(Param[0], "board")) {
103
104 if (!NumHVBoards) return;
105
106 // Print list of boards
107 if (NParam == 1) {
108 for (int i=0; i<NumHVBoards; i++) {
109 PrintMessage("Board %d: %s\n", fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName);
110 }
111 return;
112 }
113
114 //Select board(s)
115 if (Match(Param[1],"all")) {
116 FirstBoard = 0;
117 LastBoard = NumHVBoards-1;
118 }
119 else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards) {
120 FirstBoard = atoi(Param[1]);
121 LastBoard = FirstBoard;
122 }
123 else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards &&
124 atoi(Param[2])>0 && atoi(Param[2])<NumHVBoards) {
125 FirstBoard = atoi(Param[1]);
126 LastBoard = atoi(Param[2]);
127 }
128 else PrintMessage("Cannot address board(s), out of range.\n");
129
130 return;
131 }
132
133
134 // Adress chains
135 else if (Match(Param[0], "chain")) {
136
137 if (!NumHVBoards) return;
138
139 if (Match(Param[1],"all")) {
140 FirstChain = 0;
141 LastChain = 3;
142 }
143 else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NUM_CHAINS) {
144 FirstChain = atoi(Param[1]);
145 LastChain = FirstChain;
146 }
147 else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<NUM_CHAINS &&
148 atoi(Param[2])>0 && atoi(Param[2])<NUM_CHAINS) {
149 FirstChain = atoi(Param[1]);
150 LastChain = atoi(Param[2]);
151 }
152 else PrintMessage("Cannot address chain(s), out of range.\n");
153
154 return;
155 }
156
157
158 // Print HV utility configuration
159 else if (Match(Param[0], "config")) {
160 PrintMessage( " Log file: %s\n"
161 " Pixel map table: %s\n"
162 " %d USB devices:\n", config->fLogFile, config->fPixMapTable,
163 config->NumHVBoards);
164 for (int i=0; i<config->NumHVBoards; i++) {
165 PrintMessage(" Board %d: %s\n ", i, config->fUSBDevice[i]);
166 }
167 PrintMessage( " TimeOut: %.2f s\n"
168 " StatusRefreshRate: %.2f Hz\n"
169 " CCPort: %d\n"
170 " DACMin value: %d\n"
171 " DACMax value: %d\n"
172 " HVCalibOffset : %f\n"
173 " HVCalibSlope : %f\n"
174 " HVMaxDiff : %u\n", config->fTimeOut,
175 config->fStatusRefreshRate, config->fCCPort, config->DACMin,
176 config->DACMax, config->fHVCalibOffset, config->fHVCalibSlope,
177 config->fHVMaxDiff);
178
179 return;
180 }
181
182
183 // Print help
184 if (Match(Param[0], "help")) {
185 puts(" board <i>|<i> <j>|<all> Address board i, boards i-j or all boards or list boards");
186 puts(" chain <i>|<i> <j>|<all> Address chain i, chains i-j or all chains");
187 puts(" hv <PXL id>|<ch>|<all> <v> Set HV of pixel ID, ch. or all ch. of active chain(s)/board(s)");
188 puts(" hvdiff <PXL id>|<ch>|<all> <diff> Change HV by <diff>");
189 puts(" status [dac] Show status information (DAC values if requested)");
190 puts(" config Print configuration");
191 puts(" load <file> Load HV settings from <file>");
192 puts(" save <file> Save current HV settings to [file]");
193 puts(" exit Exit program");
194 puts(" rate <rate> Set status refresh rate to <rate> [Hz]");
195 puts(" timeout <time> Set timeout to return from read to <time> [s]");
196 puts(" reset Reset active HV board");
197 puts(" start Start HV status monitor");
198 puts(" stop Stop HV status monitor - not recommended!");
199 puts(" uptime Get program uptime [h:m:s]");
200 puts(" verbose <on|off>| Enable|disable verbosity");
201 puts(" help Print help");
202 puts(" .<cmd> Execute shell command <cmd>");
203
204 return;
205 }
206
207
208 // Set new high voltage (if no boards available, simply returns OK)
209 // First reponse to socket should be 'OK' if no error occurred.
210 if (Match(Param[0], "hv") || Match(Param[0], "hvdiff")) {
211
212 int hvoltage, DACValue, Errors=0, Board=-1, Chain=-1, Channel=-1;
213 double hvoltageV;
214 bool SetDac;
215
216 // Need two or parameters
217 if (NParam<3 || NParam>4) {
218 PrintMessage("Usage: hv/hvdiff <channel>|<all> <voltage> [dac]\n");
219 return;
220 }
221
222 // Evaluate voltage parameter
223 if (NParam==4 && Match(Param[3], "dac")) {
224 SetDac = true;
225 if (!ConvertToInt(Param[2], &hvoltage)) {
226 PrintMessage("Error: Wrong number format for DAC voltage setting\n");
227 return;
228 }
229 }
230 else {
231 SetDac = false;
232 if (!ConvertToDouble(Param[2], &hvoltageV)) {
233 PrintMessage("Error: Wrong number format for voltage setting\n");
234 return;
235 }
236 }
237
238 // Evaluate pixel or channel parameter
239 if(pm->Pixel_to_HVboard(Param[1]) != 999999999) {
240 Board = pm->Pixel_to_HVboard(Param[1]);
241 Chain = pm->Pixel_to_HVchain(Param[1]);
242 Channel = pm->Pixel_to_HVchannel(Param[1]);
243 }
244 else if (!Match(Param[1], "all") && !ConvertToInt(Param[1], &Channel)) {
245 PrintMessage("Error: Wrong channel identification\n");
246 return;
247 }
248
249 for (int i=FirstBoard; i<=LastBoard; i++) {
250 if (i!=Board && Board!=-1) continue;
251
252 for (int j=FirstChain; j<=LastChain; j++) {
253 if (j!=Chain && Chain!=-1) continue;
254
255 for (int k=0; k<NUM_CHANNELS; k++) {
256 if (k!=Channel && Channel!=-1) continue;
257
258 // Convert from HV to DAC values
259 if (!SetDac){
260 if(strlen(Param[0]) > 2) fHVBoard[i]->HVV[j][k] += hvoltageV; // hvdiff
261 else fHVBoard[i]->HVV[j][k] = hvoltageV;
262 DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
263 }
264 else {
265 if(strlen(Param[0]) > 2) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // hvdiff
266 else DACValue = hvoltage;
267 }
268
269 // Set new voltage (if DAC value, update calibrated value)
270 if(!RampVoltage(DACValue, i, j, k)) Errors++;
271 if(SetDac) fHVBoard[i]->HVV[j][k] = calib->DACToHV(fHVBoard[i]->HV[j][k], i, j, k);
272
273 } // Channels
274 } // Chains
275 } // Boards
276
277 if (Errors > 0) PrintMessage("ERROR - Errors on %d channel(s) occurred\n", Errors);
278 else PrintMessage("OK - no errors\n");
279
280 return;
281 }
282
283
284 // Load HV settings from file
285 else if (Match(Param[0], "load")) {
286
287 char Buffer[MAX_COM_SIZE];
288 int NBoards = 0, Errors = 0, Chain, Channel;
289 unsigned int DACValue;
290 FILE *File;
291
292 if (NParam != 2) {
293 PrintMessage("Usage: load <file>\n");
294 return;
295 }
296
297 if ((File=fopen(Param[1], "r")) == NULL) {
298 PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
299 return;
300 }
301
302 while (fgets(Buffer, sizeof(Buffer), File) != NULL) {
303 for (int Board=0; Board<NumHVBoards; Board++) {
304 if (Match(fHVBoard[Board]->BoardName, Buffer)) {
305 PrintMessage("Found HV settings for board %d (%s)\n\r",fHVBoard[Board]->GetBoardNumber(), fHVBoard[Board]->BoardName);
306
307 Chain = 0; Channel = 0;
308 while (fscanf(File, "%u", &DACValue)==1 && Chain<NUM_CHAINS) {
309 if (!RampVoltage(DACValue, Board, Chain, Channel)) {
310 Errors++;
311 PrintMessage("Error: Could not ramp chain %d, channel %d\n", Chain, Channel);
312 }
313 else {
314 PrintMessage("Ramped chain %d, channel %d to %u (%.2f V) \r",
315 Chain,Channel,DACValue,calib->DACToHV(DACValue,Board,Chain,Channel));
316 }
317 fHVBoard[Board]->HVV[Chain][Channel] = calib->DACToHV(fHVBoard[Board]->HV[Chain][Channel], Board, Chain, Channel);
318 if(++Channel == NUM_CHANNELS) {
319 Chain++;
320 Channel = 0;
321 }
322 }
323 if (ferror(File) != 0) {
324 PrintMessage("Error reading DAC value from file, terminating. (%s)\n",strerror(errno));
325 return;
326 }
327 else PrintMessage("\nFinished updating board\n");
328 NBoards++;
329 }
330 } // Loop over boards
331 } // while()
332
333 if (NBoards != NumHVBoards) {
334 PrintMessage("Warning: Could not load HV settings for all connected HV boards\n");
335 }
336 else if (Errors == 0) PrintMessage("Success: Read HV settings for all connected HV boards\n");
337 if (Errors != 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);
338
339 if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n",Param[1]);
340
341 return;
342 }
343
344
345 // Set status refresh rate
346 if (Match(Param[0], "rate")) {
347
348 double Rate;
349
350 if (NParam != 2) {
351 PrintMessage("Usage: rate <Hz>\n");
352 return;
353 }
354
355 if (!ConvertToDouble(Param[1], &Rate)) {
356 PrintMessage("Error: Wrong number format\n");
357 return;
358 }
359
360 // Check limits
361 if (Rate<MIN_RATE || Rate>MAX_RATE) {
362 PrintMessage("Refresh rate out of range (min: %.2f Hz, max: %.2f Hz)\n", MIN_RATE, MAX_RATE);
363 return;
364 }
365
366 fStatusRefreshRate = Rate;
367 PrintMessage("Refresh rate set to %.2f Hz\n", fStatusRefreshRate);
368
369 return;
370 }
371
372 // Reset
373 if (Match(Param[0], "reset")) {
374
375 if (!NumHVBoards) return;
376 for (int i=FirstBoard; i<=LastBoard; i++) ResetBoard(i);
377 return;
378 }
379
380
381 // Save HV settings of all boards
382 else if (Match(Param[0], "save")) {
383
384 FILE *File;
385 time_t time_now_secs;
386 struct tm *Time;
387
388 if (NParam != 2) {
389 PrintMessage("Usage: save <Filename>\n");
390 return;
391 }
392
393 time(&time_now_secs);
394 Time = localtime(&time_now_secs);
395
396 if ((File = fopen(Param[1], "w")) == NULL) {
397 PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
398 return;
399 }
400
401 fprintf(File,"********** HV settings, %04d %02d %02d, %02d:%02d:%02d **********\n\n",
402 1900 + Time->tm_year, 1 + Time->tm_mon,
403 Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
404
405 for (int i=0; i<NumHVBoards; i++) {
406 fprintf(File, "%s\n\n", fHVBoard[i]->BoardName);
407
408 for (int j=0; j<NUM_CHAINS; j++) {
409 for (int k=0; k<NUM_CHANNELS; k++) fprintf(File,"%5d ",fHVBoard[i]->HV[j][k]);
410 fprintf(File, "\n");
411 }
412 fprintf(File, "\n");
413 }
414
415 if (fclose(File) != 0) {
416 PrintMessage("Error: Could not close file '%s' (%s)\n", Param[1], strerror(errno));
417 }
418
419 return;
420 }
421
422
423 // Start monitoring
424 else if (Match(Param[0], "start")) {
425
426 state = active;
427 pthread_kill(HVMonitor, SIGUSR1);
428 PrintMessage("Status monitoring activated\n");
429 return;
430 }
431
432
433 // Print status
434 else if (Match(Param[0], "status")) {
435
436 PrintMessage("\n Status monitor: %s\n", state_str[state]);
437 PrintMessage(" Verbose: %s\n", Verbose ? "on" : "off");
438 PrintMessage(" Status refresh rate [Hz]: %.2f\n", fStatusRefreshRate);
439 PrintMessage(" Socket state: %s\n", Socket==-1 ? "disconnected":"connected");
440 PrintMessage(" Total number of HV boards: %d\n", NumHVBoards);
441 PrintMessage(" Active HV boards: %d\n\n ", LastBoard - FirstBoard + 1);
442
443 for (int i=FirstBoard; i<=LastBoard; i++) {
444 PrintMessage(" BOARD %d (%s) Wrap counter: %s (%d) Manual reset: %s Time-out: %.2f s\n\n",
445 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
446 fHVBoard[i]->WrapOK ? "ok":"error",
447 fHVBoard[i]->LastWrapCount,
448 fHVBoard[i]->ResetButton ? "yes" : "no",
449 fHVBoard[i]->fTimeOut);
450
451 for (int j=FirstChain; j<=LastChain; j++) {
452 PrintMessage(" CHAIN %d Over-current: %s\n ", j, fHVBoard[i]->Overcurrent[j] ? "yes" : "no");
453 for (int k=0;k<4;k++) {
454 for (int l=0;l<8;l++) {
455 if(NParam == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][k*8+l]);
456 else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][k*8+l]);
457 }
458 PrintMessage("\n ");
459 }
460 PrintMessage("\n ");
461 }
462 }
463
464 return;
465 }
466
467
468 // Stop monitoring
469 else if (Match(Param[0], "stop")) {
470
471 state = stopped;
472 pthread_kill(HVMonitor, SIGUSR1);
473 PrintMessage("Status monitor stopped\n");
474
475 return;
476 }
477
478
479 // Set timeout to return from read
480 if (Match(Param[0], "timeout")) {
481
482 double Timeout;
483
484 if (!NumHVBoards) return;
485
486 if (NParam != 2) {
487 PrintMessage("Usage: timeout <secs>\n");
488 return;
489 }
490
491 if (!ConvertToDouble(Param[1], &Timeout)) {
492 PrintMessage("Error: Wrong number format\n");
493 return;
494 }
495
496 for (int i=0; i<NumHVBoards; i++) fHVBoard[i]->SetTimeOut(Timeout);
497 PrintMessage("Timeout set to %.2f s for all boards\n", Timeout);
498
499 return;
500 }
501
502
503 // Print uptime
504 if (Match(Param[0], "uptime")) {
505 time_t ActualT;
506 time (&ActualT);
507
508 PrintMessage("%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
509
510 return;
511 }
512
513
514 // Enable/disable verbosity
515 else if (Match(Param[0], "verbose")) {
516
517 if (Match(Param[1], "on")) {
518 Verbose = true;
519 PrintMessage("Verbosity enabled\n");
520 }
521 else if (Match(Param[1], "off")) {
522 Verbose = false;
523 PrintMessage("Verbosity disabled\n");
524 }
525 else PrintMessage("Usage: verbose <on>|<off>\n");
526
527 return;
528 }
529
530
531 // Exit program
532 else if(Match(Param[0], "exit")) {
533
534 if (CmdFromSocket) {
535 PrintMessage("Exit command not allowed over socket.\n");
536 return;
537 }
538
539 Exit = true;
540 pthread_kill(HVMonitor, SIGUSR1);
541 pthread_kill(SocketThread, SIGUSR1);
542
543 return;
544 }
545
546 PrintMessage("Unknown command '%s'\n", Param[0]);
547
548 return;
549}
550
551
552// Print message to selected target
553void ProcessIO::PrintMessage(int Target, const char *Format, ...) {
554 va_list ArgumentPointer;
555 va_start(ArgumentPointer, Format);
556 PrintMessage(Target, Format, ArgumentPointer);
557 va_end(ArgumentPointer);
558}
559
560// Print message to log file, and screen or socket (depending on command origin)
561void ProcessIO::PrintMessage(const char *Format, ...) {
562 va_list ArgumentPointer;
563 va_start(ArgumentPointer, Format);
564 if (CmdFromSocket) PrintMessage(MsgToSocket|MsgToLog, Format, ArgumentPointer);
565 else PrintMessage(MsgToConsole|MsgToLog, Format, ArgumentPointer);
566 va_end(ArgumentPointer);
567}
568
569// Function doing the actual printing work
570void ProcessIO::PrintMessage(int Target, const char *Format, va_list ArgumentPointer) {
571
572 char Textbuffer[MAX_COM_SIZE];
573
574 memset(Textbuffer, 0, sizeof(Textbuffer));
575 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
576
577 // Print to console
578 if(Target & MsgToConsole) {
579 if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
580 printf("\r%s%s", Textbuffer, Prompt); // New prompt
581 }
582 else printf("%s", Textbuffer);
583 fflush(stdout);
584 }
585 // Print to socket
586 if((Target & MsgToSocket) && Socket!=-1) {
587 write(Socket, Textbuffer, strlen(Textbuffer));
588 }
589 // Print to log file (repace carriage return by linefeed)
590 if((Target & MsgToLog) && Logfile!=NULL) {
591 for (unsigned int i=0; i<strlen(Textbuffer); i++) {
592 if(Textbuffer[i] == '\r') Textbuffer[i] = '\n';
593 }
594 fprintf(Logfile, "%s", Textbuffer);
595 fflush(Logfile);
596 }
597}
598
599
600// Ramp to new voltage with maximum step size given in config->fHVMaxDiff
601// No ramping when decreasing voltage
602bool ProcessIO::RampVoltage(unsigned int Target, int Board, int Chain, int Channel) {
603
604 while (fHVBoard[Board]->HV[Chain][Channel] != (int) Target) {
605 int Diff = Target - fHVBoard[Board]->HV[Chain][Channel];
606 if (Diff > (int) config->fHVMaxDiff) Diff = config->fHVMaxDiff;
607
608 if (fHVBoard[Board]->SetHV(Chain, Channel, fHVBoard[Board]->HV[Chain][Channel]+Diff) == 1) {
609 if (Verbose) {
610 PrintMessage("Board %d: high voltage of chain %d channel %d set to %d | 0X%.4X | %f V\n",fHVBoard[Board]->GetBoardNumber(),Chain, Channel, Target, Target, calib->DACToHV(Target,fHVBoard[Board]->GetBoardNumber(),Chain,Channel));
611 PrintBoardStatus(Board);
612 }
613 }
614 else {
615 PrintMessage("Error: Could not set HV of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
616 //SlowDataClass->NewEntry("Error");
617 //SlowDataClass->AddToEntry("%s %d %d %d %d %.2f ",fHVBoard[Board]->BoardName,Board, Chain, Channel, Target, calib->DACToHV(Target,Board,Chain,Channel));
618 return false;
619 }
620 }
621 //SlowDataClass->NewEntry("Value");
622 //SlowDataClass->AddToEntry("%s %d %d %d %d %.2f ",fHVBoard[Board]->BoardName,Board, Chain, Channel, Target, calib->DACToHV(Target,Board,Chain,Channel));
623 return true;
624}
625
626
627// Check board status
628void ProcessIO::Monitor() {
629
630 for (int i=0; i<NumHVBoards; i++) {
631
632 if (fHVBoard[i]->GetStatus() != 1) {
633 PrintMessage("Error: Monitor, could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
634 }
635
636 if (fHVBoard[i]->ResetButton) {
637 PrintMessage("Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
638 ResetBoard(i);
639 }
640
641 if (!fHVBoard[i]->WrapOK) {
642 PrintMessage("Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
643 }
644
645 for (int j=0; j<NUM_CHAINS; j++) {
646 if (fHVBoard[i]->Overcurrent[j]) {
647 PrintMessage("Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
648 ResetBoard(i);
649 }
650 }
651
652 }
653}
654
655
656// Send reset to board and clear voltage arrays
657void ProcessIO::ResetBoard(int i) {
658
659 if (fHVBoard[i]->Reset() == 1) {
660 PrintMessage("Reset of board %d\n", fHVBoard[i]->GetBoardNumber());
661 PrintBoardStatus(i);
662 }
663 else PrintMessage("Error: Could not reset board %d\n",fHVBoard[i]->GetBoardNumber());
664}
665
666
667// Print current board status
668void ProcessIO::PrintBoardStatus(int i) {
669
670 PrintMessage("Status board %d (%s): MR %s OC0 %s OC1 %s OC2 %s OC3 %s WC %s (%d)\n",
671 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
672 fHVBoard[i]->ResetButton ? "yes" : "no",
673 fHVBoard[i]->Overcurrent[0] ? "yes" : "no",
674 fHVBoard[i]->Overcurrent[1] ? "yes" : "no",
675 fHVBoard[i]->Overcurrent[2] ? "yes" : "no",
676 fHVBoard[i]->Overcurrent[3] ? "yes" : "no",
677 fHVBoard[i]->WrapOK ? "ok":"error", fHVBoard[i]->LastWrapCount);
678}
679
680
681// Parse command line for white space and double-quote separated tokens
682int ProcessIO::ParseInput(char* Command, const char *Param[]) {
683 int Count=0;
684
685 while(Count<MAX_NUM_TOKEN) {
686 while (isspace(*Command)) Command++; // Ignore initial white spaces
687 if(*Command=='\0') break;
688 if (*Command == '\"') {
689 Param[Count] = ++Command;
690 while(*Command!='\"' && *Command!='\0') Command++;
691 }
692 else {
693 Param[Count] = Command;
694 while(!isspace(*Command) && *Command!='\0') Command++;
695 }
696 if(*Command != '\0') *Command++ = '\0';
697 Count++;
698 }
699 return Count;
700}
701
702
703// Check if two strings match (min 1 character must match)
704bool Match(const char *str, const char *cmd) {
705 return strncasecmp(str,cmd,strlen(str)==0 ? 1:strlen(str)) ? false:true;
706}
707
708
709// Convert string to double
710// Returns false if conversion did not stop on whitespace or EOL character
711bool ConvertToDouble(const char *String, double *Result) {
712
713 char *EndPointer;
714
715 *Result = strtod(String, &EndPointer);
716 if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
717 return true;
718}
719
720
721// Convert string to int
722// Returns false if conversion did not stop on whitespace or EOL character
723bool ConvertToInt(const char *String, int *Result) {
724
725 char *EndPointer;
726
727 *Result = (int) strtol(String, &EndPointer, 0);
728 if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
729 return true;
730}
Note: See TracBrowser for help on using the repository browser.