Changeset 11906


Ignore:
Timestamp:
08/15/11 17:01:20 (13 years ago)
Author:
ogrimm
Message:
Added voltage and system reset rate limit
Location:
fact/BIASctrl
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/BIASctrl.cc

    r11205 r11906  
    1414#include <readline/history.h>
    1515
    16 const char READLINE_HIST_FILE[] = "/tmp/.history.BIASctrl";
     16using namespace std;
     17
     18const string READLINE_HIST_FILE = string(getenv("HOME"))+"/.history_BIASctrl";
    1719
    1820// Main program
     
    2426  // Uses getc() for readline library (allows interruption by signal) and load history buffer
    2527  rl_getc_function = getc;
    26   read_history(READLINE_HIST_FILE);
     28  read_history(READLINE_HIST_FILE.c_str());
    2729
    2830  // Set signal SIGTERM to interrupt blocking system calls
     
    3840  // Handle command-line input
    3941  while (!M.ExitRequest) {       
    40     Command = readline("\rBias> ");
     42    Command = readline("Bias> ");
    4143       
    4244        // NULL returned if interrupted by signal
     
    5557 
    5658  // Save history buffer 
    57   int Ret = write_history(READLINE_HIST_FILE);
    58   if (Ret != 0 ) printf("Error writing history file to '%s' (%s)\n", READLINE_HIST_FILE, strerror(Ret));
     59  int Ret = write_history(READLINE_HIST_FILE.c_str());
     60  if (Ret != 0 ) printf("Error writing history file to '%s' (%s)\n", READLINE_HIST_FILE.c_str(), strerror(Ret));
    5961}
  • fact/BIASctrl/Crate.cc

    r11773 r11906  
    2020  // Initialize
    2121  InitOK = false;
     22  Disabled = false;
    2223  File = NULL;
    2324  m = PIO;
     
    2627  CrateNumber = Number;
    2728  WrapCount = -1;
    28 
    29   for (int i=0; i<MAX_NUM_BOARDS; i++) {
    30         for (int j=0; j<NUM_CHANNELS; j++) {
    31           OC[i][j] = false;
    32           Present[i][j] = false;
    33           Current[i][j] = 0;
    34         }
     29  LastReset = 0;
     30
     31  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     32        OC[i] = false;
     33        Present[i] = false;
     34        Current[i] = 0;
    3535  }
    3636  ResetHit = false;
     
    4545  NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name);
    4646  BiasVolt = new DimService ((char *) (SERVER_NAME"/VOLT/ID"+ID.str()).c_str(), (char *) "D", Volt, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(double));
    47   BiasDAC = new DimService ((char *) (SERVER_NAME"/DAC/ID"+ID.str()).c_str(), (char *) "I", DAC, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(int));
    4847  BiasCurrent = new DimService ((char *) (SERVER_NAME"/MICROAMP/ID"+ID.str()).c_str(), (char *) "F", Current, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(float));
    4948
     
    5251  // Open device
    5352  if ((fDescriptor = open(("/dev/"+CrateName).c_str(), O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
    54     if(errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", CrateNumber, Name, strerror(errno));
     53    if (errno != 2) m->PrintMessage("Error: Could not open device %d/%s (%s)\n", CrateNumber, Name, strerror(errno));
    5554    return;
    5655  }
     
    6968
    7069  // Set baudrate and raw mode
    71   if (cfsetspeed(&tio, BAUDRATE) == -1) {
     70  if (cfsetspeed(&tio, B115200) == -1) {
    7271        m->PrintMessage("Error: Could not set baud rate of device %s (%s)\n", Name,  strerror(errno));
    7372        return;
     
    7978  }
    8079 
     80  // Synchronize crate
     81  if (!Synch()) return;
     82
     83  // Set voltages and zero and reset crate
     84  if (!GlobalSet(0) || !SystemReset()) return;
     85
    8186  InitOK = true;
    8287}
     
    8893
    8994  if(fDescriptor != -1) {
    90     GlobalSet(0);
    91 
    92     SystemReset();
     95    if (!GlobalSet(0)) m->Message(m->ERROR, "Could not global set crate %d to zero voltage", Name);
     96
    9397    if (File == NULL) {
    9498          if (close(fDescriptor) == -1) m->PrintMessage("Error closing device %s (%s)\n", Name, strerror(errno));
     
    99103  delete NameService;
    100104  delete BiasVolt;
    101   delete BiasDAC;
    102105  delete BiasCurrent;
    103106  delete[] Name;
     
    105108
    106109
    107 // Communicate: Write and read from HV Board until time-out has been reached
    108 //
    109 // Returns: 0 error, 1 success, -1 time-out exceeded
     110//
     111// Communicate with crate (return empty vector in case of time-out or not a multiple of 3 bytes was returned)
     112//
    110113vector<unsigned char> Crate::Communicate(string Buf) {
    111114
    112115  int N;
    113116  fd_set SelectDescriptor;
    114   struct timeval WaitTime = {(long) m->fTimeOut, (long) ((m->fTimeOut-(long) m->fTimeOut)*1e6)};
     117  float TimeOut = atof(m->GetConfig("TimeOut").c_str());
     118  struct timeval WaitTime = {(long) TimeOut, (long) ((TimeOut-(long) TimeOut)*1e6)};
    115119  char Buffer[10000];
    116120  vector<unsigned char> Data;
     121
     122  // Crate disabled because of too many errors?
     123  if (Disabled) return Data;
    117124 
    118125  // === Lock device ===
    119126  flockfile(File);
    120127
    121   // Do not try to communicate if crate has too many errors
    122   if (ErrorCount > MAX_ERR_COUNT) goto ExitCommunicate;
    123 
    124128  // === Write data ===
    125129  if ((N = write(fDescriptor, Buf.data(), Buf.size())) < (int) Buf.size()) {
    126     if (N == -1) m->Message(m->ERROR, "Could not write data to crate (%s)", strerror(errno));
    127     else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Buf.size());
     130    if (N == -1) m->Message(m->ERROR, "Could not write data to crate %s (%s)", Name, strerror(errno));
     131    else m->Message(m->ERROR, "Could write only %d of %d bytes to crate %s", N, Buf.size(), Name);
    128132    ErrorCount++;
    129        
     133        goto ExitCommunicate;
    130134  }
    131135
     
    145149        // Read data   
    146150        if ((N = read(fDescriptor, Buffer, sizeof(Buffer))) == -1) {
    147       m->Message(m->ERROR, "Read error (%s)", strerror(errno));
     151      m->Message(m->ERROR, "Read error from crate %s (%s)", Name, strerror(errno));
    148152      ErrorCount++;
    149153          goto ExitCommunicate;
     
    160164  }
    161165
    162   // === Check/update all wrap counter === 
     166  // === Check/update wrap counter in all received data packages of three bytes === 
    163167  for (unsigned int i=0; i<Data.size(); i+=3) {
    164168        if (WrapCount != -1) {
     
    168172        WrapCount = (Data[i]>>4) & 7;
    169173  }
     174
     175 // Check wrap counter
     176 if (!WrapOK) {
     177        m->Message(m->WARN, "Wrap counter mismatch of crate %s", Name);
     178        ErrorCount++;
     179 }
    170180 
    171181  // === UnLock file descriptor ===
     
    173183  funlockfile(File);
    174184
    175   if (Data.empty()) Data.push_back(0);
     185  if (ErrorCount > MAX_ERR_COUNT) Disabled = true;
    176186
    177187  return Data;
     
    181191// System reset of bias crate
    182192//
    183 int Crate::SystemReset() {
    184  
    185   vector<unsigned char> Data = Communicate(string(3, 0));
    186 
    187   if (Data.size() == 3) {
    188         ResetHit = false;
    189     ErrorCount = 0;
    190         return 1;
    191   }
    192   return 0;
     193bool Crate::SystemReset() {
     194
     195  // Check if minimum requested period elapsed since last reset 
     196  if (time(NULL) - LastReset < max(atoi(m->GetConfig("MinResetPeriod").c_str()),1)) return false;
     197  LastReset = time(NULL);
     198
     199  // Send reset and check if 3 bytes returned 
     200  if (Communicate(string(3, 0)).size() != 3) return false;
     201
     202  ResetHit = false;
     203  Disabled = false;
     204  ErrorCount = 0;
     205  return true;
    193206}
    194207
     
    196209// Read all channels status
    197210//
    198 int Crate::ReadAll() {
     211bool Crate::ReadAll() {
    199212
    200213  string Buf;
    201214
    202215  // Prepare command to read all channels
    203   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
     216  for (unsigned int i=0; i<MAX_NUM_BOARDS; i++) for (int unsigned j=0; j<NUM_CHANNELS; j++) {
    204217        Buf.push_back(1<<5 | i<<1 | (j&16)>>4);
    205218        Buf.push_back(j<<4);
     
    210223  vector<unsigned char> Data = Communicate(Buf);
    211224   
    212   if (Data.size() != Buf.size()) return 0;
     225  if (Data.size() != Buf.size()) return false;
    213226
    214227  // Evaluate data returned from crate
    215228  int Count = 0;
    216   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    217         Current[i][j] = (Data[Count+1] + (Data[Count] & 0x0f)*256) * 1.22;
    218         OC[i][j] = Data[Count] & 128;
    219         Present[i][j] = (Data[Count+2] & 0x70) == 0 ? true : false;
     229  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     230        Current[i] = (Data[Count+1] + (Data[Count] & 0x0f)*256) * 1.22;
     231        OC[i] = Data[Count] & 128;
     232        Present[i] = (Data[Count+2] & 0x70) == 0 ? true : false;
    220233        if (!ResetHit) ResetHit = (Data[Count+2] & 0x80) == 0 ? false : true;
    221234        Count += 3;
    222235  }
    223   return 1;
     236  return true;
    224237}
    225238
    226239
    227240// ***** Global set *****
    228 int Crate::GlobalSet(double Voltage) {
    229 
     241bool Crate::GlobalSet(double Voltage) {
     242
     243  // Limit voltage
     244  Voltage = min(Voltage, atof(m->GetConfig("VoltageLimit").c_str()));
     245
     246  // Calculate DAC value
    230247  unsigned int SetPoint = (unsigned int) (Voltage/90.0*0x0fff);
    231  
     248
    232249  // Execute command
    233250  string Buf;
     
    235252  vector<unsigned char> Data = Communicate(Buf);
    236253
    237   if (Data.size() == 3) {
    238         for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    239           DAC[i][j] = SetPoint;
    240           Volt[i][j] = Voltage;
    241           RefVolt[i][j] = Voltage;
    242         }
    243         return 1;
    244   }
    245   return 0;
     254  if (Data.size() != 3) return false;
     255 
     256  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     257        Volt[i] = Voltage;
     258        RefVolt[i] = Voltage;
     259  }
     260  return true;
    246261}
    247262
    248263
    249264// ***** Set channel voltages *****
    250 int Crate::SetChannels(map<unsigned int, double> V) {
     265bool Crate::SetChannels(map<unsigned int, double> V) {
    251266 
    252267  string Buf;
    253268
    254   if (V.empty()) return 1;
     269  if (V.empty()) return true;
    255270
    256271  // Build and execute commands
    257   for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
     272  for (map<unsigned int, double>::iterator it = V.begin(); it != V.end(); ++it) {
     273    // Limit maximum voltage
     274        it->second = min(it->second, atof(m->GetConfig("VoltageLimit").c_str()));
     275
    258276    // If DAC value unchanged, do not send command
    259         if (DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] == it->second/90.0*0x0fff) continue;
     277        if (GetDAC(it->first) == it->second/90.0*0x0fff) continue;
    260278
    261279        // Add command to buffer
     
    267285
    268286  // Store new voltage values of successful
    269   if (Data.size() == Buf.size()) {
    270         for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
    271           DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = (unsigned int) (it->second/90.0*0x0fff);
    272           Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
    273           RefVolt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
    274         }
    275         return 1;
    276   }
    277   return 0; 
     287  if (Data.size() != Buf.size()) return false;
     288 
     289  for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
     290        Volt[it->first] = it->second;
     291        RefVolt[it->first] = it->second;
     292  }
     293
     294  return true;
    278295}
    279296
     
    296313void Crate::ClearVoltageArrays() {
    297314
    298   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    299         DAC[i][j] = 0;
    300         Volt[i][j] = 0; 
    301         RefVolt[i][j] = 0; 
     315  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     316        Volt[i] = 0; 
     317        RefVolt[i] = 0; 
    302318  }
    303319
     
    310326
    311327  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
    312   else return Volt[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS];
     328  else return Volt[Channel];
    313329}
    314330
     
    318334
    319335  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
    320   else return DAC[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS];
     336  else return (unsigned int) (Volt[Channel]/90.0*0x0fff);
    321337}
    322338
     
    326342
    327343  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
    328   else return Current[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS];
     344  else return Current[Channel];
    329345}
    330346
     
    334350
    335351  BiasVolt->updateService();
    336   BiasDAC->updateService();
    337352}
    338353
     
    341356void Crate::SetRefCurrent() {
    342357
    343   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    344         RefCurrent[i][j] = Current[i][j]; 
    345   }
     358  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) RefCurrent[i] = Current[i]; 
    346359}
    347360
     
    354367  map<unsigned int, double> Voltages;
    355368
    356   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    357     if (RefVolt[i][j] == 0) continue;
    358         Voltages[i*NUM_CHANNELS+j] = RefVolt[i][j] + (RefCurrent[i][j]-Current[i][j])*RESISTOR/1e6; 
     369  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     370    if (RefVolt[i] == 0) continue;
     371        Voltages[i] = RefVolt[i] + (RefCurrent[i]-Current[i])*RESISTOR/1e6; 
    359372  } 
    360373  SetChannels(Voltages);
  • fact/BIASctrl/Crate.h

    r11361 r11906  
    1414#include "dis.hxx"
    1515
    16 #define MAX_NUM_BOARDS 13       // Maximum number of boards per crate
    17 #define NUM_CHANNELS 32         // Channels per bias board
    18 #define BAUDRATE B115200
    19 const float RESISTOR = 1000;    // Resistance in Ohm for voltage correction
     16const unsigned int MAX_NUM_BOARDS = 13; // Maximum number of boards per crate
     17const unsigned int NUM_CHANNELS = 32;   // Channels per bias board
     18const float RESISTOR = 1000;                    // Resistance in Ohm for voltage correction
    2019const int MAX_ERR_COUNT = 10;   // Maximum number of errors before reporting stopped
    2120class User;
     
    2928        DimService *NameService;
    3029        DimService *BiasVolt;
    31         DimService *BiasDAC;
    3230        DimService *BiasCurrent;
    3331
     32        double Volt[MAX_NUM_BOARDS*NUM_CHANNELS];       // Voltage
     33        float Current[MAX_NUM_BOARDS*NUM_CHANNELS];
     34        time_t LastReset;
    3435
    35         int DAC[MAX_NUM_BOARDS][NUM_CHANNELS];          // Voltage in DAC units
    36         double Volt[MAX_NUM_BOARDS][NUM_CHANNELS];      // Voltage in Volt
    37         float Current[MAX_NUM_BOARDS][NUM_CHANNELS];
    3836        std::vector<unsigned char> Communicate(std::string);
    3937        void ClearVoltageArrays();
     
    4543    char *Name;
    4644
    47         bool OC[MAX_NUM_BOARDS][NUM_CHANNELS];
    48         bool Present[MAX_NUM_BOARDS][NUM_CHANNELS];
     45        bool OC[MAX_NUM_BOARDS*NUM_CHANNELS];
     46        bool Present[MAX_NUM_BOARDS*NUM_CHANNELS];
    4947        bool ResetHit;
    5048        bool WrapOK;
    5149        int WrapCount;
    5250        int ErrorCount;
     51        bool Disabled;
    5352
    54         float RefCurrent[MAX_NUM_BOARDS][NUM_CHANNELS];
    55         double RefVolt[MAX_NUM_BOARDS][NUM_CHANNELS];
     53        float RefCurrent[MAX_NUM_BOARDS*NUM_CHANNELS];
     54        double RefVolt[MAX_NUM_BOARDS*NUM_CHANNELS];
    5655
    5756        bool InitOK;
    5857
    59         int SetChannels(std::map<unsigned int, double>);
    60         int ReadAll();
    61         int SystemReset();
    62         int GlobalSet(double);
     58        bool SetChannels(std::map<unsigned int, double>);
     59        bool ReadAll();
     60        bool SystemReset();
     61        bool GlobalSet(double);
    6362        bool Synch();
    6463        double GetVoltage(unsigned int);
  • fact/BIASctrl/History.txt

    r11781 r11906  
    16164/8/2011        'pixel' and 'channel' commands accept 'info' parameter.
    17175/8/2011        Default voltages now given per bias channel, not per pixel
     1815/8/2011       Added global voltage limit and minimum time between system resets.
  • 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();
  • fact/BIASctrl/User.h

    r11772 r11906  
    1818
    1919#define MAX_COM_SIZE 5000
    20 
    21 #define MIN_RATE 0.01
    22 #define MAX_RATE 50.0
    2320
    2421class User: public EvidenceServer {
     
    5047
    5148 public:
    52         double fTimeOut;
    53         float fStatusRefreshRate;
    54         double fMaxDiff;
    5549        unsigned int ActiveCrate;
    5650
     
    6660        void cmd_status();      void cmd_gs();
    6761        void cmd_load();        void cmd_save();
    68         void cmd_exit();        void cmd_rate();
    69         void cmd_timeout();     void cmd_reset();
     62        void cmd_exit();        void cmd_reset();
    7063        void cmd_help();        void cmd_mode();
    7164        void cmd_crate();       void cmd_shell();
Note: See TracChangeset for help on using the changeset viewer.