Ignore:
Timestamp:
08/15/11 17:01:20 (13 years ago)
Author:
ogrimm
Message:
Added voltage and system reset rate limit
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/User.cc

    r11781 r11906  
    2626        {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"},
    2727        {"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"},
    3028        {"help", &User::cmd_help, 0, false, "", "Print help"},
    3129        {"exit", &User::cmd_exit, 0, false, "", "Exit program"},
     
    4341  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
    4442
    45   // Get configuration data
     43  // Get/initialize configuration data
    4644  vector<string> Boards = Tokenize(GetConfig("Boards", "dummy"), " \t");
    47   fTimeOut = atof(GetConfig("TimeOut").c_str());
    48   fStatusRefreshRate = atof(GetConfig("StatusRefreshRate").c_str());
    49   fMaxDiff = atof(GetConfig("HVMaxDiffNew").c_str());
    50 
    51   if (fStatusRefreshRate < MIN_RATE || fStatusRefreshRate > MAX_RATE)  fStatusRefreshRate = 1;
     45  GetConfig("TimeOut");
     46  GetConfig("VoltageLimit");
     47  GetConfig("MinResetPeriod");
     48  GetConfig("RampSpeed");
     49  GetConfig("UpdatePeriod");
    5250
    5351  vector<string> Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t");
     
    6260    class Crate *New = new class Crate(Boards[i], Crates.size(), this);
    6361
    64     if (New->InitOK && New->Synch()) {
     62    if (New->InitOK) {
    6563       PrintMessage("Synchronized and reset crate %s (#%d)\n", Boards[i].c_str(), Crates.size());
    6664       Crates.push_back(New);
     
    9492  int Ret;
    9593 
    96   // Wait for thread to quit
    97   if ((Ret = pthread_cancel(Thread)) != 0) Message(ERROR, "pthread_cancel() failed (%s)", strerror(Ret));
     94  // Wait for thread to quit (ignore error if thread did already exit)
     95  if ((Ret = pthread_cancel(Thread)) != 0) {
     96        if (Ret != ESRCH) Message(ERROR, "pthread_cancel() failed (%s)", strerror(Ret));
     97  }
    9898  if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret));
    9999
     
    266266          if (Match(Parameter[n+1], "info")) {
    267267                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                 }
     268                if (!Crates[Crate]->Present[Channel]) PrintMessage("(channel not present in crate)");
    271269                PrintMessage("\n  Channel is on board %d, board channel %d\n", Channel/32, Channel%32);
    272270
     
    280278                PrintMessage("\n  Voltage setpoint: %.2f V (DAC %u)    Current: %.2f uA ", Crates[Crate]->GetVoltage(Channel), Crates[Crate]->GetDAC(Channel), Crates[Crate]->GetCurrent(Channel));
    281279
    282                 if (Crates[Crate]->OC[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]) PrintMessage("(overcurrent)\n");
     280                if (Crates[Crate]->OC[Channel]) PrintMessage("(overcurrent)\n");
    283281                else PrintMessage("\n");
    284282
     
    327325
    328326  char Buffer[MAX_COM_SIZE];
    329   int Errors = 0, Channel;
     327  int Errors = 0;
     328  unsigned int Channel;
    330329  double Value;
    331330  FILE *File;
     
    368367  if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n", Parameter[1].c_str());
    369368}
    370            
    371 //
    372 // Set refresh rate
    373 //
    374 void User::cmd_rate() {
    375 
    376   double Rate;
    377 
    378   if (!ConvertToDouble(Parameter[1], &Rate)) {
    379      PrintMessage("Error: Wrong number format\n");
    380      return;   
    381   }
    382 
    383   // Check limits
    384   if (Rate<MIN_RATE || Rate>MAX_RATE) {
    385     PrintMessage("Refresh rate out of range (min: %.2f Hz, max: %.2f Hz)\n", MIN_RATE, MAX_RATE);
    386     return;
    387   }
    388 
    389   fStatusRefreshRate = Rate;
    390   PrintMessage("Refresh rate set to %.2f Hz\n", fStatusRefreshRate);
    391 }
    392  
     369             
    393370//
    394371// Reset crates
     
    396373void User::cmd_reset() {
    397374
    398   if (Crates[ActiveCrate]->SystemReset() == 1) PrintMessage("System reset of crate %d\n", ActiveCrate);
     375  if (Crates[ActiveCrate]->SystemReset()) PrintMessage("System reset of crate %d\n", ActiveCrate);
    399376  else PrintMessage("Error: Could not reset crate %d\n", ActiveCrate);
    400377}
     
    412389  }
    413390 
    414   if (Crates[ActiveCrate]->GlobalSet(Voltage) != 1) {
     391  if (!Crates[ActiveCrate]->GlobalSet(Voltage)) {
    415392        PrintMessage("Error: Could not global set crate %d\n", ActiveCrate);
    416393  } 
     
    435412    fprintf(File, "%s\n\n", Crates[i]->Name);
    436413
    437     for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j));
     414    for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j));
    438415    fprintf(File, "\n");
    439416  }
     
    463440void User::cmd_status() {
    464441
    465   PrintMessage(" Number of crates:  %d\n", Crates.size());
    466   PrintMessage(" Active crate:      %d\n", ActiveCrate); 
    467   PrintMessage(" Refresh rate:      %.2f Hz\n", fStatusRefreshRate);
    468   PrintMessage(" Time out:          %.2f s\n\n", fTimeOut);
    469   PrintMessage(" MaxDiff :          %u\n", fMaxDiff);
    470 
     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 
    471450  for (unsigned int i=0; i<Crates.size(); i++) {
    472     PrintMessage(" CRATE %d (%s)\n   Wrap counter: %s (%d)  Reset: %s  Error count: %d\n ",
     451
     452    PrintMessage(" CRATE %d (%s)\n   Wrap counter: %s (%d)  Reset: %s  Error count: %d %s\n ",
    473453                i, Crates[i]->Name,     Crates[i]->WrapOK ? "ok":"error", Crates[i]->WrapCount,
    474                 Crates[i]->ResetHit ? "yes" : "no", Crates[i]->ErrorCount);
     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        }
    475461
    476462        if (Parameter.size() == 1) PrintMessage("Channel voltages (in V)");
     
    478464        else PrintMessage("Channel currents (in uA)");
    479465
    480     for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
     466    for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    481467          if (j%12 == 0) PrintMessage("\n%3.1d:  ", j);
    482           if (!Crates[i]->Present[j/NUM_CHANNELS][j%NUM_CHANNELS]) PrintMessage("  -   ");
     468          if (!Crates[i]->Present[j]) PrintMessage("  -   ");
    483469      else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->GetVoltage(j));
    484470          else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->GetDAC(j));
    485           else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":"");
     471          else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j] ? "OC":"");
    486472    }
    487473        PrintMessage("\n");
     
    489475}
    490476
    491 //
    492 // Set timeout to return from read
    493 //
    494 void User::cmd_timeout() {
    495 
    496   double Timeout;
    497 
    498   if (!ConvertToDouble(Parameter[1], &Timeout)) {
    499      PrintMessage("Error: Wrong number format\n");
    500      return;   
    501   }
    502 
    503   fTimeOut = Timeout;
    504   PrintMessage("Timeout set to %.2f s\n", fTimeOut);
    505 }
    506    
    507477//
    508478// Exit program (Signal makes readline return and sets ExitRequest)
     
    535505  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
    536506  va_end(ArgumentPointer);
     507
     508  if (strlen(Text) == 0) return;
    537509 
    538510  // Print to console
    539   printf("%s", Text); // New prompt
     511  printf("%s", Text);
    540512  fflush(stdout);
    541   if (strlen(Text)>0 && Text[strlen(Text)-1]=='\n') rl_on_new_line(); // New prompt
     513  if (Text[strlen(Text)-1] == '\n') rl_on_new_line(); // New prompt
    542514
    543515  // Send to DIM text service
     
    550522
    551523
    552 // Ramp to new voltage with maximum step size given in fMaxDiff
     524// Ramp to new voltage with given maximum step
    553525// No ramping when decreasing voltage
    554526unsigned int User::RampVoltages(int Crate, map<unsigned int, double> Voltages) {
     
    556528  map<unsigned int, double> Target;
    557529  int Errors = 0;
     530  double MaxDiff = atof(GetConfig("RampSpeed").c_str());
    558531
    559532  // Ramp until all channels at desired value
     
    567540        Target = Voltages;
    568541        for (map<unsigned int, double>::iterator it = Target.begin(); it != Target.end(); ++it) {
    569           if (Crates[Crate]->GetVoltage(it->first) + fMaxDiff < it->second) {
    570                 it->second = Crates[Crate]->GetVoltage(it->first) + fMaxDiff;
     542          if (Crates[Crate]->GetVoltage(it->first) + MaxDiff < it->second) {
     543                it->second = Crates[Crate]->GetVoltage(it->first) + MaxDiff;
    571544          }
    572545        }       
    573546       
    574547        // Set channels to next target and wait 10 ms
    575         if (Crates[Crate]->SetChannels(Target) != 1) Errors++;
     548        if (!Crates[Crate]->SetChannels(Target)) Errors++;
    576549        usleep(10000);
    577550  }
     
    586559void User::Monitor() {
    587560
    588   static bool Warned = false;
    589561  int Ret;
    590   unsigned int Count=0;
    591562
    592563  while (!ExitRequest) {
     
    596567          Message(FATAL, "pthread_setcancelstate() failed (%s)", strerror(Ret));
    597568        }
    598         if (usleep((unsigned long) floor(1000000./fStatusRefreshRate)) == -1) {
    599           Message(FATAL, "usleep() failed (%s)", strerror(errno));
    600         }
     569        sleep(min(atoi(GetConfig("UpdatePeriod").c_str()), 1));
    601570        if ((Ret=pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL)) != 0) {
    602571          Message(FATAL, "pthread_setcancelstate() failed (%s)", strerror(Ret));
     
    605574        // Check all crates
    606575        for (unsigned int i=0; i<Crates.size(); i++) {
    607       if (Crates[i]->ErrorCount > MAX_ERR_COUNT) {
    608         if (!Warned) {
    609           Warned = true;
    610           Message(WARN, "Crate %d has many read/write errors, further error reporting disabled", i);
    611         }
    612         continue;
     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;
    613583      }
    614584
     585          // Check if crate push button was hit
    615586      if (Crates[i]->ResetHit) {
    616587        Message(INFO, "Manual reset of crate %d, setting voltages to zero and issuing system reset", i);
    617                 Crates[i]->GlobalSet(0);
    618                 Crates[i]->SystemReset();
     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);
    619590      }
    620591
    621       if (!Crates[i]->WrapOK) {
    622         Message(ERROR, "Wrap counter mismatch of crate %d", i);
    623       }
    624 
    625       if (Crates[i]->ReadAll() != 1) {
    626         Message(ERROR, "Monitor could not read status from crate %d", i);
    627                 continue;
    628       }
    629 
     592          // Check for overcurrent and set voltage to zero if occurred
    630593          map<unsigned int, double> Voltages;
    631594         
    632       for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    633         if (Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS]) {
    634                   if (Count++ < 5) 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(ERROR, "Five overcurrent warnings, no more!");
     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);
    636598                  Voltages[j] = 0;
    637599        }
    638600      }
    639           if (!Voltages.empty()) {
    640                 Crates[i]->SetChannels(Voltages);
    641                 Crates[i]->SystemReset();
    642           }
     601          if (!Crates[i]->SetChannels(Voltages)) Message(ERROR, "Error when setting voltages of crate %d", i);
    643602         
    644603          if (Mode == mode_dynamic) Crates[i]->AdaptVoltages();
Note: See TracChangeset for help on using the changeset viewer.