Changeset 11915 for fact/BIASctrl


Ignore:
Timestamp:
08/26/11 09:47:05 (13 years ago)
Author:
ogrimm
Message:
Ramping also for decreasing voltage
Location:
fact/BIASctrl
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/BIASctrl.cc

    r11906 r11915  
    1919
    2020// Main program
    21 int main() {
     21int main(int argc, char *argv[]) {
    2222
    2323  char *Command;
     
    3636   
    3737  // Construct main instance
    38   static User M;
     38  static User M(argc == 2 ? argv[1] : string());
    3939 
    4040  // Handle command-line input
  • fact/BIASctrl/Crate.cc

    r11906 r11915  
    2525  Name = new char [CrateName.size()+1];
    2626  strcpy(Name, CrateName.c_str());
    27   CrateNumber = Number;
    2827  WrapCount = -1;
    2928  LastReset = 0;
     
    4140  // Create DIM services
    4241  stringstream ID;
    43   ID << setfill('0') << setw(2) << CrateNumber;
     42  ID << setfill('0') << setw(2) << Number;
    4443
    4544  NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name);
     
    5150  // Open device
    5251  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));
    5453    return;
    5554  }
     
    5756  // Generate FILE pointer
    5857  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));
    6059    return;
    6160  }
     
    9392
    9493  if(fDescriptor != -1) {
    95     if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate %d to zero voltage", Name);
     94    if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate %s to zero voltage", Name);
    9695
    9796    if (File == NULL) {
     
    231230        OC[i] = Data[Count] & 128;
    232231        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;
    234233        Count += 3;
    235234  }
     
    243242  // Limit voltage
    244243  Voltage = min(Voltage, atof(m->GetConfig("VoltageLimit").c_str()));
     244  Voltage = max(Voltage, 0.0);
    245245
    246246  // Calculate DAC value
     
    271271  // Build and execute commands
    272272  for (map<unsigned int, double>::iterator it = V.begin(); it != V.end(); ++it) {
    273     // Limit maximum voltage
     273    // Limit voltage
    274274        it->second = min(it->second, atof(m->GetConfig("VoltageLimit").c_str()));
     275        it->second = max(it->second, 0.0);
    275276
    276277    // If DAC value unchanged, do not send command
  • fact/BIASctrl/Crate.h

    r11906 r11915  
    1616const unsigned int MAX_NUM_BOARDS = 13; // Maximum number of boards per crate
    1717const unsigned int NUM_CHANNELS = 32;   // Channels per bias board
    18 const float RESISTOR = 1000;                    // Resistance in Ohm for voltage correction
     18const float RESISTOR = 2000;                    // Resistance in Ohm for voltage correction
    1919const int MAX_ERR_COUNT = 10;   // Maximum number of errors before reporting stopped
    2020class User;
     
    2323 
    2424    class User *m;
    25         int CrateNumber;
    2625        int fDescriptor;
    2726        FILE *File;
  • fact/BIASctrl/History.txt

    r11906 r11915  
    17175/8/2011        Default voltages now given per bias channel, not per pixel
    181815/8/2011       Added global voltage limit and minimum time between system resets.
     1924/8/2011       Ramping also for decreasing voltages.
     2026/8/2011       Removed support for multiple crates. Crate name can be given as
     21                        command line argument.
  • fact/BIASctrl/User.cc

    r11906 r11915  
    1616                                                                const char *Help;
    1717  } 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"},
    2020    {"gs", &User::cmd_gs, 1, true, "[crate] <volt>", "Global voltage set active crate"},
    2121        {"reset", &User::cmd_reset, 0, true, "", "Reset active crate"},
    2222        {"synch", &User::cmd_synch, 0, true, "", "Synchronize active crate"},
    23         {"crate", &User::cmd_crate, 1, true, "<number>", "Select active crate"},
    2423        {"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)"},
    2625        {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"},
    2726        {"save", &User::cmd_save, 1, true, "<file>", "Save current bias settings to file"},
     
    3332// Constructor
    3433//
    35 User::User(): EvidenceServer(SERVER_NAME) {
     34User::User(string Board): EvidenceServer(SERVER_NAME) {
    3635
    3736  MainThread = pthread_self();
     
    4241
    4342  // Get/initialize configuration data
    44   vector<string> Boards = Tokenize(GetConfig("Boards", "dummy"), " \t");
     43  if (Board.empty()) Board = GetConfig("Boards", "dummy");
    4544  GetConfig("TimeOut");
    4645  GetConfig("VoltageLimit");
     
    4847  GetConfig("RampSpeed");
    4948  GetConfig("UpdatePeriod");
    50 
    5149  vector<string> Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t");
    5250 
     
    5553  }
    5654
    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  }
    7264
    7365  // Create PixelMap instance (map from config server)
     
    9890  if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed (%s)", strerror(Ret));
    9991
    100   // Delete all crates
    101   for (unsigned int i=0; i<Crates.size(); i++) delete Crates[i];
     92  // Delete crate
     93  delete Dev;
    10294
    10395  delete DIMCommand;   
     
    143135          }
    144136
    145           // Check if crates needed
    146           if (CommandList[CmdNumber].NeedCrate && Crates.empty()) {
     137          // Check if crate needed
     138          if (CommandList[CmdNumber].NeedCrate && Dev==NULL) {
    147139                PrintMessage("No crate available\n");
    148140                return;
     
    172164
    173165//
    174 // Synchronize boards
     166// Synchronize crate
    175167//
    176168void User::cmd_synch() {
    177169
    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");
    201172}
    202173
     
    206177void User::cmd_hv() {
    207178
    208   unsigned int Errors=0;
     179  unsigned int Channel, Errors = 0;
    209180  double Double;
    210181  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;
    214184
    215185  // Loop over all parameters
     
    223193
    224194        // Extract affected channels for this argument pair
    225         P.clear();
     195        Channels.clear();
    226196
    227197        // Pixel identification?
     
    236206         
    237207          for (int i=Pixel.Min; i<=Pixel.Max; i++) {
    238             Crate = PixMap->Pixel_to_HVcrate(i);
    239208                Channel = PixMap->Pixel_to_HVboard(i)*NUM_CHANNELS + PixMap->Pixel_to_HVchannel(i);
    240209               
    241210                // 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);
    244213                }
    245214          }
     
    255224          }
    256225         
    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);   
    258227        }
    259228 
    260229        // 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];
    264232
    265233          // Should only information be printed?
    266234          if (Match(Parameter[n+1], "info")) {
    267                 PrintMessage("Crate %2d, channel %3d  ", Crate, Channel);
    268                 if (!Crates[Crate]->Present[Channel]) PrintMessage("(channel not present in crate)");
    269                 PrintMessage("\n  Channel is 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);
    270238
    271239                // 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);
    273241                PrintMessage("\n  Default voltage: %.2f    Pixel IDs: ", Channel < DefaultVoltage.size() ? DefaultVoltage[Channel] : 0);
    274242                for (unsigned int j=0; j<List.size(); j++) PrintMessage("%u ", List[j]);
     
    276244
    277245                // 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");
    281249                else PrintMessage("\n");
    282250
     
    284252          }
    285253
    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;
    293259       
    294260          // Should the default value be set?
     
    297263                else Double = 0;
    298264          }
    299 
     265         
    300266          // Relative or absolute change?
    301           if (isdigit(Parameter[n+1][0]) == 0) Voltages[Crate][Channel] = Crates[Crate]->GetVoltage(Channel) + Double;
    302           else Voltages[Crate][Channel] = Double;
     267          if (Parameter[n+1][0]=='+' || Parameter[n+1][0]=='-') Voltages[Channel] += Double;
     268          else Voltages[Channel] = Double;
    303269        } // Channels
    304270  } // Loop over command argument
    305271
    306272  // 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();
    311275
    312276  // Error message only if not yet too many errors
    313277  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;
    317279    Message(ERROR, "%d errors occurred from SetChannels()", Errors);
    318280  }
     
    338300
    339301  // 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()
    365323           
    366324  if (Errors != 0) PrintMessage("Warning: %d error(s) occurred\n", Errors);
     
    369327             
    370328//
    371 // Reset crates
     329// Reset crate
    372330//
    373331void User::cmd_reset() {
    374332
    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");
    377335}
    378336
     
    389347  }
    390348 
    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");
    393351  } 
    394352}
     
    408366
    409367  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");
    417372
    418373  if (fclose(File) != 0) {
     
    429384  else {
    430385    Mode = mode_dynamic;
    431         for (unsigned int i=0; i<Crates.size(); i++) {
    432           Crates[i]->SetRefCurrent();
    433         }
     386        Dev->SetRefCurrent();
    434387  }
    435388}
     
    440393void User::cmd_status() {
    441394
    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");
    475430}
    476431
     
    523478
    524479// 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) {
     480unsigned int User::RampVoltages(map<unsigned int, double> Voltages) {
    527481
    528482  map<unsigned int, double> Target;
    529483  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
    533486  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);
    537497        }
    538498       
    539         // Limit voltage changes to fMaxDiff
     499        // Limit voltage changes to MaxDiff
    540500        Target = Voltages;
    541501        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;
    545507        }       
    546508       
    547509        // Set channels to next target and wait 10 ms
    548         if (!Crates[Crate]->SetChannels(Target)) Errors++;
     510        if (!Dev->SetChannels(Target)) Errors++;
    549511        usleep(10000);
    550512  }
     
    561523  int Ret;
    562524
     525  // End if no crate available
     526  if (Dev == NULL) return;
     527
    563528  while (!ExitRequest) {
    564 
    565529        // Wait (this is the only allowed cancelation point)
    566530        if ((Ret=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) != 0) {
     
    572536        }
    573537
    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();
    605564  } // while
    606565}
  • fact/BIASctrl/User.h

    r11906 r11915  
    3131        RunMode Mode;
    3232
    33         std::vector<class Crate *> Crates;
     33        class Crate *Dev;
    3434        std::vector<double> DefaultVoltage;
    3535
     
    4747
    4848 public:
    49         unsigned int ActiveCrate;
    50 
    51         User();
     49        User(std::string);
    5250        ~User();
    5351
    5452        void PrintMessage(const char *, ...);
    55         unsigned int RampVoltages(int, std::map<unsigned int, double>);
     53        unsigned int RampVoltages(std::map<unsigned int, double>);
    5654        void Monitor();
    5755        static void LaunchMonitor(User *);
     
    6260        void cmd_exit();        void cmd_reset();
    6361        void cmd_help();        void cmd_mode();
    64         void cmd_crate();       void cmd_shell();
     62        void cmd_shell();
    6563};
    6664
Note: See TracChangeset for help on using the changeset viewer.