source: hvcontrol/src/ProcessIO.cc@ 162

Last change on this file since 162 was 161, checked in by ogrimm, 15 years ago
Removed local configuration, now dependent on Evidence configuration server
File size: 21.9 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 DimCommand((char *) SERVER_NAME"/Command", (char *) "C"),
19 EvidenceServer(SERVER_NAME) {
20
21 // Get program start time
22 time (&StartTime);
23
24 // Create DIM text output service
25 Textout = new DimService (SERVER_NAME"/Textout", (char *) "");
26
27 // Initialize status variables
28 state = active;
29 Exit = false;
30 CmdFromSocket = false;
31 Socket = -1;
32
33 NumHVBoards = 0;
34 FirstBoard = 0;
35 LastBoard = -1;
36 FirstChain = 0;
37 LastChain = NUM_CHAINS-1;
38
39 // Get configuration data
40 char *Boards = GetConfig(SERVER_NAME " Boards");
41 fPixMapTable = GetConfig(SERVER_NAME " PixMapTable");
42 fTimeOut = atof(GetConfig(SERVER_NAME " TimeOut"));
43 fStatusRefreshRate = atof(GetConfig(SERVER_NAME " StatusRefreshRate"));
44 fCCPort = atoi(GetConfig(SERVER_NAME " CCPort"));
45 DACMin = atoi(GetConfig(SERVER_NAME " DACMin"));
46 DACMax = atoi(GetConfig(SERVER_NAME " DACMax"));
47 fHVCalibOffset = atof(GetConfig(SERVER_NAME " HVCalibOffset"));
48 fHVCalibSlope = atof(GetConfig(SERVER_NAME " HVCalibSlope"));
49 fHVMaxDiff = atoi(GetConfig(SERVER_NAME " HVMaxDiff"));
50
51 if (fStatusRefreshRate < MIN_RATE || fStatusRefreshRate > MAX_RATE) fStatusRefreshRate = 1;
52
53 // Open HV devices
54 fHVBoard = new HVBoard* [strlen(Boards)];
55 char *Token = strtok(Boards, " \t");
56 while (Token != NULL) {
57 fHVBoard[NumHVBoards] = new HVBoard(NumHVBoards, Token, this);
58 if(fHVBoard[NumHVBoards]->fDescriptor >= 0) {
59 PrintMessage("Synchronized and reset board %d (%s)\n",NumHVBoards,fHVBoard[NumHVBoards]->BoardName);
60 NumHVBoards++;
61 }
62 else {
63 PrintMessage(All, "Failed to synchronize board %d (%s)\n",NumHVBoards,fHVBoard[NumHVBoards]->BoardName);
64 delete fHVBoard[NumHVBoards];
65 }
66 Token = strtok(NULL, " \t");
67 }
68 LastBoard = NumHVBoards-1;
69
70 // Create instances
71 calib = new HVCalib(this);
72 pm = new PixelMap(fPixMapTable);
73}
74
75
76ProcessIO::~ProcessIO() {
77
78 for (int i=0; i<NumHVBoards; i++) delete fHVBoard[i];
79 delete[] fHVBoard;
80
81 delete pm; delete calib;
82 delete Textout;
83}
84
85
86// Process user input
87void ProcessIO::CommandControl(char *Command) {
88
89 if (strlen(Command)==0) return; // Ignore empty commands
90
91 if(Command[0]=='.') { // Shell command
92 system(&(Command[1]));
93 return;
94 }
95
96 for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = ""; // All pointers point initially to empty string
97 NParam = ParseInput(Command, Param);
98
99 // Adress board
100 if (Match(Param[0], "board")) {
101
102 if (!NumHVBoards) return;
103
104 // Print list of boards
105 if (NParam == 1) {
106 for (int i=0; i<NumHVBoards; i++) {
107 PrintMessage("Board %d: %s\n", fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName);
108 }
109 return;
110 }
111
112 //Select board(s)
113 if (Match(Param[1],"all")) {
114 FirstBoard = 0;
115 LastBoard = NumHVBoards-1;
116 }
117 else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards) {
118 FirstBoard = atoi(Param[1]);
119 LastBoard = FirstBoard;
120 }
121 else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards &&
122 atoi(Param[2])>0 && atoi(Param[2])<NumHVBoards) {
123 FirstBoard = atoi(Param[1]);
124 LastBoard = atoi(Param[2]);
125 }
126 else PrintMessage("Cannot address board(s), out of range.\n");
127
128 return;
129 }
130
131
132 // Adress chains
133 else if (Match(Param[0], "chain")) {
134
135 if (!NumHVBoards) return;
136
137 if (Match(Param[1],"all")) {
138 FirstChain = 0;
139 LastChain = 3;
140 }
141 else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NUM_CHAINS) {
142 FirstChain = atoi(Param[1]);
143 LastChain = FirstChain;
144 }
145 else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<NUM_CHAINS &&
146 atoi(Param[2])>0 && atoi(Param[2])<NUM_CHAINS) {
147 FirstChain = atoi(Param[1]);
148 LastChain = atoi(Param[2]);
149 }
150 else PrintMessage("Cannot address chain(s), out of range.\n");
151
152 return;
153 }
154
155
156 // Print HV utility configuration
157 else if (Match(Param[0], "config")) {
158 PrintMessage( " Pixel map table: %s\n"
159 " %d USB devices:\n", fPixMapTable,
160 NumHVBoards);
161 for (int i=0; i<NumHVBoards; i++) {
162 PrintMessage(" Board %d: %s\n", i, fHVBoard[i]->BoardName);
163 }
164 PrintMessage( " TimeOut: %.2f s\n"
165 " StatusRefreshRate: %.2f Hz\n"
166 " CCPort: %d\n"
167 " DACMin value: %d\n"
168 " DACMax value: %d\n"
169 " HVCalibOffset : %f\n"
170 " HVCalibSlope : %f\n"
171 " HVMaxDiff : %u\n", fTimeOut,
172 fStatusRefreshRate, fCCPort, DACMin,
173 DACMax, fHVCalibOffset, fHVCalibSlope,
174 fHVMaxDiff);
175
176 return;
177 }
178
179
180 // Print help
181 if (Match(Param[0], "help")) {
182 PrintMessage(" board <i>|<i> <j>|<all> Address board i, boards i-j or all boards or list boards\n"
183 " chain <i>|<i> <j>|<all> Address chain i, chains i-j or all chains\n"
184 " hv <PXL id>|<ch>|<all> <v> Set bias of pixel ID, ch. or all ch. of active chain(s)/board(s)\n"
185 " hvdiff <PXL id>|<ch>|<all> <diff> Change bias by <diff>\n"
186 " status [dac] Show status information (DAC values if requested)\n"
187 " config Print configuration\n"
188 " load <file> Load and set bias settings from <file>\n"
189 " save <file> Save current bias settings to [file]\n"
190 " exit Exit program\n"
191 " rate <rate> Set status refresh rate to <rate> [Hz]\n"
192 " timeout <time> Set timeout to return from read to <time> [s]\n"
193 " reset Reset active bias board\n"
194 " start Start bias status monitor\n"
195 " stop Stop bias status monitor - not recommended!\n"
196 " uptime Get program uptime [h:m:s]\n"
197 " help Print help\n"
198 " .<cmd> Execute shell command <cmd>");
199
200 return;
201 }
202
203
204 // Set new bias voltage (if no boards available, simply returns OK)
205 // First reponse to socket should be 'OK' if no error occurred.
206 if (Match(Param[0], "hv") || Match(Param[0], "hvdiff")) {
207
208 int hvoltage, DACValue, Errors=0, Board=-1, Chain=-1, Channel=-1;
209 double hvoltageV;
210 bool SetDac;
211
212 // Need two or parameters
213 if (NParam<3 || NParam>4) {
214 PrintMessage("Usage: hv/hvdiff <channel>|<all> <voltage> [dac]\n");
215 return;
216 }
217
218 // Evaluate voltage parameter
219 if (NParam==4 && Match(Param[3], "dac")) {
220 SetDac = true;
221 if (!ConvertToInt(Param[2], &hvoltage)) {
222 PrintMessage("Error: Wrong number format for DAC voltage setting\n");
223 return;
224 }
225 }
226 else {
227 SetDac = false;
228 if (!ConvertToDouble(Param[2], &hvoltageV)) {
229 PrintMessage("Error: Wrong number format for voltage setting\n");
230 return;
231 }
232 }
233
234 // Evaluate pixel or channel parameter
235 if(pm->Pixel_to_HVboard(Param[1]) != 999999999) {
236 Board = pm->Pixel_to_HVboard(Param[1]);
237 Chain = pm->Pixel_to_HVchain(Param[1]);
238 Channel = pm->Pixel_to_HVchannel(Param[1]);
239 }
240 else if (!Match(Param[1], "all") && !ConvertToInt(Param[1], &Channel)) {
241 PrintMessage("Error: Wrong channel identification\n");
242 return;
243 }
244
245 for (int i=FirstBoard; i<=LastBoard; i++) {
246 if (i!=Board && Board!=-1) continue;
247 for (int j=FirstChain; j<=LastChain; j++) {
248 if (j!=Chain && Chain!=-1) continue;
249 for (int k=0; k<NUM_CHANNELS; k++) {
250 if (k!=Channel && Channel!=-1) continue;
251
252 // hvdiff is ignored if DAC value is zero
253 if ((strlen(Param[0])>2 || isdigit(*Param[2])==0) && (fHVBoard[i]->HV[j][k] == 0)) continue;
254
255 // Determine new DAC values
256 if (!SetDac){
257 if (strlen(Param[0])>2 || isdigit(*Param[2])==0) fHVBoard[i]->HVV[j][k] += hvoltageV; // hvdiff
258 else fHVBoard[i]->HVV[j][k] = hvoltageV;
259 DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
260 }
261 else {
262 if(strlen(Param[0])>2 || isdigit(*Param[2])==0) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // hvdiff
263 else DACValue = hvoltage;
264 }
265
266 // Set new voltage (if DAC value, update calibrated value)
267 if (!RampVoltage(DACValue, i, j, k)) Errors++;
268 if (SetDac) fHVBoard[i]->HVV[j][k] = calib->DACToHV(fHVBoard[i]->HV[j][k], i, j, k);
269
270 // Update DIM services
271 fHVBoard[i]->BiasVolt[j][k]->updateService();
272
273 } // Channels
274 } // Chains
275 } // Boards
276
277 if (Errors > 0) PrintMessage("ERROR - Errors on %d channel(s) occurred\n", Errors);
278 else PrintMessage("OK - no errors\n");
279
280 return;
281 }
282
283
284 // Load HV settings from file
285 else if (Match(Param[0], "load")) {
286
287 char Buffer[MAX_COM_SIZE];
288 int NBoards = 0, Errors = 0, Chain, Channel;
289 unsigned int DACValue;
290 FILE *File;
291
292 if (NParam != 2) {
293 PrintMessage("Usage: load <file>\n");
294 return;
295 }
296
297 if ((File=fopen(Param[1], "r")) == NULL) {
298 PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
299 return;
300 }
301
302 while (fgets(Buffer, sizeof(Buffer), File) != NULL) {
303 for (int Board=0; Board<NumHVBoards; Board++) {
304 if (Match(fHVBoard[Board]->BoardName, Buffer)) {
305 PrintMessage("Found bias settings for board %d (%s)\n\r",fHVBoard[Board]->GetBoardNumber(), fHVBoard[Board]->BoardName);
306
307 Chain = 0; Channel = 0;
308 while (fscanf(File, "%u", &DACValue)==1 && Chain<NUM_CHAINS) {
309 if (!RampVoltage(DACValue, Board, Chain, Channel)) {
310 Errors++;
311 PrintMessage("Error: Could not ramp chain %d, channel %d\n", Chain, Channel);
312 }
313 else {
314 PrintMessage("Ramped chain %d, channel %d to %u (%.2f V) \r",
315 Chain,Channel,DACValue,calib->DACToHV(DACValue,Board,Chain,Channel));
316 }
317 fHVBoard[Board]->HVV[Chain][Channel] = calib->DACToHV(fHVBoard[Board]->HV[Chain][Channel], Board, Chain, Channel);
318
319 // Update DIM services
320 fHVBoard[Board]->BiasVolt[Chain][Channel]->updateService();
321
322 if(++Channel == NUM_CHANNELS) {
323 Chain++;
324 Channel = 0;
325 }
326 }
327 if (ferror(File) != 0) {
328 PrintMessage("Error reading DAC value from file, terminating. (%s)\n",strerror(errno));
329 return;
330 }
331 else PrintMessage("\nFinished updating board\n");
332 NBoards++;
333 }
334 } // Loop over boards
335 } // while()
336
337 if (NBoards != NumHVBoards) {
338 PrintMessage("Warning: Could not load bias settings for all connected HV boards\n");
339 }
340 else if (Errors == 0) PrintMessage("Success: Read bias 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,"********** Bias 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(All, "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(" Status refresh rate [Hz]: %.2f\n", fStatusRefreshRate);
442 PrintMessage(" Socket state: %s\n", Socket==-1 ? "disconnected":"connected");
443 PrintMessage(" Total number of boards: %d\n", NumHVBoards);
444 PrintMessage(" Active boards: %d\n\n", LastBoard - FirstBoard + 1);
445
446 for (int i=FirstBoard; i<=LastBoard; i++) {
447 PrintMessage(" BOARD %d (%s) Wrap counter: %s (%d) Manual reset: %s\n Time-out: %.2f s Error count: %d\n\n",
448 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
449 fHVBoard[i]->WrapOK ? "ok":"error",
450 fHVBoard[i]->LastWrapCount,
451 fHVBoard[i]->ResetButton ? "yes" : "no",
452 fHVBoard[i]->fTimeOut,
453 fHVBoard[i]->ErrorCount);
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 PrintMessage("\r");
459 for (int l=0;l<8;l++) {
460 if(NParam == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][k*8+l]);
461 else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][k*8+l]);
462 }
463 PrintMessage("\n");
464 }
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(All, "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 // Exit program
519 else if(Match(Param[0], "exit")) {
520
521 if (CmdFromSocket) {
522 PrintMessage("Exit command not allowed over socket.\n");
523 return;
524 }
525
526 Exit = true;
527 pthread_kill(HVMonitor, SIGUSR1);
528 pthread_kill(SocketThread, SIGUSR1);
529
530 return;
531 }
532
533 PrintMessage("Unknown command '%s'\n", Param[0]);
534
535 return;
536}
537
538
539// Print message to selected target
540void ProcessIO::PrintMessage(MsgTarget Target, const char *Format, ...) {
541 va_list ArgumentPointer;
542 va_start(ArgumentPointer, Format);
543 DoPrintMessage(Format, ArgumentPointer, Target);
544 va_end(ArgumentPointer);
545}
546
547// Print message to log file, and screen or socket (depending on command origin)
548void ProcessIO::PrintMessage(const char *Format, ...) {
549 va_list ArgumentPointer;
550 va_start(ArgumentPointer, Format);
551 if (CmdFromSocket) DoPrintMessage(Format, ArgumentPointer, Client);
552 else DoPrintMessage(Format, ArgumentPointer, Console);
553 va_end(ArgumentPointer);
554}
555
556// Function doing the actual printing work
557// Be careful with overloading variadic functions!
558void ProcessIO::DoPrintMessage(const char *Format, va_list ArgumentPointer, MsgTarget Target) {
559
560 static char Textbuffer[MAX_COM_SIZE]; // static because of DIM service
561
562 memset(Textbuffer, 0, sizeof(Textbuffer));
563 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
564
565 // Print to console
566 if(Target & Console) {
567 if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
568 printf("\r%s%s", Textbuffer, Prompt); // New prompt
569 }
570 else printf("%s", Textbuffer);
571 fflush(stdout);
572 }
573
574 // Send to DIM service
575 Textout->updateService(Textbuffer);
576
577 // Print to socket
578 if((Target & Client) && Socket!=-1) {
579 write(Socket, Textbuffer, strlen(Textbuffer));
580 }
581
582 // Send to log
583 if(Target & Log) {
584 char *Buf;
585 if (asprintf(&Buf, "%s %s", SERVER_NAME, Textbuffer) != -1) {
586 DimClient::sendCommand("DColl/Log", Buf);
587 free(Buf);
588 }
589 else DimClient::sendCommand("DColl/Log", SERVER_NAME" asprintf() failed");
590 }
591}
592
593
594// Ramp to new voltage with maximum step size given in fHVMaxDiff
595// No ramping when decreasing voltage
596bool ProcessIO::RampVoltage(unsigned int Target, int Board, int Chain, int Channel) {
597
598 while (fHVBoard[Board]->HV[Chain][Channel] != (int) Target) {
599 int Diff = Target - fHVBoard[Board]->HV[Chain][Channel];
600 if (Diff > (int) fHVMaxDiff) Diff = fHVMaxDiff;
601
602 if (fHVBoard[Board]->SetHV(Chain, Channel, fHVBoard[Board]->HV[Chain][Channel]+Diff) != 1) {
603 State(ERROR, "Could not set bias of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
604 return false;
605 }
606 }
607
608 return true;
609}
610
611
612// Check board status (ignore board if it has more than 10 read/write errors)
613void ProcessIO::Monitor() {
614
615 static bool Warned = false;
616
617 for (int i=0; i<NumHVBoards; i++) {
618 if (fHVBoard[i]->ErrorCount > 10) {
619 if (!Warned) {
620 Warned = true;
621 PrintMessage(All, "Warning: Some board has many read/write errors, status monitor disabled\n");
622 State(WARN, "Warning: Some board has many read/write errors, status monitor disabled\n");
623 }
624 continue;
625 }
626
627 if (fHVBoard[i]->GetStatus() != 1) {
628 PrintMessage(All, "Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
629 State(ERROR, "Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
630 }
631
632 if (fHVBoard[i]->ResetButton) {
633 PrintMessage(All, "Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
634 State(INFO, "Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
635 ResetBoard(i);
636 }
637
638 if (!fHVBoard[i]->WrapOK) {
639 PrintMessage(All, "Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
640 State(ERROR, "Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
641 }
642
643 for (int j=0; j<NUM_CHAINS; j++) {
644 if (fHVBoard[i]->Overcurrent[j]) {
645 PrintMessage(All, "Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
646 State(WARN, "Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
647 ResetBoard(i);
648 }
649 }
650
651 }
652}
653
654
655// Send reset to board and clear voltage arrays
656void ProcessIO::ResetBoard(int i) {
657
658 if (fHVBoard[i]->Reset() == 1) {
659 PrintMessage("Reset of board %d\n", fHVBoard[i]->GetBoardNumber());
660 PrintBoardStatus(i);
661 }
662 else PrintMessage("Error: Could not reset board %d\n",fHVBoard[i]->GetBoardNumber());
663}
664
665
666// Print current board status
667void ProcessIO::PrintBoardStatus(int i) {
668
669 PrintMessage("Status board %d (%s): MR %s OC0 %s OC1 %s OC2 %s OC3 %s WC %s (%d)\n",
670 fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
671 fHVBoard[i]->ResetButton ? "yes" : "no",
672 fHVBoard[i]->Overcurrent[0] ? "yes" : "no",
673 fHVBoard[i]->Overcurrent[1] ? "yes" : "no",
674 fHVBoard[i]->Overcurrent[2] ? "yes" : "no",
675 fHVBoard[i]->Overcurrent[3] ? "yes" : "no",
676 fHVBoard[i]->WrapOK ? "ok":"error", fHVBoard[i]->LastWrapCount);
677}
678
679
680// Parse command line for white space and double-quote separated tokens
681int ProcessIO::ParseInput(char* Command, const char *Param[]) {
682 int Count=0;
683
684 while(Count<MAX_NUM_TOKEN) {
685 while (isspace(*Command)) Command++; // Ignore initial white spaces
686 if(*Command=='\0') break;
687 if (*Command == '\"') {
688 Param[Count] = ++Command;
689 while(*Command!='\"' && *Command!='\0') Command++;
690 }
691 else {
692 Param[Count] = Command;
693 while(!isspace(*Command) && *Command!='\0') Command++;
694 }
695 if(*Command != '\0') *Command++ = '\0';
696 Count++;
697 }
698 return Count;
699}
700
701//
702// Command handling (the only command is 'BIAS/Command')
703//
704void ProcessIO::commandHandler() {
705
706 // Log command
707 PrintMessage(Log, "DIM> %s\n", getString());
708
709 // Process command
710 pthread_mutex_lock(&control_mutex);
711 CommandControl(getString());
712 pthread_mutex_unlock(&control_mutex);
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.