source: hvcontrol/src/ProcessIO.cc@ 93

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