source: hvcontrol/src/ProcessIO.cc@ 154

Last change on this file since 154 was 126, checked in by ogrimm, 15 years ago
Implemented DIM servers
File size: 22.7 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): EvidenceServer(SERVER_NAME) {
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 // Update DIM services
274 fHVBoard[i]->BiasVolt[j][k]->updateService();
275
276 } // Channels
277 } // Chains
278 } // Boards
279
280 if (Errors > 0) PrintMessage("ERROR - Errors on %d channel(s) occurred\n", Errors);
281 else PrintMessage("OK - no errors\n");
282
283 return;
284 }
285
286
287 // Load HV settings from file
288 else if (Match(Param[0], "load")) {
289
290 char Buffer[MAX_COM_SIZE];
291 int NBoards = 0, Errors = 0, Chain, Channel;
292 unsigned int DACValue;
293 FILE *File;
294
295 if (NParam != 2) {
296 PrintMessage("Usage: load <file>\n");
297 return;
298 }
299
300 if ((File=fopen(Param[1], "r")) == NULL) {
301 PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
302 return;
303 }
304
305 while (fgets(Buffer, sizeof(Buffer), File) != NULL) {
306 for (int Board=0; Board<NumHVBoards; Board++) {
307 if (Match(fHVBoard[Board]->BoardName, Buffer)) {
308 PrintMessage("Found HV settings for board %d (%s)\n\r",fHVBoard[Board]->GetBoardNumber(), fHVBoard[Board]->BoardName);
309
310 Chain = 0; Channel = 0;
311 while (fscanf(File, "%u", &DACValue)==1 && Chain<NUM_CHAINS) {
312 if (!RampVoltage(DACValue, Board, Chain, Channel)) {
313 Errors++;
314 PrintMessage("Error: Could not ramp chain %d, channel %d\n", Chain, Channel);
315 }
316 else {
317 PrintMessage("Ramped chain %d, channel %d to %u (%.2f V) \r",
318 Chain,Channel,DACValue,calib->DACToHV(DACValue,Board,Chain,Channel));
319 }
320 fHVBoard[Board]->HVV[Chain][Channel] = calib->DACToHV(fHVBoard[Board]->HV[Chain][Channel], Board, Chain, Channel);
321
322 // Update DIM services
323 fHVBoard[Board]->BiasVolt[Chain][Channel]->updateService();
324
325 if(++Channel == NUM_CHANNELS) {
326 Chain++;
327 Channel = 0;
328 }
329 }
330 if (ferror(File) != 0) {
331 PrintMessage("Error reading DAC value from file, terminating. (%s)\n",strerror(errno));
332 return;
333 }
334 else PrintMessage("\nFinished updating board\n");
335 NBoards++;
336 }
337 } // Loop over boards
338 } // while()
339
340 if (NBoards != NumHVBoards) {
341 PrintMessage("Warning: Could not load HV settings for all connected HV boards\n");
342 }
343 else if (Errors == 0) PrintMessage("Success: Read HV settings for all connected HV boards\n");
344 if (Errors != 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);
345
346 if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n",Param[1]);
347
348 return;
349 }
350
351
352 // Set status refresh rate
353 if (Match(Param[0], "rate")) {
354
355 double Rate;
356
357 if (NParam != 2) {
358 PrintMessage("Usage: rate <Hz>\n");
359 return;
360 }
361
362 if (!ConvertToDouble(Param[1], &Rate)) {
363 PrintMessage("Error: Wrong number format\n");
364 return;
365 }
366
367 // Check limits
368 if (Rate<MIN_RATE || Rate>MAX_RATE) {
369 PrintMessage("Refresh rate out of range (min: %.2f Hz, max: %.2f Hz)\n", MIN_RATE, MAX_RATE);
370 return;
371 }
372
373 fStatusRefreshRate = Rate;
374 PrintMessage("Refresh rate set to %.2f Hz\n", fStatusRefreshRate);
375
376 return;
377 }
378
379 // Reset
380 if (Match(Param[0], "reset")) {
381
382 if (!NumHVBoards) return;
383 for (int i=FirstBoard; i<=LastBoard; i++) ResetBoard(i);
384 return;
385 }
386
387
388 // Save HV settings of all boards
389 else if (Match(Param[0], "save")) {
390
391 FILE *File;
392 time_t time_now_secs;
393 struct tm *Time;
394
395 if (NParam != 2) {
396 PrintMessage("Usage: save <Filename>\n");
397 return;
398 }
399
400 time(&time_now_secs);
401 Time = localtime(&time_now_secs);
402
403 if ((File = fopen(Param[1], "w")) == NULL) {
404 PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
405 return;
406 }
407
408 fprintf(File,"********** HV settings, %04d %02d %02d, %02d:%02d:%02d **********\n\n",
409 1900 + Time->tm_year, 1 + Time->tm_mon,
410 Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
411
412 for (int i=0; i<NumHVBoards; i++) {
413 fprintf(File, "%s\n\n", fHVBoard[i]->BoardName);
414
415 for (int j=0; j<NUM_CHAINS; j++) {
416 for (int k=0; k<NUM_CHANNELS; k++) fprintf(File,"%5d ",fHVBoard[i]->HV[j][k]);
417 fprintf(File, "\n");
418 }
419 fprintf(File, "\n");
420 }
421
422 if (fclose(File) != 0) {
423 PrintMessage("Error: Could not close file '%s' (%s)\n", Param[1], strerror(errno));
424 }
425
426 return;
427 }
428
429
430 // Start monitoring
431 else if (Match(Param[0], "start")) {
432
433 state = active;
434 pthread_kill(HVMonitor, SIGUSR1);
435 PrintMessage("Status monitoring activated\n");
436 return;
437 }
438
439
440 // Print status
441 else if (Match(Param[0], "status")) {
442
443 PrintMessage("\n Status monitor: %s\n", state_str[state]);
444 PrintMessage(" Verbose: %s\n", Verbose ? "on" : "off");
445 PrintMessage(" Status refresh rate [Hz]: %.2f\n", fStatusRefreshRate);
446 PrintMessage(" Socket state: %s\n", Socket==-1 ? "disconnected":"connected");
447 PrintMessage(" Total number of HV boards: %d\n", NumHVBoards);
448 PrintMessage(" Active HV boards: %d\n\n", LastBoard - FirstBoard + 1);
449
450 for (int i=FirstBoard; i<=LastBoard; i++) {
451 PrintMessage(" BOARD %d (%s) Wrap counter: %s (%d) Manual reset: %s\n Time-out: %.2f s Error count: %d\n\n",
452 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
453 fHVBoard[i]->WrapOK ? "ok":"error",
454 fHVBoard[i]->LastWrapCount,
455 fHVBoard[i]->ResetButton ? "yes" : "no",
456 fHVBoard[i]->fTimeOut,
457 fHVBoard[i]->ErrorCount);
458
459 for (int j=FirstChain; j<=LastChain; j++) {
460 PrintMessage(" CHAIN %d Over-current: %s\n", j, fHVBoard[i]->Overcurrent[j] ? "yes" : "no");
461 for (int k=0;k<4;k++) {
462 PrintMessage("\r");
463 for (int l=0;l<8;l++) {
464 if(NParam == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][k*8+l]);
465 else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][k*8+l]);
466 }
467 PrintMessage("\n");
468 }
469 }
470 }
471
472 return;
473 }
474
475
476 // Stop monitoring
477 else if (Match(Param[0], "stop")) {
478
479 state = stopped;
480 pthread_kill(HVMonitor, SIGUSR1);
481 PrintMessage("Status monitor stopped\n");
482
483 return;
484 }
485
486
487 // Set timeout to return from read
488 if (Match(Param[0], "timeout")) {
489
490 double Timeout;
491
492 if (!NumHVBoards) return;
493
494 if (NParam != 2) {
495 PrintMessage("Usage: timeout <secs>\n");
496 return;
497 }
498
499 if (!ConvertToDouble(Param[1], &Timeout)) {
500 PrintMessage("Error: Wrong number format\n");
501 return;
502 }
503
504 for (int i=0; i<NumHVBoards; i++) fHVBoard[i]->SetTimeOut(Timeout);
505 PrintMessage("Timeout set to %.2f s for all boards\n", Timeout);
506
507 return;
508 }
509
510
511 // Print uptime
512 if (Match(Param[0], "uptime")) {
513 time_t ActualT;
514 time (&ActualT);
515
516 PrintMessage("%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
517
518 return;
519 }
520
521
522 // Enable/disable verbosity
523 else if (Match(Param[0], "verbose")) {
524
525 if (Match(Param[1], "on")) {
526 Verbose = true;
527 PrintMessage("Verbosity enabled\n");
528 }
529 else if (Match(Param[1], "off")) {
530 Verbose = false;
531 PrintMessage("Verbosity disabled\n");
532 }
533 else PrintMessage("Usage: verbose <on>|<off>\n");
534
535 return;
536 }
537
538
539 // Exit program
540 else if(Match(Param[0], "exit")) {
541
542 if (CmdFromSocket) {
543 PrintMessage("Exit command not allowed over socket.\n");
544 return;
545 }
546
547 Exit = true;
548 pthread_kill(HVMonitor, SIGUSR1);
549 pthread_kill(SocketThread, SIGUSR1);
550
551 return;
552 }
553
554 PrintMessage("Unknown command '%s'\n", Param[0]);
555
556 return;
557}
558
559
560// Print message to selected target
561void ProcessIO::PrintMessage(int Target, const char *Format, ...) {
562 va_list ArgumentPointer;
563 va_start(ArgumentPointer, Format);
564 DoPrintMessage(Format, ArgumentPointer, Target);
565 va_end(ArgumentPointer);
566}
567
568// Print message to log file, and screen or socket (depending on command origin)
569void ProcessIO::PrintMessage(const char *Format, ...) {
570 va_list ArgumentPointer;
571 va_start(ArgumentPointer, Format);
572 if (CmdFromSocket) DoPrintMessage(Format, ArgumentPointer, MsgToSocket|MsgToLog);
573 else DoPrintMessage(Format, ArgumentPointer, MsgToConsole|MsgToLog);
574 va_end(ArgumentPointer);
575}
576
577// Function doing the actual printing work
578// Be careful with overloading variadic functions!
579void ProcessIO::DoPrintMessage(const char *Format, va_list ArgumentPointer, int Target) {
580
581 char Textbuffer[MAX_COM_SIZE];
582
583 memset(Textbuffer, 0, sizeof(Textbuffer));
584 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
585
586 // Print to console
587 if(Target & MsgToConsole) {
588 if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
589 printf("\r%s%s", Textbuffer, Prompt); // New prompt
590 }
591 else printf("%s", Textbuffer);
592 fflush(stdout);
593 }
594 // Print to socket
595 if((Target & MsgToSocket) && Socket!=-1) {
596 write(Socket, Textbuffer, strlen(Textbuffer));
597 }
598 // Print to log file (replace carriage return by linefeed)
599 if((Target & MsgToLog) && Logfile!=NULL) {
600 for (unsigned int i=0; i<strlen(Textbuffer); i++) {
601 if(Textbuffer[i] == '\r') Textbuffer[i] = '\n';
602 }
603 time_t Time;
604 strftime(Textbuffer+strlen(Textbuffer)+1,MAX_COM_SIZE-strlen(Textbuffer)-1, "%d/%m/%y %X", localtime(&(Time=time(NULL))));
605 fprintf(Logfile, "%s: %s", Textbuffer+strlen(Textbuffer)+1, Textbuffer);
606 fflush(Logfile);
607 }
608}
609
610
611// Ramp to new voltage with maximum step size given in config->fHVMaxDiff
612// No ramping when decreasing voltage
613bool ProcessIO::RampVoltage(unsigned int Target, int Board, int Chain, int Channel) {
614
615 while (fHVBoard[Board]->HV[Chain][Channel] != (int) Target) {
616 int Diff = Target - fHVBoard[Board]->HV[Chain][Channel];
617 if (Diff > (int) config->fHVMaxDiff) Diff = config->fHVMaxDiff;
618
619 if (fHVBoard[Board]->SetHV(Chain, Channel, fHVBoard[Board]->HV[Chain][Channel]+Diff) == 1) {
620 if (Verbose) {
621 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));
622 PrintBoardStatus(Board);
623 }
624 }
625 else {
626 PrintMessage("Error: Could not set HV of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
627 SlowDataClass->NewEntry("Error");
628 SlowDataClass->AddToEntry("%s %d %d %d %d %.2f ",fHVBoard[Board]->BoardName,Board, Chain, Channel, Target, calib->DACToHV(Target,Board,Chain,Channel));
629 return false;
630 }
631 }
632 SlowDataClass->NewEntry("Value");
633 SlowDataClass->AddToEntry("%s %d %d %d %d %.2f ",fHVBoard[Board]->BoardName,Board, Chain, Channel, Target, calib->DACToHV(Target,Board,Chain,Channel));
634
635 // Update DIM service
636 fHVBoard[Board]->BiasDAC[Chain][Channel]->updateService();
637
638 return true;
639}
640
641
642// Check board status (ignore board if it has more than 10 read/write errors)
643void ProcessIO::Monitor() {
644
645 static bool Warned = false;
646
647 for (int i=0; i<NumHVBoards; i++) {
648 if (fHVBoard[i]->ErrorCount > 10) {
649 if (!Warned) {
650 Warned = true;
651 PrintMessage("Warning: Some board has many read/write errors, status monitor disabled\n");
652 }
653 continue;
654 }
655
656 if (fHVBoard[i]->GetStatus() != 1) {
657 PrintMessage("Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
658 }
659
660 if (fHVBoard[i]->ResetButton) {
661 PrintMessage("Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
662 ResetBoard(i);
663 }
664
665 if (!fHVBoard[i]->WrapOK) {
666 PrintMessage("Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
667 }
668
669 for (int j=0; j<NUM_CHAINS; j++) {
670 if (fHVBoard[i]->Overcurrent[j]) {
671 PrintMessage("Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
672 ResetBoard(i);
673 }
674 }
675
676 }
677}
678
679
680// Send reset to board and clear voltage arrays
681void ProcessIO::ResetBoard(int i) {
682
683 if (fHVBoard[i]->Reset() == 1) {
684 PrintMessage("Reset of board %d\n", fHVBoard[i]->GetBoardNumber());
685 PrintBoardStatus(i);
686 }
687 else PrintMessage("Error: Could not reset board %d\n",fHVBoard[i]->GetBoardNumber());
688}
689
690
691// Print current board status
692void ProcessIO::PrintBoardStatus(int i) {
693
694 PrintMessage("Status board %d (%s): MR %s OC0 %s OC1 %s OC2 %s OC3 %s WC %s (%d)\n",
695 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
696 fHVBoard[i]->ResetButton ? "yes" : "no",
697 fHVBoard[i]->Overcurrent[0] ? "yes" : "no",
698 fHVBoard[i]->Overcurrent[1] ? "yes" : "no",
699 fHVBoard[i]->Overcurrent[2] ? "yes" : "no",
700 fHVBoard[i]->Overcurrent[3] ? "yes" : "no",
701 fHVBoard[i]->WrapOK ? "ok":"error", fHVBoard[i]->LastWrapCount);
702}
703
704
705// Parse command line for white space and double-quote separated tokens
706int ProcessIO::ParseInput(char* Command, const char *Param[]) {
707 int Count=0;
708
709 while(Count<MAX_NUM_TOKEN) {
710 while (isspace(*Command)) Command++; // Ignore initial white spaces
711 if(*Command=='\0') break;
712 if (*Command == '\"') {
713 Param[Count] = ++Command;
714 while(*Command!='\"' && *Command!='\0') Command++;
715 }
716 else {
717 Param[Count] = Command;
718 while(!isspace(*Command) && *Command!='\0') Command++;
719 }
720 if(*Command != '\0') *Command++ = '\0';
721 Count++;
722 }
723 return Count;
724}
725
726
727// Check if two strings match (min 1 character must match)
728bool Match(const char *str, const char *cmd) {
729 return strncasecmp(str,cmd,strlen(str)==0 ? 1:strlen(str)) ? false:true;
730}
731
732
733// Convert string to double
734// Returns false if conversion did not stop on whitespace or EOL character
735bool ConvertToDouble(const char *String, double *Result) {
736
737 char *EndPointer;
738
739 *Result = strtod(String, &EndPointer);
740 if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
741 return true;
742}
743
744
745// Convert string to int
746// Returns false if conversion did not stop on whitespace or EOL character
747bool ConvertToInt(const char *String, int *Result) {
748
749 char *EndPointer;
750
751 *Result = (int) strtol(String, &EndPointer, 0);
752 if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
753 return true;
754}
Note: See TracBrowser for help on using the repository browser.