Changeset 10059


Ignore:
Timestamp:
11/24/10 12:11:50 (14 years ago)
Author:
ogrimm
Message:
Fast ramping for many channels
Location:
fact/BIASctrl
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/Crate.cc

    r10052 r10059  
    44               
    55\********************************************************************/
     6#include <utility>
    67
    78#include "Crate.h"
     
    2930        for (int j=0; j<NUM_CHANNELS; j++) {
    3031          OC[i][j] = false;
     32          Present[i][j] = false;
    3133          Current[i][j] = 0;
    3234        }
     
    102104//
    103105// Returns: 0 error, 1 success, -1 time-out exceeded
    104 vector<char> Crate::Communicate(unsigned char* wbuf, int Bytes) {
     106vector<char> Crate::Communicate(string Buf) {
    105107
    106108  int N;
     
    114116 
    115117  // === Write data ===
    116   if ((N = write(fDescriptor, wbuf, Bytes)) < Bytes) {
     118  if ((N = write(fDescriptor, Buf.data(), Buf.size())) < (int) Buf.size()) {
    117119    if (N == -1) m->Message(m->ERROR, "Could not write data to crate (%s)", strerror(errno));
    118     else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Bytes);
     120    else m->Message(m->ERROR, "Could write only %d of %d bytes to board", N, Buf.size());
    119121    ErrorCount++;
    120122        goto ExitCommunicate;
     
    144146        // Add data to buffer
    145147        for (int i=0; i<N; i++) Data.push_back(Buffer[i]);
    146   } while(Data.size() < (unsigned int) Bytes);
     148  } while(Data.size() < Buf.size());
    147149 
    148150  // === Check if multiple of three bytes were returned ===
     
    175177int Crate::SystemReset() {
    176178 
    177   unsigned char wbuf[] = {0,0,0};
    178   vector<char> Data = Communicate(wbuf, 3);
    179  
     179  vector<char> Data = Communicate(string(3, 0));
     180
    180181  if (Data.size() == 3) {
    181     ClearVoltageArrays();
    182182    ErrorCount = 0;
    183183        return 1;
     
    187187
    188188//
    189 // Read channel status
    190 //
    191 int Crate::ReadChannel(unsigned int Board, unsigned int Channel) {
    192  
    193    // Check limits
    194   if (Board > MAX_NUM_BOARDS) {
    195     m->PrintMessage("Error: Board number out of range\n");
    196     return 0;
    197   }
    198   if (Channel > NUM_CHANNELS) {
    199     m->PrintMessage("Error: Channel number out of range\n");
    200     return 0;
    201   }
    202 
    203   // Execute command
    204   unsigned char wbuf[] = {1<<5 | Board<<1 | (Channel&16)>>4, Channel<<4, 0};
    205   vector<char> Data = Communicate(wbuf, 3);
    206 
    207   if (Data.size() == 3) {
    208         Current[Board][Channel] = Data[1] + (Data[0]&15)*256;
    209         OC[Board][Channel] = Data[0] & 128;
    210         ResetHit = Data[2] & 128;
    211         if (Board==2 && Channel==19) OC[Board][Channel] = false;
    212         return 1;
    213   }
    214   return Data[0];
    215 }
    216 
    217 
    218 //
    219189// Read all channels status
    220190//
    221191int Crate::ReadAll() {
    222192
    223   unsigned char wbuf[3*MAX_NUM_BOARDS*NUM_CHANNELS];
    224   int Count = 0;
     193  string Buf;
    225194
    226195  // Prepare command to read all channels
    227196  for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    228         wbuf[Count++] = 1<<5 | i<<1 | (j&16)>>4;
    229         wbuf[Count++] = j<<4;
    230         wbuf[Count++] = 0;
     197        Buf.push_back(1<<5 | i<<1 | (j&16)>>4);
     198        Buf.push_back(j<<4);
     199        Buf.push_back(0);
    231200  }
    232201 
    233202  // Execute command
    234   vector<char> Data = Communicate(wbuf, 3*MAX_NUM_BOARDS*NUM_CHANNELS);
     203  vector<char> Data = Communicate(Buf);
    235204   
    236   if (Data.size() != 3*MAX_NUM_BOARDS*NUM_CHANNELS) return Data[0];
    237 
    238   //Evaluate returned data
    239   Count = 0;
     205  if (Data.size() != Buf.size()) return Data[0];
     206
     207  // Evaluate data returned from crate
     208  int Count = 0;
    240209  for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    241210        Current[i][j] = Data[Count+1] + (Data[Count]&15)*256;
    242211        OC[i][j] = Data[Count] & 128;
     212        Present[i][j] = Data[Count+2] & 0x70 ? false : true;
    243213        ResetHit = Data[Count+2] & 128;
    244214        Count += 3;
     
    259229
    260230  // Execute command
    261   unsigned char wbuf[] = {1<<6 , SetPoint>>8, SetPoint};
    262   vector<char> Data = Communicate(wbuf, 3);
     231  string Buf;
     232  Buf = (((Buf + char(1<<6)) + char(SetPoint>>8)) + char(SetPoint));
     233  vector<char> Data = Communicate(Buf);
    263234
    264235  if (Data.size() == 3) {
     
    273244
    274245
    275 // ***** Channel set *****
    276 int Crate::ChannelSet(int Board, int Channel, unsigned int SetPoint) {
    277  
    278   // Check limits
    279   if (SetPoint > 0x0FFF) {
    280     m->PrintMessage("Error: Voltage DAC value above 0x0FFF\n");
    281     return 0;
    282   }
    283   if (Board > MAX_NUM_BOARDS) {
    284     m->PrintMessage("Error: Board number out of range\n");
    285     return 0;
    286   }
    287   if (Channel > NUM_CHANNELS) {
    288     m->PrintMessage("Error: Channel number out of range\n");
    289     return 0;
    290   }
    291 
    292   // Execute command
    293   unsigned char wbuf[] = {3<<5 |  Board<<1 | (Channel&16)>>4, Channel<<4 | SetPoint>>8, SetPoint};
    294   vector<char> Data = Communicate(wbuf, 3);
    295    
    296   if (Data.size() == 3) {
    297     DAC[Board][Channel] = SetPoint;
    298         Volt[Board][Channel] = (double) SetPoint / 0xfff * 90;
     246// ***** Set channel voltages *****
     247int Crate::SetChannels(map<unsigned int, unsigned int> V) {
     248 
     249  string Buf;
     250
     251  if (V.empty()) return 1;
     252
     253  // Build and execute commands
     254  for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) {
     255        Buf += char(3<<5) |  char(it->first/NUM_CHANNELS<<1 & 0x0f) | char((it->first%NUM_CHANNELS&16)>>4 & 1);
     256        Buf += char(it->first%NUM_CHANNELS<<4) | ((it->second>>8) & 0x0f);
     257        Buf += char(it->second);
     258  }
     259  vector<char> Data = Communicate(Buf);
     260
     261  // Store new voltage values of successful
     262  if (Data.size() == Buf.size()) {
     263        for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) {
     264          DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
     265          Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = 90.0*it->second/0x0fff;
     266        }
    299267        return 1;
    300268  }
    301   return Data[0];
    302 }
    303 
    304 
    305 // ***** Channel set *****
    306 int Crate::SetAll() {
    307  
    308   unsigned char wbuf[3*MAX_NUM_BOARDS*NUM_CHANNELS];
    309   double Volt = 10;
    310   int Count=0;
    311   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
    312         wbuf[Count++] = 3<<5 |  i<<1 | (j&16)>>4;
    313         wbuf[Count++] = j<<4 | ((int) (Volt/90*0x0fff))>>8;
    314         wbuf[Count++] = (int) (Volt/90*0x0fff);
    315         Volt += 0.2;
    316   }
    317  
    318   // Execute command
    319   vector<char> Data = Communicate(wbuf, 3*MAX_NUM_BOARDS*NUM_CHANNELS);
    320    
    321   if (Data.size() == 3*MAX_NUM_BOARDS*NUM_CHANNELS) {
    322     //DAC[Board][Channel] = SetPoint;
    323         //Volt[Board][Channel] = (double) SetPoint / 0xfff * 90;
    324         return 1;
    325   }
    326   return Data[0];
     269  return Data[0]; 
    327270}
    328271
     
    331274bool Crate::Synch() {
    332275 
    333   unsigned char wbuf = 0;
    334276  int Trial = 0;
    335277  vector<char> Data;
    336278
    337279  while(++Trial <= 3) {
    338     Data = Communicate(&wbuf, 1);
     280    Data = Communicate(string(1, 0));
    339281    if (Data.size() == 3) return true;
    340282    if (Data[0] == 0) break;
  • fact/BIASctrl/Crate.h

    r10052 r10059  
    1010#include <string>
    1111#include <vector>
     12#include <map>
    1213
    1314#include "dis.hxx"
     
    2728        DimService *NameService;
    2829
    29         std::vector<char> Communicate(unsigned char*, int);
     30        std::vector<char> Communicate(std::string);
    3031        void ClearVoltageArrays();
    3132   
     
    3940        int Current[MAX_NUM_BOARDS][NUM_CHANNELS];
    4041        bool OC[MAX_NUM_BOARDS][NUM_CHANNELS];
     42        bool Present[MAX_NUM_BOARDS][NUM_CHANNELS];
    4143        bool ResetHit;
    4244        bool WrapOK;
     
    4446        int ErrorCount;
    4547
    46         int DAC[MAX_NUM_BOARDS][NUM_CHANNELS];      // Voltage in DAC units
     48        unsigned int DAC[MAX_NUM_BOARDS][NUM_CHANNELS];      // Voltage in DAC units
    4749        double Volt[MAX_NUM_BOARDS][NUM_CHANNELS];  // Voltage in Volt
    4850        int CurrentOffset[MAX_NUM_BOARDS][NUM_CHANNELS]; // Offset for current measurement
     
    5052        bool InitOK;
    5153
    52         int SetAll();
     54        int SetChannels(std::map<unsigned int, unsigned int>);
    5355        int ReadAll();
    5456        int SystemReset();
    55         int ReadChannel(unsigned int, unsigned int);
    5657        int GlobalSet(unsigned int);
    57         int ChannelSet(int, int, unsigned int);
    5858        bool Synch();
    5959        bool CurrentCalib(double);
  • fact/BIASctrl/History.txt

    r10052 r10059  
    22                        program 'hvcontrol' (revision 9852).
    3320/8/2010       Removed the possibility to set DAC values.
    4 17/11/2010      Added possibility for bulk transfers (ReadAll(), SetAll())
     417/11/2010      Added possibility for bulk transfers (ReadAll(), SetChannels())
     524/11/2010      Ramping for many channels possible with bulk transfers
  • fact/BIASctrl/User.cc

    r10052 r10059  
    161161  double Double;
    162162  struct Range Crt, Chan;
    163  
     163  vector< map<unsigned int, unsigned int> > Voltages (Crates.size());
     164
    164165  // Loop over all parameters
    165   for (unsigned int n=1; n < Parameter.size()-1; n++) {
     166  for (unsigned int n=1; n < Parameter.size()-1; n+=2) {
    166167
    167168        // Extract channel identification
     
    197198          continue;
    198199        }
    199        
     200
    200201        // Loop over given crates and channels
    201202        for (int i=Crt.Min; i<=Crt.Max; i++) for (int j=Chan.Min; j<=Chan.Max; j++) {
     
    211212          else DACValue = (unsigned int) (Double/90*0x0fff);
    212213
    213           // Set new voltage
    214           if (!RampVoltage(DACValue, i, B, C)) Errors++;
    215 
     214          Voltages[i][j] = DACValue;
    216215        } // Channels
    217216  } // Loop over command argument
    218217
    219   // Update DIM service
    220   for (unsigned int i=0; i<Crates.size(); i++) Crates[i]->BiasVolt->updateService();
    221  
    222   if (Errors > 0) PrintMessage("Errors on %d channel(s) occurred\n", Errors);
     218  // Ramp voltages and update DIM services
     219  for (unsigned int i=0; i<Voltages.size(); i++) {
     220        Errors += RampVoltages(i, Voltages[i]);
     221    Crates[i]->BiasVolt->updateService();
     222  }
     223
     224  if (Errors > 0) Message(ERROR, "%d errors occurred from SetChannels()", Errors);
    223225}
    224226
     
    232234  unsigned int DACValue, NBoards = 0;
    233235  FILE *File;
     236  map<unsigned int, unsigned int> Voltages;
    234237
    235238  // Open file
     
    245248          PrintMessage("Found bias settings for board %s (#%d)\n\r", Crates[Crate]->Name, Crate);
    246249
     250          Voltages.clear();
    247251          Board = 0;  Channel = 0;
    248252          while (fscanf(File, "%u", &DACValue)==1 && Board<MAX_NUM_BOARDS) {
     253                Voltages[Board*NUM_CHANNELS+Channel] = DACValue;
     254
    249255            // Ramp channel to new voltage
    250         if (!RampVoltage(DACValue, Crate, Board, Channel)) {
     256        /*if (!RampVoltage(DACValue, Crate, Board, Channel)) {
    251257              Errors++;
    252258              PrintMessage("Error: Could not ramp board %d, channel %d\n", Board, Channel);
     
    255261              PrintMessage("Ramped board %d, channel %d to %u (%.2f V)                         \r",
    256262                 Board, Channel, DACValue, (double) DACValue/0x0fff*90);
    257                 }
     263                }*/
    258264
    259265                if(++Channel == NUM_CHANNELS) {
     
    262268                }
    263269          }
     270
     271          // Ramp channels
     272          Errors += RampVoltages(Crate, Voltages);
    264273
    265274      // Update DIM service
     
    278287  else if (Errors == 0) PrintMessage("Success: Read bias settings for all connected crates\n");
    279288
    280   if (Errors != 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);
     289  if (Errors != 0) PrintMessage("Warning: %d error(s) occurred\n", Errors);
    281290
    282291  if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n", Parameter[1].c_str());
     
    409418    for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    410419          if (j%12 == 0) PrintMessage("\n%3.1d:  ", j);
    411       if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->Volt[j/NUM_CHANNELS][j%NUM_CHANNELS]);
     420          if (!Crates[i]->Present[j/NUM_CHANNELS][j%NUM_CHANNELS]) PrintMessage("  -   ");
     421      else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->Volt[j/NUM_CHANNELS][j%NUM_CHANNELS]);
    412422          else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->DAC[j/NUM_CHANNELS][j%NUM_CHANNELS]);
    413423          else PrintMessage("%#5.2f %s ", (Crates[i]->Current[j/NUM_CHANNELS][j%NUM_CHANNELS]-Crates[i]->CurrentOffset[j/NUM_CHANNELS][j%NUM_CHANNELS])*1.2, Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":"");
     
    474484// Ramp to new voltage with maximum step size given in fMaxDiff
    475485// No ramping when decreasing voltage
    476 bool User::RampVoltage(unsigned int Target, int Crate, int Board, int Channel) {
    477 
    478   while (Crates[Crate]->DAC[Board][Channel] != (int) Target) {   
    479     int Diff = Target - Crates[Crate]->DAC[Board][Channel];
    480     if (Diff > (int) fMaxDiff) Diff = fMaxDiff;
    481 
    482     if (Crates[Crate]->ChannelSet(Board, Channel, Crates[Crate]->DAC[Board][Channel]+Diff) != 1) {
    483       Message(ERROR, "Could not set bias of crate %d, board %d, channel %d. Skipping channel\n", Crate, Board, Channel);
    484       return false;
    485     }
    486   }
    487 
    488   return true;
     486unsigned int User::RampVoltages(int Crate, map<unsigned int, unsigned int> Voltages) {
     487
     488  map<unsigned int, unsigned int> Target;
     489  unsigned int Errors = 0;
     490
     491  // Ramp until all channels at desired value
     492  while (!Voltages.empty()) {
     493    // Remove channels already at target
     494        for (map<unsigned int, unsigned int>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) {
     495          if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] == it->second) Voltages.erase(it);
     496        }
     497       
     498        // Limit voltage changes to fMaxDiff
     499        Target = Voltages;
     500        for (map<unsigned int, unsigned int>::iterator it = Target.begin(); it != Target.end(); ++it) {
     501          if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2 < it->second) {
     502                it->second = Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2;
     503          }
     504        }       
     505       
     506        // Set channels to next target and wait 10 ms
     507        if (Crates[Crate]->SetChannels(Target) != 1) Errors++;
     508        usleep(10000);
     509  }
     510 
     511  return Errors;
    489512}
    490513
     
    522545      }
    523546
     547          map<unsigned int, unsigned int> Voltages;
     548         
    524549      for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    525550        if (Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS]) {
    526551                  Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS);
    527                   Crates[i]->ChannelSet(j/NUM_CHANNELS, j%NUM_CHANNELS, 0);
    528                   Crates[i]->SystemReset();
     552                  Voltages[j] = 0;
     553                  //Crates[i]->ChannelSet(j/NUM_CHANNELS, j%NUM_CHANNELS, 0);
    529554        }
    530555      }
     556          if (!Voltages.empty()) {
     557                Crates[i]->SetChannels(Voltages);
     558                Crates[i]->SystemReset();
     559          }
    531560        } // for
    532561
  • fact/BIASctrl/User.h

    r10052 r10059  
    5454
    5555        void PrintMessage(const char *, ...);
    56         bool RampVoltage(unsigned int, int, int, int);
     56        unsigned int RampVoltages(int, std::map<unsigned int, unsigned int>);
    5757        void Monitor();
    5858        static void LaunchMonitor(User *);
Note: See TracChangeset for help on using the changeset viewer.