Changeset 11915
- Timestamp:
- 08/26/11 09:47:05 (13 years ago)
- Location:
- fact/BIASctrl
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/BIASctrl/BIASctrl.cc
r11906 r11915 19 19 20 20 // Main program 21 int main( ) {21 int main(int argc, char *argv[]) { 22 22 23 23 char *Command; … … 36 36 37 37 // Construct main instance 38 static User M ;38 static User M(argc == 2 ? argv[1] : string()); 39 39 40 40 // Handle command-line input -
fact/BIASctrl/Crate.cc
r11906 r11915 25 25 Name = new char [CrateName.size()+1]; 26 26 strcpy(Name, CrateName.c_str()); 27 CrateNumber = Number;28 27 WrapCount = -1; 29 28 LastReset = 0; … … 41 40 // Create DIM services 42 41 stringstream ID; 43 ID << setfill('0') << setw(2) << CrateNumber;42 ID << setfill('0') << setw(2) << Number; 44 43 45 44 NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name); … … 51 50 // Open device 52 51 if ((fDescriptor = open(("/dev/"+CrateName).c_str(), O_RDWR|O_NOCTTY|O_NDELAY)) == -1) { 53 if (errno != 2) m->PrintMessage("Error: Could not open device % d/%s (%s)\n", CrateNumber, Name, strerror(errno));52 if (errno != 2) m->PrintMessage("Error: Could not open device %s (%s)\n", Name, strerror(errno)); 54 53 return; 55 54 } … … 57 56 // Generate FILE pointer 58 57 if ((File = fdopen(fDescriptor, "rb+")) == NULL) { 59 m->PrintMessage("Error: fdopen() failed on device % d/%s (%s)\n", CrateNumber, Name, strerror(errno));58 m->PrintMessage("Error: fdopen() failed on device %s (%s)\n", Name, strerror(errno)); 60 59 return; 61 60 } … … 93 92 94 93 if(fDescriptor != -1) { 95 if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate % dto zero voltage", Name);94 if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate %s to zero voltage", Name); 96 95 97 96 if (File == NULL) { … … 231 230 OC[i] = Data[Count] & 128; 232 231 Present[i] = (Data[Count+2] & 0x70) == 0 ? true : false; 233 if (!ResetHit) ResetHit= (Data[Count+2] & 0x80) == 0 ? false : true;232 ResetHit |= (Data[Count+2] & 0x80) == 0 ? false : true; 234 233 Count += 3; 235 234 } … … 243 242 // Limit voltage 244 243 Voltage = min(Voltage, atof(m->GetConfig("VoltageLimit").c_str())); 244 Voltage = max(Voltage, 0.0); 245 245 246 246 // Calculate DAC value … … 271 271 // Build and execute commands 272 272 for (map<unsigned int, double>::iterator it = V.begin(); it != V.end(); ++it) { 273 // Limit maximumvoltage273 // Limit voltage 274 274 it->second = min(it->second, atof(m->GetConfig("VoltageLimit").c_str())); 275 it->second = max(it->second, 0.0); 275 276 276 277 // If DAC value unchanged, do not send command -
fact/BIASctrl/Crate.h
r11906 r11915 16 16 const unsigned int MAX_NUM_BOARDS = 13; // Maximum number of boards per crate 17 17 const unsigned int NUM_CHANNELS = 32; // Channels per bias board 18 const float RESISTOR = 1000; // Resistance in Ohm for voltage correction18 const float RESISTOR = 2000; // Resistance in Ohm for voltage correction 19 19 const int MAX_ERR_COUNT = 10; // Maximum number of errors before reporting stopped 20 20 class User; … … 23 23 24 24 class User *m; 25 int CrateNumber;26 25 int fDescriptor; 27 26 FILE *File; -
fact/BIASctrl/History.txt
r11906 r11915 17 17 5/8/2011 Default voltages now given per bias channel, not per pixel 18 18 15/8/2011 Added global voltage limit and minimum time between system resets. 19 24/8/2011 Ramping also for decreasing voltages. 20 26/8/2011 Removed support for multiple crates. Crate name can be given as 21 command line argument. -
fact/BIASctrl/User.cc
r11906 r11915 16 16 const char *Help; 17 17 } CommandList[] = 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)"},18 {{"pixel", &User::cmd_hv, 2, true, "<range> <voltage|default|info>", "Change bias of pixels"}, 19 {"channel", &User::cmd_hv, 2, true, "<range> <voltage|default|info>", "Change bias of channels of active crate"}, 20 20 {"gs", &User::cmd_gs, 1, true, "[crate] <volt>", "Global voltage set active crate"}, 21 21 {"reset", &User::cmd_reset, 0, true, "", "Reset active crate"}, 22 22 {"synch", &User::cmd_synch, 0, true, "", "Synchronize active crate"}, 23 {"crate", &User::cmd_crate, 1, true, "<number>", "Select active crate"},24 23 {"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)"},24 {"mode", &User::cmd_mode, 1, true, "<static|dynamic>", "Set voltage stabilization mode (experimental)"}, 26 25 {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"}, 27 26 {"save", &User::cmd_save, 1, true, "<file>", "Save current bias settings to file"}, … … 33 32 // Constructor 34 33 // 35 User::User( ): EvidenceServer(SERVER_NAME) {34 User::User(string Board): EvidenceServer(SERVER_NAME) { 36 35 37 36 MainThread = pthread_self(); … … 42 41 43 42 // Get/initialize configuration data 44 vector<string> Boards = Tokenize(GetConfig("Boards", "dummy"), " \t");43 if (Board.empty()) Board = GetConfig("Boards", "dummy"); 45 44 GetConfig("TimeOut"); 46 45 GetConfig("VoltageLimit"); … … 48 47 GetConfig("RampSpeed"); 49 48 GetConfig("UpdatePeriod"); 50 51 49 vector<string> Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t"); 52 50 … … 55 53 } 56 54 57 // Open devices 58 for (unsigned int i=0; i<Boards.size(); i++) { 59 60 class Crate *New = new class Crate(Boards[i], Crates.size(), this); 61 62 if (New->InitOK) { 63 PrintMessage("Synchronized and reset crate %s (#%d)\n", Boards[i].c_str(), Crates.size()); 64 Crates.push_back(New); 65 } 66 else { 67 Message(WARN, "Failed to synchronize crate %s", Boards[i].c_str()); 68 delete New; 69 } 70 } 71 ActiveCrate = 0; 55 // Open device 56 Dev = new class Crate(Board, 0, this); 57 58 if (Dev->InitOK) PrintMessage("Synchronized and reset crate %s\n", Board.c_str()); 59 else { 60 Message(WARN, "Failed to synchronize crate %s", Board.c_str()); 61 delete Dev; 62 Dev = NULL; 63 } 72 64 73 65 // Create PixelMap instance (map from config server) … … 98 90 if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret)); 99 91 100 // Delete all crates101 for (unsigned int i=0; i<Crates.size(); i++) delete Crates[i];92 // Delete crate 93 delete Dev; 102 94 103 95 delete DIMCommand; … … 143 135 } 144 136 145 // Check if crate sneeded146 if (CommandList[CmdNumber].NeedCrate && Crates.empty()) {137 // Check if crate needed 138 if (CommandList[CmdNumber].NeedCrate && Dev==NULL) { 147 139 PrintMessage("No crate available\n"); 148 140 return; … … 172 164 173 165 // 174 // Synchronize boards166 // Synchronize crate 175 167 // 176 168 void User::cmd_synch() { 177 169 178 if (Crates[ActiveCrate]->Synch()) PrintMessage("Synchronized crate %d\n", ActiveCrate); 179 else PrintMessage("Failed to synchronize crate %d\n", ActiveCrate); 180 } 181 182 // 183 // Select active crate 184 // 185 void User::cmd_crate() { 186 187 int Crate; 188 189 if (!ConvertToInt(Parameter[1], &Crate)) { 190 PrintMessage("Error: Wrong number format\n"); 191 return; 192 } 193 194 // Check limits 195 if (Crate<0 || Crate>=(int) Crates.size()) { 196 PrintMessage("Crate number %d not existing\n", Crate); 197 return; 198 } 199 200 ActiveCrate = Crate; 170 if (Dev->Synch()) PrintMessage("Synchronized crate\n"); 171 else PrintMessage("Failed to synchronize crate\n"); 201 172 } 202 173 … … 206 177 void User::cmd_hv() { 207 178 208 unsigned int Errors=0;179 unsigned int Channel, Errors = 0; 209 180 double Double; 210 181 struct Range Chan, Pixel; 211 unsigned int Crate, Channel; 212 vector< map<unsigned int, double> > Voltages (Crates.size()); 213 vector < pair <unsigned int, unsigned int> > P; 182 map<unsigned int, double> Voltages; 183 vector<unsigned int> Channels; 214 184 215 185 // Loop over all parameters … … 223 193 224 194 // Extract affected channels for this argument pair 225 P.clear();195 Channels.clear(); 226 196 227 197 // Pixel identification? … … 236 206 237 207 for (int i=Pixel.Min; i<=Pixel.Max; i++) { 238 Crate = PixMap->Pixel_to_HVcrate(i);239 208 Channel = PixMap->Pixel_to_HVboard(i)*NUM_CHANNELS + PixMap->Pixel_to_HVchannel(i); 240 209 241 210 // 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));211 if (PixMap->Pixel_to_HVcrate(i) == 0 && Channel<MAX_NUM_BOARDS*NUM_CHANNELS) { 212 Channels.push_back(Channel); 244 213 } 245 214 } … … 255 224 } 256 225 257 for (int i=Chan.Min; i<=Chan.Max; i++) P.push_back(make_pair(ActiveCrate, i));226 for (int i=Chan.Min; i<=Chan.Max; i++) Channels.push_back(i); 258 227 } 259 228 260 229 // 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; 230 for (unsigned int i=0; i<Channels.size(); i++) { 231 Channel = Channels[i]; 264 232 265 233 // Should only information be printed? 266 234 if (Match(Parameter[n+1], "info")) { 267 PrintMessage("C rate %2d, channel %3d ", Crate, Channel);268 if (! Crates[Crate]->Present[Channel]) PrintMessage("(channel not present in crate)");269 PrintMessage("\n Channelis on board %d, board channel %d\n", Channel/32, Channel%32);235 PrintMessage("Channel %d ", Channel); 236 if (!Dev->Present[Channel]) PrintMessage(" is not present in crate\n"); 237 else PrintMessage("is on board %d, board channel %d\n", Channel/32, Channel%32); 270 238 271 239 // Print pixel information 272 vector<unsigned int> List = PixMap->HV_to_Pixel( Crate, Channel/NUM_CHANNELS, Channel%NUM_CHANNELS);240 vector<unsigned int> List = PixMap->HV_to_Pixel(0, Channel/NUM_CHANNELS, Channel%NUM_CHANNELS); 273 241 PrintMessage("\n Default voltage: %.2f Pixel IDs: ", Channel < DefaultVoltage.size() ? DefaultVoltage[Channel] : 0); 274 242 for (unsigned int j=0; j<List.size(); j++) PrintMessage("%u ", List[j]); … … 276 244 277 245 // Print voltage and current 278 PrintMessage("\n Voltage setpoint: %.2f V (DAC %u) Current: %.2f uA ", Crates[Crate]->GetVoltage(Channel), Crates[Crate]->GetDAC(Channel), Crates[Crate]->GetCurrent(Channel));279 280 if ( Crates[Crate]->OC[Channel]) PrintMessage("(overcurrent)\n");246 PrintMessage("\n Voltage setpoint: %.2f V (DAC %u) Current: %.2f uA ", Dev->GetVoltage(Channel), Dev->GetDAC(Channel), Dev->GetCurrent(Channel)); 247 248 if (Dev->OC[Channel]) PrintMessage("(overcurrent)\n"); 281 249 else PrintMessage("\n"); 282 250 … … 284 252 } 285 253 286 // Check that indices are in legal range (safety check, should be unnecessary) 287 if (Crate >= Crates.size() || Channel >=MAX_NUM_BOARDS*NUM_CHANNELS) continue; 288 289 // Voltage change (number starts with + oder -) ignored if current DAC value is zero 290 if (Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') { 291 if (Crates[Crate]->GetDAC(Channel) == 0) continue; 292 } 254 // Get current voltage on first change of a channel 255 if (Voltages.count(Channel) == 0) Voltages[Channel] = Dev->GetVoltage(Channel); 256 257 // Voltage change (number starts with + oder -) ignored if voltage is zero 258 if (Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') if (Voltages[Channel] == 0) continue; 293 259 294 260 // Should the default value be set? … … 297 263 else Double = 0; 298 264 } 299 265 300 266 // Relative or absolute change? 301 if ( isdigit(Parameter[n+1][0]) == 0) Voltages[Crate][Channel] = Crates[Crate]->GetVoltage(Channel) +Double;302 else Voltages[C rate][Channel] = Double;267 if (Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') Voltages[Channel] += Double; 268 else Voltages[Channel] = Double; 303 269 } // Channels 304 270 } // Loop over command argument 305 271 306 272 // Ramp voltages and update DIM services 307 for (unsigned int i=0; i<Voltages.size(); i++) { 308 Errors += RampVoltages(i, Voltages[i]); 309 Crates[i]->UpdateDIM(); 310 } 273 Errors += RampVoltages(Voltages); 274 Dev->UpdateDIM(); 311 275 312 276 // Error message only if not yet too many errors 313 277 if (Errors > 0) { 314 for (unsigned int i=0; i<Crates.size(); i++) { 315 if (Crates[i]->ErrorCount > MAX_ERR_COUNT) return; 316 } 278 if (Dev->ErrorCount > MAX_ERR_COUNT) return; 317 279 Message(ERROR, "%d errors occurred from SetChannels()", Errors); 318 280 } … … 338 300 339 301 // Scan through file line by line 340 while (fgets(Buffer, sizeof(Buffer), File) != NULL) { 341 for (unsigned int Crate=0; Crate<Crates.size(); Crate++) if (Match(Crates[Crate]->Name, Buffer)) { 342 343 if (Crate != ActiveCrate) continue; 344 PrintMessage("Found bias settings for crate %s (#%d)\n\r", Crates[Crate]->Name, Crate); 345 346 Voltages.clear(); 347 Channel = 0; 348 while (fscanf(File, "%lf", &Value)==1 && Channel<MAX_NUM_BOARDS*NUM_CHANNELS) { 349 Voltages[Channel++] = Value; 350 } 351 352 // Ramp channels 353 Errors += RampVoltages(Crate, Voltages); 354 355 // Update DIM service 356 Crates[Crate]->UpdateDIM(); 357 358 if (ferror(File) != 0) { 359 PrintMessage("Error reading DAC value from file, terminating. (%s)\n",strerror(errno)); 360 return; 361 } 362 else PrintMessage("\nFinished updating board\n"); 363 } // Loop over boards 364 } // while() 302 while (fgets(Buffer, sizeof(Buffer), File) != NULL) if (Match(Dev->Name, Buffer)) { 303 PrintMessage("Found bias settings for crate %s\n\r", Dev->Name); 304 305 Voltages.clear(); 306 Channel = 0; 307 while (fscanf(File, "%lf", &Value)==1 && Channel<MAX_NUM_BOARDS*NUM_CHANNELS) { 308 Voltages[Channel++] = Value; 309 } 310 311 // Ramp channels 312 Errors += RampVoltages(Voltages); 313 314 // Update DIM service 315 Dev->UpdateDIM(); 316 317 if (ferror(File) != 0) { 318 PrintMessage("Error reading DAC value from file, terminating. (%s)\n",strerror(errno)); 319 return; 320 } 321 else PrintMessage("\nFinished updating board\n"); 322 } // if() 365 323 366 324 if (Errors != 0) PrintMessage("Warning: %d error(s) occurred\n", Errors); … … 369 327 370 328 // 371 // Reset crate s329 // Reset crate 372 330 // 373 331 void User::cmd_reset() { 374 332 375 if ( Crates[ActiveCrate]->SystemReset()) PrintMessage("System reset of crate %d\n", ActiveCrate);376 else PrintMessage("Error: Could not reset crate %d\n", ActiveCrate);333 if (Dev->SystemReset()) PrintMessage("System reset of crate\n"); 334 else PrintMessage("Error: Could not reset crate\n"); 377 335 } 378 336 … … 389 347 } 390 348 391 if (! Crates[ActiveCrate]->GlobalSet(Voltage)) {392 PrintMessage("Error: Could not global set crate %d\n", ActiveCrate);349 if (!Dev->GlobalSet(Voltage)) { 350 PrintMessage("Error: Could not global set crate\n"); 393 351 } 394 352 } … … 408 366 409 367 fprintf(File,"********** Bias settings of %s **********\n\n", ctime(&Time)); 410 411 for (unsigned int i=0; i<Crates.size(); i++) { 412 fprintf(File, "%s\n\n", Crates[i]->Name); 413 414 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j)); 415 fprintf(File, "\n"); 416 } 368 fprintf(File, "%s\n\n", Dev->Name); 369 370 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ", Dev->GetVoltage(j)); 371 fprintf(File, "\n"); 417 372 418 373 if (fclose(File) != 0) { … … 429 384 else { 430 385 Mode = mode_dynamic; 431 for (unsigned int i=0; i<Crates.size(); i++) { 432 Crates[i]->SetRefCurrent(); 433 } 386 Dev->SetRefCurrent(); 434 387 } 435 388 } … … 440 393 void User::cmd_status() { 441 394 442 PrintMessage(" Number of crates: %d\n", Crates.size()); 443 PrintMessage(" Active crate: %d\n", ActiveCrate); 444 PrintMessage(" Update delay: %d sec\n", min(atoi(GetConfig("UpdatePeriod").c_str()), 1)); 445 PrintMessage(" Time out: %.2f sec\n", atof(GetConfig("TimeOut").c_str())); 446 PrintMessage(" Max ramp speed %.2f V/10 ms\n", atof(GetConfig("RampSpeed").c_str())); 447 PrintMessage(" Voltage limit: %.2f V\n", atof(GetConfig("VoltageLimit").c_str())); 448 PrintMessage(" Minium reset delay: %u sec\n", atoi(GetConfig("MinResetPeriod").c_str())); 449 450 for (unsigned int i=0; i<Crates.size(); i++) { 451 452 PrintMessage(" CRATE %d (%s)\n Wrap counter: %s (%d) Reset: %s Error count: %d %s\n ", 453 i, Crates[i]->Name, Crates[i]->WrapOK ? "ok":"error", Crates[i]->WrapCount, 454 Crates[i]->ResetHit ? "yes" : "no", Crates[i]->ErrorCount, Crates[i]->Disabled ? "(DISABLED)":""); 455 456 // Read all channels 457 if (!Crates[i]->ReadAll()) { 458 PrintMessage("Could not update status from crate %d\n", i); 459 continue; 460 } 461 462 if (Parameter.size() == 1) PrintMessage("Channel voltages (in V)"); 463 else if (Match(Parameter[1], "dac")) PrintMessage("Channel voltages (in DAC values)"); 464 else PrintMessage("Channel currents (in uA)"); 465 466 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 467 if (j%12 == 0) PrintMessage("\n%3.1d: ", j); 468 if (!Crates[i]->Present[j]) PrintMessage(" - "); 469 else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->GetVoltage(j)); 470 else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->GetDAC(j)); 471 else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j] ? "OC":""); 472 } 473 PrintMessage("\n"); 474 } 395 // Overview information 396 PrintMessage("Update delay: %2d sec Time out: %.2f sec Minium reset delay: %u sec\n", 397 min(atoi(GetConfig("UpdatePeriod").c_str()), 1), atof(GetConfig("TimeOut").c_str()), 398 atoi(GetConfig("MinResetPeriod").c_str())); 399 PrintMessage("Voltage limit: %.2f V Ramp speed: %.2f V/10 ms\n", 400 atof(GetConfig("VoltageLimit").c_str()), atof(GetConfig("RampSpeed").c_str())); 401 402 if (Dev == NULL) return; 403 404 // Details 405 PrintMessage("\nCRATE %s Wrap counter: %s (%d) Reset: %s Error count: %d %s\n ", 406 Dev->Name, Dev->WrapOK ? "ok":"error", Dev->WrapCount, 407 Dev->ResetHit ? "yes" : "no", Dev->ErrorCount, Dev->Disabled ? "(DISABLED)":""); 408 409 // Read all channels 410 if (!Dev->ReadAll()) { 411 PrintMessage("Could not update status, ReadAll() failed\n"); 412 return; 413 } 414 415 // Voltage or current list 416 if (Parameter.size() == 1) PrintMessage("Channel voltages (in V)"); 417 else if (Match(Parameter[1], "dac")) PrintMessage("Channel voltages (in DAC values)"); 418 else PrintMessage("Channel currents (in uA)"); 419 420 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 421 if (j%12 == 0) PrintMessage("\n%3.1d: ", j); 422 if (!Dev->Present[j]) PrintMessage(" - "); 423 else if (Parameter.size() == 1) PrintMessage("%#5.2f", Dev->GetVoltage(j)); 424 else if (Match(Parameter[1], "dac")) PrintMessage("%5d", Dev->GetDAC(j)); 425 else PrintMessage("%#5.2f", Dev->GetCurrent(j)); 426 // Print overcurrent marker 427 PrintMessage("%s ", Dev->OC[j] ? "*":" "); 428 } 429 PrintMessage("\n"); 475 430 } 476 431 … … 523 478 524 479 // Ramp to new voltage with given maximum step 525 // No ramping when decreasing voltage 526 unsigned int User::RampVoltages(int Crate, map<unsigned int, double> Voltages) { 480 unsigned int User::RampVoltages(map<unsigned int, double> Voltages) { 527 481 528 482 map<unsigned int, double> Target; 529 483 int Errors = 0; 530 double MaxDiff = atof(GetConfig("RampSpeed").c_str()); 531 532 // Ramp until all channels at desired value 484 double V, Lim, MaxDiff = atof(GetConfig("RampSpeed").c_str()); 485 533 486 while (!Voltages.empty() && Errors < MAX_ERR_COUNT) { 534 // Remove channels already at target (check for DAC, not for floating-point voltage) 535 for (map<unsigned int, double>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) { 536 if (fabs(Crates[Crate]->GetVoltage(it->first)-it->second) < 0.001) Voltages.erase(it); 487 // Voltage limit evaluate here in case of asynchronous update in config file 488 Lim = atof(GetConfig("VoltageLimit").c_str()); 489 490 // Remove channels already at target or at voltage limit 491 for (map<unsigned int, double>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) { 492 // Channel at target? 493 if (fabs(Dev->GetVoltage(it->first)-it->second) < 0.001) Voltages.erase(it); 494 // Channel at voltage limit? 495 if (it->second > Lim && Dev->GetVoltage(it->first) == Lim) Voltages.erase(it); 496 if (it->second < 0 && Dev->GetVoltage(it->first) == 0) Voltages.erase(it); 537 497 } 538 498 539 // Limit voltage changes to fMaxDiff499 // Limit voltage changes to MaxDiff 540 500 Target = Voltages; 541 501 for (map<unsigned int, double>::iterator it = Target.begin(); it != Target.end(); ++it) { 542 if (Crates[Crate]->GetVoltage(it->first) + MaxDiff < it->second) { 543 it->second = Crates[Crate]->GetVoltage(it->first) + MaxDiff; 544 } 502 V = Dev->GetVoltage(it->first); 503 // Ramp up 504 if ((V < it->second) && (V + MaxDiff < it->second)) it->second = V + MaxDiff; 505 // Ramp down 506 if ((V > it->second) && (V - MaxDiff > it->second)) it->second = V - MaxDiff; 545 507 } 546 508 547 509 // Set channels to next target and wait 10 ms 548 if (! Crates[Crate]->SetChannels(Target)) Errors++;510 if (!Dev->SetChannels(Target)) Errors++; 549 511 usleep(10000); 550 512 } … … 561 523 int Ret; 562 524 525 // End if no crate available 526 if (Dev == NULL) return; 527 563 528 while (!ExitRequest) { 564 565 529 // Wait (this is the only allowed cancelation point) 566 530 if ((Ret=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) != 0) { … … 572 536 } 573 537 574 // Check all crates 575 for (unsigned int i=0; i<Crates.size(); i++) { 576 // Crate disabled because of too many errors? 577 if (Crates[i]->Disabled) continue; 578 579 // Read all channels 580 if (!Crates[i]->ReadAll()) { 581 Message(ERROR, "Monitor thread could not read status from crate %d", i); 582 continue; 583 } 584 585 // Check if crate push button was hit 586 if (Crates[i]->ResetHit) { 587 Message(INFO, "Manual reset of crate %d, setting voltages to zero and issuing system reset", i); 588 if (!Crates[i]->GlobalSet(0)) Message(ERROR, "Global set to zero voltage of crate %d failed", i); 589 if (!Crates[i]->SystemReset()) Message(ERROR, "System reset of crate %d failed", i); 590 } 591 592 // Check for overcurrent and set voltage to zero if occurred 593 map<unsigned int, double> Voltages; 594 595 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) { 596 if (Crates[i]->OC[j]) { 597 Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS); 598 Voltages[j] = 0; 599 } 600 } 601 if (!Crates[i]->SetChannels(Voltages)) Message(ERROR, "Error when setting voltages of crate %d", i); 602 603 if (Mode == mode_dynamic) Crates[i]->AdaptVoltages(); 604 } // for 538 // Check crate 539 if (Dev->Disabled) continue; 540 541 // Read all channels 542 if (!Dev->ReadAll()) { 543 Message(ERROR, "Monitor thread could not read status, ReadAll() failed\n"); 544 continue; 545 } 546 547 // Check if crate push button was hit 548 if (Dev->ResetHit) { 549 Message(INFO, "Manual reset of crate, setting voltages to zero and issuing system reset"); 550 if (!Dev->GlobalSet(0)) Message(ERROR, "Global set to zero voltage of crate failed"); 551 if (!Dev->SystemReset()) Message(ERROR, "System reset of crate failed"); 552 } 553 554 // Check for overcurrent and set voltage to zero if occurred 555 map<unsigned int, double> Voltages; 556 557 for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) if (Dev->OC[j]) Voltages[j] = 0; 558 if (!Voltages.empty()) { 559 if (!Dev->SetChannels(Voltages)) Message(ERROR, "Error setting voltage to zero for channels with overcurrent"); 560 Dev->UpdateDIM(); 561 } 562 563 if (Mode == mode_dynamic) Dev->AdaptVoltages(); 605 564 } // while 606 565 } -
fact/BIASctrl/User.h
r11906 r11915 31 31 RunMode Mode; 32 32 33 std::vector<class Crate *> Crates;33 class Crate *Dev; 34 34 std::vector<double> DefaultVoltage; 35 35 … … 47 47 48 48 public: 49 unsigned int ActiveCrate; 50 51 User(); 49 User(std::string); 52 50 ~User(); 53 51 54 52 void PrintMessage(const char *, ...); 55 unsigned int RampVoltages( int,std::map<unsigned int, double>);53 unsigned int RampVoltages(std::map<unsigned int, double>); 56 54 void Monitor(); 57 55 static void LaunchMonitor(User *); … … 62 60 void cmd_exit(); void cmd_reset(); 63 61 void cmd_help(); void cmd_mode(); 64 void cmd_ crate(); void cmd_shell();62 void cmd_shell(); 65 63 }; 66 64
Note:
See TracChangeset
for help on using the changeset viewer.