source: hvcontrol/src/ProcessIO.cc@ 216

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