source: hvcontrol/src/ProcessIO.cc@ 185

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