Ignore:
Timestamp:
08/04/11 12:44:02 (13 years ago)
Author:
ogrimm
Message:
Added 'info' option for 'pixel' and 'channel' commands
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/User.cc

    r11362 r11772  
    1212                                                                void (User::*CommandPointer)();
    1313                                                                unsigned int MinNumParameter;
     14                                                                bool NeedCrate;
    1415                                                                const char *Parameters;
    1516                                                                const char *Help;
    1617  } 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"}};   
    3133
    3234//
     
    4244
    4345  // 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");
    4647  fTimeOut = atof(GetConfig("TimeOut").c_str());
    4748  fStatusRefreshRate = atof(GetConfig("StatusRefreshRate").c_str());
     
    7071    }
    7172  }
    72 
    73   // Set active crate
    74   if (!Boards.empty()) ActiveCrate = 0;
    75   else ActiveCrate = -1;
     73  ActiveCrate = 0;
    7674
    7775  // Create PixelMap instance (map from config server)
     
    9492User::~User() {
    9593
     94  int Ret;
     95 
    9696  // 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));
    9999
    100100  // Delete all crates
     
    118118  if (getCommand() != DIMCommand || Command.size() < 2) return;
    119119
    120   // Shell command
    121   if(Command[0]=='.') {
    122     if (system(Command.c_str()+1) == 1) {
    123           PrintMessage("Error with system() call\n");
    124         }
    125     return;
    126   }
    127 
    128120  // Parse command into tokens
    129121  Parameter = Tokenize(Command, " ");
    130122
     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 
    131130  // Search for command in command list
    132131  for(unsigned int CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++) {
    133132    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) {
    135141                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");
    136148                return;
    137149          }
     
    149161void User::cmd_help() {
    150162
    151   char Buffer[MAX_COM_SIZE];
    152163  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"
    158169        "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");
    160171}
    161172
     
    164175//
    165176void User::cmd_synch() {
    166 
    167   if (ActiveCrate == -1) return; 
    168177
    169178  if (Crates[ActiveCrate]->Synch()) PrintMessage("Synchronized crate %d\n", ActiveCrate);
     
    199208  unsigned int Errors=0;
    200209  double Double;
    201   struct Range Crt, Chan;
    202   unsigned int PixelID = 0;
     210  struct Range Chan, Pixel;
     211  unsigned int Crate, Channel;
    203212  vector< map<unsigned int, double> > Voltages (Crates.size());
     213  vector < pair <unsigned int, unsigned int> > P;
    204214
    205215  // Loop over all parameters
    206216  for (unsigned int n=1; n < Parameter.size()-1; n+=2) {
    207217
     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
    208227        // Pixel identification?
    209228        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          }
    212236         
    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          }
    221246        }
    222247        // Channel identification
    223248        else {
    224           if (ActiveCrate == -1) continue;
    225           else  Crt.Min = Crt.Max = ActiveCrate;
    226 
    227249          Chan.Min = 0;
    228250          Chan.Max = MAX_NUM_BOARDS*NUM_CHANNELS-1;       
     
    232254                continue;
    233255          }
    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;
    246290 
    247291          // 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       
    250296          // Should the default value be set?
    251297          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;
    263301          }
    264302
    265303          // 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;
    268306        } // Channels
    269307  } // Loop over command argument
     
    305343    for (unsigned int Crate=0; Crate<Crates.size(); Crate++) if (Match(Crates[Crate]->Name, Buffer)) {
    306344
    307           if ((int) Crate != ActiveCrate) continue;
     345          if (Crate != ActiveCrate) continue;
    308346          PrintMessage("Found bias settings for crate %s (#%d)\n\r", Crates[Crate]->Name, Crate);
    309347
     
    359397void User::cmd_reset() {
    360398
    361   if (ActiveCrate == -1) return; 
    362  
    363399  if (Crates[ActiveCrate]->SystemReset() == 1) PrintMessage("System reset of crate %d\n", ActiveCrate);
    364400  else PrintMessage("Error: Could not reset crate %d\n", ActiveCrate);
    365 
    366401}
    367402
     
    372407
    373408  double Voltage;
    374 
    375   if (ActiveCrate == -1) return; 
    376409
    377410  if (!ConvertToDouble(Parameter[1], &Voltage)) {
     
    432465
    433466  PrintMessage(" Number of crates:  %d\n", Crates.size());
    434   PrintMessage(" Active crate:     %d\n", ActiveCrate); 
     467  PrintMessage(" Active crate:      %d\n", ActiveCrate); 
    435468  PrintMessage(" Refresh rate:      %.2f Hz\n", fStatusRefreshRate);
    436469  PrintMessage(" Time out:          %.2f s\n\n", fTimeOut);
     
    480513  pthread_kill(MainThread, SIGTERM);
    481514}
    482  
     515
     516//
     517// Execute shell command
     518//
     519void User::cmd_shell() {
     520
     521  if (system(Parameter[1].c_str()) == -1) PrintMessage("Error with system() call\n");
     522}
     523
    483524
    484525//
     
    521562    // Remove channels already at target (check for DAC, not for floating-point voltage)
    522563        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);
    524564          if (fabs(Crates[Crate]->GetVoltage(it->first)-it->second) < 0.001) Voltages.erase(it);
    525565        }
     
    549589  static bool Warned = false;
    550590  int Ret;
     591  unsigned int Count=0;
    551592
    552593  while (!ExitRequest) {
     
    592633      for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    593634        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!");
    595637                  Voltages[j] = 0;
    596638        }
Note: See TracChangeset for help on using the changeset viewer.