Changeset 11772 for fact/BIASctrl/User.cc
- Timestamp:
- 08/04/11 12:44:02 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/BIASctrl/User.cc
r11362 r11772 12 12 void (User::*CommandPointer)(); 13 13 unsigned int MinNumParameter; 14 bool NeedCrate; 14 15 const char *Parameters; 15 16 const char *Help; 16 17 } CommandList[] = 17 {{"pixel", &User::cmd_hv, 2, "<pix id> <volt|default>", "Change bias of pixel (to default value)"}, 18 {"channel", &User::cmd_hv, 2, "<range> <volt|default>", "Change bias of (all) channels of active crate"}, 19 {"gs", &User::cmd_gs, 1, "[crate] <volt>", "Global voltage set active crate"}, 20 {"reset", &User::cmd_reset, 0, "", "Reset active crate"}, 21 {"synch", &User::cmd_synch, 0, "", "Synchronize active crate"}, {"crate", &User::cmd_crate, 1, "<number>", "Select active crate"}, 22 {"status", &User::cmd_status, 0, "[dac|current]", "Show status information (DAC values if requested)"}, 23 {"mode", &User::cmd_mode, 1, "<static|dynamic>", "Set voltage stabilization mode (experimental)"}, 24 {"load", &User::cmd_load, 1, "<file>", "Load and set bias settings from file"}, 25 {"save", &User::cmd_save, 1, "<file>", "Save current bias settings to file"}, 26 {"rate", &User::cmd_rate, 1, "<rate>", "Set refresh rate in Hz"}, 27 {"timeout", &User::cmd_timeout, 1, "<time>", "Set timeout to return from read in seconds"}, 28 {"help", &User::cmd_help, 0, "", "Print help"}, 29 {"exit", &User::cmd_exit, 0, "", "Exit program"}}; 30 18 {{"pixel", &User::cmd_hv, 2, true, "<range> <voltage|default|info>", "Change bias of pixels (to default)"}, 19 {"channel", &User::cmd_hv, 2, true, "<range> <voltage|default|info>", "Change bias of channels of active crate (to default)"}, 20 {"gs", &User::cmd_gs, 1, true, "[crate] <volt>", "Global voltage set active crate"}, 21 {"reset", &User::cmd_reset, 0, true, "", "Reset active crate"}, 22 {"synch", &User::cmd_synch, 0, true, "", "Synchronize active crate"}, 23 {"crate", &User::cmd_crate, 1, true, "<number>", "Select active crate"}, 24 {"status", &User::cmd_status, 0, false, "[dac|current]", "Show status information (DAC values if requested)"}, 25 {"mode", &User::cmd_mode, 1, false, "<static|dynamic>", "Set voltage stabilization mode (experimental)"}, 26 {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"}, 27 {"save", &User::cmd_save, 1, true, "<file>", "Save current bias settings to file"}, 28 {"rate", &User::cmd_rate, 1, false, "<rate>", "Set refresh rate in Hz"}, 29 {"timeout", &User::cmd_timeout, 1, false, "<time>", "Set timeout to return from read in seconds"}, 30 {"help", &User::cmd_help, 0, false, "", "Print help"}, 31 {"exit", &User::cmd_exit, 0, false, "", "Exit program"}, 32 {".", &User::cmd_shell, 1, false, "<command>", "Execute shell command"}}; 31 33 32 34 // … … 42 44 43 45 // Get configuration data 44 vector<string> Boards = Tokenize(GetConfig("Boards"), " \t"); 45 Boards = Tokenize("FTE00FOH", " \t"); 46 vector<string> Boards = Tokenize(GetConfig("Boards", "dummy"), " \t"); 46 47 fTimeOut = atof(GetConfig("TimeOut").c_str()); 47 48 fStatusRefreshRate = atof(GetConfig("StatusRefreshRate").c_str()); … … 70 71 } 71 72 } 72 73 // Set active crate 74 if (!Boards.empty()) ActiveCrate = 0; 75 else ActiveCrate = -1; 73 ActiveCrate = 0; 76 74 77 75 // Create PixelMap instance (map from config server) … … 94 92 User::~User() { 95 93 94 int Ret; 95 96 96 // Wait for thread to quit 97 if ( pthread_cancel(Thread) != 0) Message(ERROR, "pthread_cancel() failed in ()");98 if ( pthread_join(Thread, NULL) != 0) Message(ERROR, "pthread_join() failed in ()");97 if ((Ret = pthread_cancel(Thread)) != 0) Message(ERROR, "pthread_cancel() failed (%s)", strerror(Ret)); 98 if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret)); 99 99 100 100 // Delete all crates … … 118 118 if (getCommand() != DIMCommand || Command.size() < 2) return; 119 119 120 // Shell command121 if(Command[0]=='.') {122 if (system(Command.c_str()+1) == 1) {123 PrintMessage("Error with system() call\n");124 }125 return;126 }127 128 120 // Parse command into tokens 129 121 Parameter = Tokenize(Command, " "); 130 122 123 // Special handling of shell execution 124 if (Command[0] == '.') { 125 Parameter.clear(); 126 Parameter.push_back("."); 127 Parameter.push_back(Command.substr(1)); 128 } 129 131 130 // Search for command in command list 132 131 for(unsigned int CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++) { 133 132 if (Match(Parameter[0], CommandList[CmdNumber].Name)) { 134 if(Parameter.size()-1 < CommandList[CmdNumber].MinNumParameter) { 133 // Requested command help? 134 if (Parameter.size() == 2 && Match(Parameter[1], "?")) { 135 PrintMessage("Usage: %s %s\n%s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters, CommandList[CmdNumber].Help); 136 return; 137 } 138 139 // Incorrect number of parameters? 140 if (Parameter.size()-1 < CommandList[CmdNumber].MinNumParameter) { 135 141 PrintMessage("Usage: %s %s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters); 142 return; 143 } 144 145 // Check if crates needed 146 if (CommandList[CmdNumber].NeedCrate && Crates.empty()) { 147 PrintMessage("No crate available\n"); 136 148 return; 137 149 } … … 149 161 void User::cmd_help() { 150 162 151 char Buffer[MAX_COM_SIZE];152 163 for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) { 153 snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);154 PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);155 }156 157 PrintMessage(".<command> Execute shell command\n\n"164 PrintMessage("%-10s%s\n", CommandList[i].Name, CommandList[i].Help); 165 } 166 167 PrintMessage("\nUse '?' as argument to get more extensive help.\n" 168 "Commands 'pixel' and 'channel' allow and arbitary number of argument pairs.\n" 158 169 "Items in <> are mandatory, in [] optional, | indicates mutual exclusive or.\n" 159 " Channel ranges can be 'all', a single number or in the form 'a-b'.\n");170 "Ranges can be 'all', a single number or in the form 'a-b'.\n"); 160 171 } 161 172 … … 164 175 // 165 176 void User::cmd_synch() { 166 167 if (ActiveCrate == -1) return;168 177 169 178 if (Crates[ActiveCrate]->Synch()) PrintMessage("Synchronized crate %d\n", ActiveCrate); … … 199 208 unsigned int Errors=0; 200 209 double Double; 201 struct Range C rt, Chan;202 unsigned int PixelID = 0;210 struct Range Chan, Pixel; 211 unsigned int Crate, Channel; 203 212 vector< map<unsigned int, double> > Voltages (Crates.size()); 213 vector < pair <unsigned int, unsigned int> > P; 204 214 205 215 // Loop over all parameters 206 216 for (unsigned int n=1; n < Parameter.size()-1; n+=2) { 207 217 218 // Convert voltage value and check format 219 if (!ConvertToDouble(Parameter[n+1], &Double) && !Match(Parameter[n+1], "default") && !Match(Parameter[n+1], "info")) { 220 PrintMessage("Error: Wrong number format for voltage setting\n"); 221 continue; 222 } 223 224 // Extract affected channels for this argument pair 225 P.clear(); 226 208 227 // Pixel identification? 209 228 if (Match(Parameter[0], "pixel")) { 210 // Skip if first character is not digit 211 if (isdigit(Parameter[n][0] == 0)) continue; 229 Pixel.Min = 0; 230 Pixel.Max = 1439; 231 232 if (!ConvertToRange(Parameter[n], Pixel)) { 233 PrintMessage("Pixel ID out-of-range for parameter %d, skipping channel\n", n); 234 continue; 235 } 212 236 213 // Extract pixel ID 214 PixelID = atoi(Parameter[n].c_str()); 215 216 // Skip if pixel ID not existing 217 if (PixMap->Pixel_to_HVcrate(PixelID) == PixMap->PM_ERROR_CODE) continue; 218 219 Crt.Min = Crt.Max = PixMap->Pixel_to_HVcrate(PixelID); 220 Chan.Min = Chan.Max = PixMap->Pixel_to_HVboard(PixelID)*NUM_CHANNELS + PixMap->Pixel_to_HVchannel(PixelID); 237 for (int i=Pixel.Min; i<=Pixel.Max; i++) { 238 Crate = PixMap->Pixel_to_HVcrate(i); 239 Channel = PixMap->Pixel_to_HVboard(i)*NUM_CHANNELS + PixMap->Pixel_to_HVchannel(i); 240 241 // Skip if pixel ID or corresponding channels not existing 242 if (Crate!=PixMap->PM_ERROR_CODE && Crate<Crates.size() && Channel<MAX_NUM_BOARDS*NUM_CHANNELS) { 243 P.push_back(make_pair(Crate, Channel)); 244 } 245 } 221 246 } 222 247 // Channel identification 223 248 else { 224 if (ActiveCrate == -1) continue;225 else Crt.Min = Crt.Max = ActiveCrate;226 227 249 Chan.Min = 0; 228 250 Chan.Max = MAX_NUM_BOARDS*NUM_CHANNELS-1; … … 232 254 continue; 233 255 } 234 } 235 236 // Convert voltage value and check format 237 if (!ConvertToDouble(Parameter[n+1], &Double) && !Match(Parameter[n+1], "default")) { 238 PrintMessage("Error: Wrong number format for voltage setting\n"); 239 continue; 240 } 241 242 // Loop over given crates and channels 243 for (int i=Crt.Min; i<=Crt.Max; i++) for (int j=Chan.Min; j<=Chan.Max; j++) { 244 // Check that indices are in legal range 245 if (i<0 || i>=(int) Crates.size() || j<0 || j >=MAX_NUM_BOARDS*NUM_CHANNELS) continue; 256 257 for (int i=Chan.Min; i<=Chan.Max; i++) P.push_back(make_pair(ActiveCrate, i)); 258 } 259 260 // Loop over all given channels 261 for (unsigned int i=0; i<P.size(); i++) { 262 Crate = P[i].first; 263 Channel = P[i].second; 264 265 // Should only information be printed? 266 if (Match(Parameter[n+1], "info")) { 267 PrintMessage("Crate %2d, channel %3d ", Crate, Channel); 268 if (!Crates[Crate]->Present[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]) { 269 PrintMessage("(channel not present in crate)"); 270 } 271 PrintMessage("\n Channel is on board %d, board channel %d\n", Channel/32, Channel%32); 272 273 // Print pixel information 274 vector<unsigned int> List = PixMap->HV_to_Pixel(Crate, Channel/NUM_CHANNELS, Channel%NUM_CHANNELS); 275 PrintMessage("\n Pixel IDs (default voltage): "); 276 for (unsigned int j=0; j<List.size(); j++) PrintMessage("%u (%.2f) ", List[j], List[j]<DefaultVoltage.size() ? DefaultVoltage[List[j]] : 0); 277 if (List.empty()) PrintMessage("none"); 278 279 // Print voltage and current 280 PrintMessage("\n Voltage setpoint: %.2f V (DAC %u) Current: %.2f uA ", Crates[Crate]->GetVoltage(Channel), Crates[Crate]->GetDAC(Channel), Crates[Crate]->GetCurrent(Channel)); 281 282 if (Crates[Crate]->OC[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]) PrintMessage("(overcurrent)\n"); 283 else PrintMessage("\n"); 284 285 continue; 286 } 287 288 // Check that indices are in legal range (safety check, should be unnecessary) 289 if (Crate >= Crates.size() || Channel >=MAX_NUM_BOARDS*NUM_CHANNELS) continue; 246 290 247 291 // Voltage change (number starts with + oder -) ignored if current DAC value is zero 248 if ((Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') && Crates[i]->GetDAC(j) == 0) continue; 249 292 if (Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') { 293 if (Crates[Crate]->GetDAC(Channel) == 0) continue; 294 } 295 250 296 // Should the default value be set? 251 297 if (Match(Parameter[n+1], "default")) { 252 // Pixel ID given directly or channel number? 253 if (!Match(Parameter[0], "pixel")) { 254 vector<unsigned int> List = PixMap->HV_to_Pixel(i, j/NUM_CHANNELS, j%NUM_CHANNELS); 255 if (!List.empty()) PixelID = List[0]; 256 else PixelID = numeric_limits<unsigned int>::max(); 257 } 258 259 // Set default voltage 260 if (PixelID < DefaultVoltage.size()) Voltages[i][j] = DefaultVoltage[PixelID]; 261 else Voltages[i][j] = 0; 262 continue; 298 vector<unsigned int> List = PixMap->HV_to_Pixel(Crate, Channel/NUM_CHANNELS, Channel%NUM_CHANNELS); 299 if (!List.empty() && List[0]<DefaultVoltage.size()) Double = DefaultVoltage[List[0]]; 300 else Double = 0; 263 301 } 264 302 265 303 // Relative or absolute change? 266 if (isdigit(Parameter[n+1][0]) == 0) Voltages[ i][j] = Crates[i]->GetVoltage(j) + Double;267 else Voltages[ i][j] = Double;304 if (isdigit(Parameter[n+1][0]) == 0) Voltages[Crate][Channel] = Crates[Crate]->GetVoltage(Channel) + Double; 305 else Voltages[Crate][Channel] = Double; 268 306 } // Channels 269 307 } // Loop over command argument … … 305 343 for (unsigned int Crate=0; Crate<Crates.size(); Crate++) if (Match(Crates[Crate]->Name, Buffer)) { 306 344 307 if ( (int)Crate != ActiveCrate) continue;345 if (Crate != ActiveCrate) continue; 308 346 PrintMessage("Found bias settings for crate %s (#%d)\n\r", Crates[Crate]->Name, Crate); 309 347 … … 359 397 void User::cmd_reset() { 360 398 361 if (ActiveCrate == -1) return;362 363 399 if (Crates[ActiveCrate]->SystemReset() == 1) PrintMessage("System reset of crate %d\n", ActiveCrate); 364 400 else PrintMessage("Error: Could not reset crate %d\n", ActiveCrate); 365 366 401 } 367 402 … … 372 407 373 408 double Voltage; 374 375 if (ActiveCrate == -1) return;376 409 377 410 if (!ConvertToDouble(Parameter[1], &Voltage)) { … … 432 465 433 466 PrintMessage(" Number of crates: %d\n", Crates.size()); 434 PrintMessage(" Active crate: %d\n", ActiveCrate);467 PrintMessage(" Active crate: %d\n", ActiveCrate); 435 468 PrintMessage(" Refresh rate: %.2f Hz\n", fStatusRefreshRate); 436 469 PrintMessage(" Time out: %.2f s\n\n", fTimeOut); … … 480 513 pthread_kill(MainThread, SIGTERM); 481 514 } 482 515 516 // 517 // Execute shell command 518 // 519 void User::cmd_shell() { 520 521 if (system(Parameter[1].c_str()) == -1) PrintMessage("Error with system() call\n"); 522 } 523 483 524 484 525 // … … 521 562 // Remove channels already at target (check for DAC, not for floating-point voltage) 522 563 for (map<unsigned int, double>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) { 523 //if (Crates[Crate]->GetDAC(it->first) == (unsigned int ) (it->second/90.0*0x0fff)) Voltages.erase(it);524 564 if (fabs(Crates[Crate]->GetVoltage(it->first)-it->second) < 0.001) Voltages.erase(it); 525 565 } … … 549 589 static bool Warned = false; 550 590 int Ret; 591 unsigned int Count=0; 551 592 552 593 while (!ExitRequest) { … … 592 633 for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 593 634 if (Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS]) { 594 Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 635 if (Count++ < 5) Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 636 if (Count == 5) Message(ERROR, "Five overcurrent warnings, no more!"); 595 637 Voltages[j] = 0; 596 638 }
Note:
See TracChangeset
for help on using the changeset viewer.