source: hvcontrol/src/ProcessIO.cc@ 98

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