Changeset 176 for drsdaq


Ignore:
Timestamp:
03/10/10 10:34:59 (15 years ago)
Author:
ogrimm
Message:
Migrated to DRS4. DRS class does not run with DRS2 FPGA firmware anymore.
Location:
drsdaq
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • drsdaq/DAQReadout.cc

    r114 r176  
    2626   {"status", &DAQReadout::cmd_status, false, "[daq|drs]", "Show DAQ/DRS status information"},
    2727   {"frequency", &DAQReadout::cmd_freq, true, "<GHz> [reg]", "Set DRS sampling frequency (regulated)"},
    28    {"calib", &DAQReadout::cmd_calib, true, "<trig rate> ", "Response calibration"},
     28   {"acalib", &DAQReadout::cmd_acalib, true, "<trig rate> ", "Amplitude calibration"},
     29   {"tcalib", &DAQReadout::cmd_tcalib, true, "<trig rate> ", "Amplitude calibration"},
    2930   {"trigger", &DAQReadout::cmd_trigger, true, "<on|off>", "Hardware trigger on or off"},
    30    {"delayed", &DAQReadout::cmd_delayed, true, "<on|off>", "Switch delayed start on or off"},
    31    {"wmode", &DAQReadout::cmd_wmode, true, "<0|1>", "Set DRS wave mode"},
    32    {"rmode", &DAQReadout::cmd_rmode, true, "<0|1>", "Set DRS readout mode"},
    33    {"mode", &DAQReadout::cmd_mode, true, "<single|continuous>", "Set DRS single shot or continuous mode"},
     31   {"wmode", &DAQReadout::cmd_wmode, true, "<run|stop>", "Domino wave running or stopped during read out"},
     32   {"rmode", &DAQReadout::cmd_rmode, true, "<first|stop>", "Readout start at first bin or stop position (DRS4)"},
     33   {"dmode", &DAQReadout::cmd_dmode, true, "<single|continuous>", "Domino wave single shot or continuous"},
     34   {"centre", &DAQReadout::cmd_centre, true, "<V>", "Set centre of input range (DRS4)"},
     35   {"refclk", &DAQReadout::cmd_refclk, true, "<FPGA|extern>", "Set reference clock to FPGA or external (DRS4)"},
    3436   {"read", &DAQReadout::cmd_read, false, "<brd chip chan> [res]", "Read current data (and restart if DAQ not active)"},
    3537   {"take", &DAQReadout::cmd_take, false, "<d|p|t> [n] [source]", "Start run (data, pedestal or test) with n events"},
     
    3739   {"start", &DAQReadout::cmd_start, true, "", "Start DRS and DAQ without disk writing (feedback will be called)"},
    3840   {"stop", &DAQReadout::cmd_stop, false, "", "Issue soft trigger and stop DAQ"},
    39    {"test", &DAQReadout::cmd_test, true, "[2e]<blt32|blt64> [n]", "Test read access of VMEbus (n blocks)"},
    4041   {"regtest", &DAQReadout::cmd_regtest, true, "", "DRS register test"},
    4142   {"ramtest", &DAQReadout::cmd_ramtest, true, "", "DRS RAM integrity and speed test"},
     43   {"chiptest", &DAQReadout::cmd_chiptest, true, "", "Chip test"},
     44   {"eepromtest", &DAQReadout::cmd_eepromtest, true, "", "EEPROM test"},
    4245   {"led", &DAQReadout::cmd_led, true, "<on|off>", "Turn LED on or off"},
    4346   {"config", &DAQReadout::cmd_config, false, "", "Print drsdaq configuration"},
     
    6972  Socket             = -1;
    7073  Exit               = false;
    71   CalibrationRead    = false;
    7274  NumEvents          = 0;
    7375  NumEventsRequested = 0;
     
    9193    ConfigOK &= ReadCard("MaxLogLines",        &fMaxLogLines,       'U', File);
    9294    ConfigOK &= ReadCard("RawDataPath",         fRawDataPath,       's', File);
     95    ConfigOK &= ReadCard("CalibDataPath",       fCalibDataPath,     's', File);
    9396    ConfigOK &= ReadCard("FirstSample",        &fFirstSample,       'I', File);
    9497    ConfigOK &= ReadCard("Samples",            &fSamples,           'U', File);
     
    9699    ConfigOK &= ReadCard("MaxFileSizeMB",      &fMaxFileSizeMB,     'I', File);
    97100    ConfigOK &= ReadCard("CCPort",             &fCCPort,            'I', File);
    98     ConfigOK &= ReadCard("FirstVMESlot",       &fFirstVMESlot,      'I', File);
    99     ConfigOK &= ReadCard("LastVMESlot",        &fLastVMESlot,       'I', File);
    100101    ConfigOK &= ReadCard("HVFeedbackConfig",    fHVFeedbackConfig,  's', File);
    101102    ConfigOK &= ReadCard("DefaultFrequency",   &fDefaultFrequency , 'd', File);
     
    109110  }
    110111 
    111   // Truncate log file to given number of lines
    112   char ShellCmd[MAX_COM_SIZE];
    113   snprintf(ShellCmd, sizeof(ShellCmd), "tail --lines=%u %s >%s; cp %s %s; rm %s", fMaxLogLines, fLogFile, TMPNAME, TMPNAME, fLogFile, TMPNAME);
    114   if (system(ShellCmd) != 0) printf("Warning: Could not truncate log file '%s' to %u lines\n", fLogFile, fMaxLogLines);
    115 
    116112  // Open log file and log configuration
    117113  if ((Logfile = fopen(fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", fLogFile);
    118114  PrintMessage(MsgToLog,"********** Logging started **********\n");
    119115  PrintConfig(MsgToLog);
    120 
    121   // Create DRS instance and perform initial scan
    122   drs = new DRS();
    123   drs->SetFirstVMESlot(fFirstVMESlot);
    124   drs->SetLastVMESlot(fLastVMESlot);
    125   drs->InitialScan();
    126116
    127117  // Allocate headers and initialise to zero
     
    132122 
    133123  // Scan for DRS boards
    134   DRSFreq = new float [drs->GetNumberOfBoards()];
    135   if (drs->GetNumberOfBoards()==0) PrintMessage("No DRS boards found - check VME crate and configuration file!\n");
    136 
    137   for (int i=0; i<drs->GetNumberOfBoards(); i++) {
    138     PrintMessage("Init. mezz. board %2d on VME slot %2d %s, serial #%d, firmware revision %d\n",
    139       i, (drs->GetBoard(i)->GetSlotNumber() >> 1)+2, ((drs->GetBoard(i)->GetSlotNumber() & 1) == 0) ? "upper" : "lower",
    140       drs->GetBoard(i)->GetCMCSerialNumber(), drs->GetBoard(i)->GetFirmwareVersion());
     124  DRSFreq = new float [GetNumberOfBoards()];
     125  ACalib = new bool [GetNumberOfBoards()];
     126  ACalibTemp = new double [GetNumberOfBoards()];
     127  TCalib = new bool [GetNumberOfBoards()];
     128
     129  if (GetNumberOfBoards() == 0) PrintMessage("No DRS boards found - check VME crate and configuration file!\n");
     130
     131  for (int i=0; i<GetNumberOfBoards(); i++) {
    141132    NumBoards++;
    142133    LastBoard++;
    143     drs->GetBoard(i)->Init();
    144     drs->GetBoard(i)->SetRotation(false);
     134    GetBoard(i)->Init();
    145135    DRSFreq[i] = 0;
    146   }
    147   BStruct  = new BoardStructure [NumBoards == 0 ? 1:drs->GetNumberOfBoards()];
    148   memset(BStruct, 0, sizeof(BoardStructure)*(NumBoards == 0 ? 1:drs->GetNumberOfBoards()));
    149 
    150   WaveForm = new short [NumBoards == 0 ? 1:NumBoards][kNumberOfChips][kNumberOfChannels][kNumberOfBins];
    151   TriggerCell = new int [NumBoards == 0 ? 1:NumBoards][kNumberOfChips] ();  // Zero initialised
     136    ACalib[i] = false;
     137    ACalibTemp[i] = -999;
     138    TCalib[i] = false;     
     139  }
     140  BStruct  = new BoardStructure [NumBoards == 0 ? 1:GetNumberOfBoards()];
     141  memset(BStruct, 0, sizeof(BoardStructure)*(NumBoards == 0 ? 1:GetNumberOfBoards()));
     142
     143  WaveForm = new short [NumBoards == 0 ? 1:NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins];
     144  TriggerCell = new int [NumBoards == 0 ? 1:NumBoards][kNumberOfChipsMax] ();  // Zero initialised
    152145 
    153146  // Create instance of HV feedback (must be called after CMC board detection)
     
    169162  delete SlowDataClass;
    170163  delete RHeader;     delete EHeader;
    171   delete drs;         delete HVFB;
     164  delete HVFB;        delete[] ACalibTemp;
     165  delete[] ACalib;    delete[] TCalib;
    172166  delete[] DRSFreq;   delete[] BStruct;
    173167  delete[] WaveForm;  delete[] TriggerCell;
     
    232226void DAQReadout::cmd_take() {
    233227 
     228  // Check conditions if this is not a test run
    234229  if(!Match(Param[1],"test")) {
    235230    if (daq_state==active || NumBoards==0) {
     
    237232      return;
    238233    }
     234    // Check if all boards have the same number of DRS chips and channels
     235    // (restriction of current data format)
     236    for (int i=FirstBoard; i<=LastBoard-1; i++) {
     237      if ((GetBoard(i)->GetNumberOfChannels() != GetBoard(i+1)->GetNumberOfChannels()) || (GetBoard(i)->GetNumberOfChips() != GetBoard(i+1)->GetNumberOfChips())) {
     238        PrintMessage("Cannot take data is not all boards have the same number of DRS chips and channels due to data format restriction\n");
     239        return;
     240      }
     241    }
    239242    if (!IsDRSFreqSet()) {
    240243      PrintMessage("Setting default frequency\n");
    241       SetDRSFrequency(fDefaultFrequency, false);
    242       CalibrationRead = false;
    243     }
    244    
    245     if (!CalibrationRead && !ReadCalibration()) {
     244      SetDRSFrequency(fDefaultFrequency, true);
     245    }
     246    if (!ReadCalibration()) {
    246247      PrintMessage("Cannot start run if response calibration not read\n");
    247       return;
    248     }
    249   }
    250    
     248      //return;
     249    }
     250    // Readout from domino wave stop position (ignored if not DRS4)
     251    SetDOMINOReadMode(1);
     252  }
     253     
    251254  if (Match(Param[1],"data")) {
    252255    HWTrigger(1);
     
    272275  else snprintf(RHeader->Description,sizeof(RHeader->Description),"DUMMY");
    273276
    274   // Determine new run number using the file RUN_NUM_FILE
     277  // Determine new run number using the file given by RUN_NUM_FILE
    275278  FILE *RunNumFile = fopen(RUN_NUM_FILE,"r+");
    276279  if(RunNumFile == NULL) {
     
    318321}
    319322
     323// EEPROM test
     324void DAQReadout::cmd_eepromtest() {
     325
     326  unsigned short buf[16384],rbuf[16384];
     327  int n = 0;
     328
     329  for (int i=FirstBoard; i<=LastBoard; i++) {
     330    PrintMessage("EEPROM test of board #%d:\n\r",i);
     331    for (int j=0; j<16384; j++) buf[j] = rand();
     332    GetBoard(i)->WriteEEPROM(1, buf, sizeof(buf));
     333    memset(rbuf, 0, sizeof(rbuf));
     334    GetBoard(i)->Write(T_RAM, 0, rbuf, sizeof(rbuf));
     335    GetBoard(i)->ReadEEPROM(1, rbuf, sizeof(rbuf));
     336   
     337    for (int j=0; j<16384; j++) if (buf[j] != rbuf[j]) n++;
     338    printf("32 kByte written, %d errors\n", n);
     339  }
     340}
     341
    320342// RAM test
    321343void DAQReadout::cmd_ramtest() {
    322344  for (int i=FirstBoard; i<=LastBoard; i++) {
    323     PrintMessage("RAM integrity and speed test (board #%d):\n",i);
    324     (drs->GetBoard(i))->RAMTest(3);
     345    PrintMessage("RAM integrity and speed test of board #%d:\n",i);
     346    GetBoard(i)->RAMTest(3);
    325347  }
    326348}
     
    329351void DAQReadout::cmd_regtest() {
    330352  for (int i=FirstBoard; i<=LastBoard; i++) {
    331     PrintMessage("Register test (board #%d):\n",i);
    332     (drs->GetBoard(i))->RegisterTest();
    333   }
    334 }
    335 
    336 // Test VME transfer
    337 void DAQReadout::cmd_test() {
    338   int Type=-1, i;
    339  
    340   if (Match(Param[1], "2eblt64")) Type = 2;
    341   else if (Match(Param[1], "blt32")) Type = 0;
    342   else if (Match(Param[1], "blt64")) Type = 1;
    343   else {
    344     PrintMessage("Unknown type for testing\n");
    345     return;
    346   }
    347  
    348   if (NumBoards) for (i=FirstBoard; i<=LastBoard; i++) {
    349         PrintMessage("BLT test started (board #%d)\n",i);
    350         (drs->GetBoard(i))->TestRead(Param[2][0] && atoi(Param[2])<=10000 && atoi(Param[2])>0 ? atoi(Param[2]):1, Type);
    351       }
    352   else PrintMessage("No DRS boards available\n");
    353 }
     353    PrintMessage("Register test of board #%d:\n\r",i);
     354    GetBoard(i)->RegisterTest();
     355  }
     356}
     357
     358// Chip test
     359void DAQReadout::cmd_chiptest() {
     360  for (int i=FirstBoard; i<=LastBoard; i++) {
     361    if (GetBoard(i)->ChipTest()) PrintMessage("Chip test of board %i successful\n", i);
     362    else PrintMessage("Chip test of board %i failed\n", i);
     363  }
     364}
    354365
    355366// Stop DAQ
     
    376387    PrintUsage();
    377388    return;
    378   }     
    379   if (atoi(Param[1])>LastBoard || atoi(Param[1])<FirstBoard) {
     389  }
     390  int Board = atoi(Param[1]), Chip = atoi(Param[2]), Channel = atoi(Param[3]);
     391       
     392  if (Board>LastBoard || Board<FirstBoard) {
    380393    PrintMessage("Error: Board number out of range\n");
    381394    return;
    382395  }
    383   if (atoi(Param[3])<0 || atoi(Param[3])>=kNumberOfChannels) {
     396  if (Channel<0 || Channel>=GetBoard(Board)->GetNumberOfChannels()) {
    384397    PrintMessage("Error: Channel number out of range\n");
    385398    return;
    386399  }
    387   if (atoi(Param[2])<0 || atoi(Param[2])>=kNumberOfChips) {
     400  if (Chip<0 || Chip>=GetBoard(Board)->GetNumberOfChips()) {
    388401    PrintMessage("Error: Chip number out of range\n");
    389402    return;
    390403  }
    391  
    392   if (daq_state!=active) {
    393     if (!CalibrationRead) ReadCalibration();
     404
     405  if (daq_state != active) {
     406    ReadCalibration();
    394407    if(NParam==5) StopDRS();
    395408    ReadCalibratedDRSData();
    396409    if(NParam==5) StartDRS();
    397   } 
    398   PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[atoi(Param[1])],drs->GetBoard(atoi(Param[1]))->GetPrecision());
    399   for (int k=0; k<kNumberOfBins; k++) PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "%.1f ",
    400         (float) WaveForm[atoi(Param[1])][atoi(Param[2])][atoi(Param[3])][(k+TriggerCell[atoi(Param[1])][atoi(Param[2])])%kNumberOfBins]);
     410  }
     411
     412  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[Board],GetBoard(Board)->GetPrecision());
     413  double mean=0,square=0.0;
     414  for (int k=0; k<kNumberOfBins; k++) {
     415//    PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "%.1f ", (float) WaveForm[Board][Chip][Channel][(k+TriggerCell[Board][Chip])%kNumberOfBins]);
     416    PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "%.1f ", (float) WaveForm[Board][Chip][Channel][k]);
     417
     418        mean += (float) WaveForm[atoi(Param[1])][atoi(Param[2])][atoi(Param[3])][(k+TriggerCell[atoi(Param[1])][atoi(Param[2])])%kNumberOfBins];
     419                square += pow((float) WaveForm[atoi(Param[1])][atoi(Param[2])][atoi(Param[3])][(k+TriggerCell[atoi(Param[1])][atoi(Param[2])])%kNumberOfBins],2);
     420
     421       
     422  }
    401423  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==END==");
    402424  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "\n");
     425  PrintMessage(MsgToConsole, "Trigger cell: %d\n", TriggerCell[Board][Chip]); 
     426  printf("rms: %f\n",sqrt(square/kNumberOfBins - pow(mean/kNumberOfBins,2)));
    403427}
    404428
    405429// Set Domino mode
    406 void DAQReadout::cmd_mode() {
     430void DAQReadout::cmd_dmode() {
    407431  if (Match(Param[1],"continuous")) SetDOMINOMode(1);
    408432  else if (Match(Param[1],"single")) SetDOMINOMode(0);
     
    412436// Set Domino readout mode
    413437void DAQReadout::cmd_rmode() {
    414   if (Match(Param[1],"1")) SetDOMINOReadMode(1);
    415   else if (Match(Param[1],"0")) SetDOMINOReadMode(0);
     438  if (Match(Param[1],"first")) SetDOMINOReadMode(0);
     439  else if (Match(Param[1],"stop")) SetDOMINOReadMode(1);
    416440  else PrintUsage();
    417441}
     
    419443// Set Domino wave mode
    420444void DAQReadout::cmd_wmode() {
    421   if (Match(Param[1],"1")) SetDOMINOWaveMode(1);
    422   else if (Match(Param[1],"0")) SetDOMINOWaveMode(0);
     445  if (Match(Param[1],"run")) SetDOMINOWaveMode(1);
     446  else if (Match(Param[1],"stop")) SetDOMINOWaveMode(0);
    423447  else PrintUsage();
    424448}
    425449
    426 // Switch delayed start on/off
    427 void DAQReadout::cmd_delayed() {
    428   if (Match(Param[1],"on")) SetDelayedStart(1);
    429   else if (Match(Param[1],"off")) SetDelayedStart(0);
    430   else PrintUsage();
    431 }
     450// Set input range
     451void DAQReadout::cmd_centre() {
     452
     453  if (NParam!=2) {
     454    PrintUsage();
     455    return;
     456  }
     457 
     458  for (int i=FirstBoard; i<=LastBoard; i++) {
     459    if (GetBoard(i)->SetInputRange(atof(Param[1])) == 1) {
     460      PrintMessage("Range of board %d: %.2f to %.2f Volt (centre %.2f V)\n",i,atof(Param[1])-0.5, atof(Param[1])+0.5, atof(Param[1]));
     461    }
     462    else PrintMessage("Centre voltage of board %d out of range\n", i);
     463  }
     464}
     465
     466// Set refclock source
     467void DAQReadout::cmd_refclk() {
     468
     469  if (NParam!=2) {
     470    PrintUsage();
     471    return;
     472  }
     473 
     474  for (int i=FirstBoard; i<=LastBoard; i++) {
     475    if (Match(Param[1], "extern")) GetBoard(i)->SetRefclk(1);
     476        else GetBoard(i)->SetRefclk(0);
     477  }
     478}
    432479
    433480// Set trigger mode
     
    447494    else {
    448495      PrintMessage("Flashing EEPROM of board %d...\n", atoi(Param[1]));
    449       (drs->GetBoard(atoi(Param[1])))->FlashEEPROM(atoi(Param[2]));
     496      (GetBoard(atoi(Param[1])))->SetBoardSerialNumber(atoi(Param[2]));
    450497    }
    451498  }
     
    453500}
    454501
    455 // Do internal calibration
    456 void DAQReadout::cmd_calib() {
    457   char str[MAX_COM_SIZE];
    458 
    459   if (NParam!=2 || !atof(Param[1])) {
    460     PrintUsage();
     502// Do amplitude calibration
     503void DAQReadout::cmd_acalib() {
     504
     505  if (!IsDRSFreqSet()) {
     506    PrintMessage("Set sampling frequency for all boards first\n");
    461507    return;
    462508  }
     509     
     510  for (int i=FirstBoard; i<=LastBoard; i++) {
     511    if (GetBoard(i)->GetDRSType()==2 && (NParam!=2 || !atof(Param[1]))) {
     512      PrintUsage();
     513      return;
     514    }
     515
     516    PrintMessage("Creating amplitude calibration of board %d (serial #%04d)\n", i, GetBoard(i)->GetBoardSerialNumber());
     517   
     518    GetBoard(i)->EnableTcal(0);
     519    GetBoard(i)->SelectClockSource(0);
     520    if (GetBoard(i)->GetDRSType() == 4) {
     521      GetBoard(i)->SetFrequency(DRSFreq[i], true);
     522      GetBoard(i)->CalibrateVolt(this);
     523    } else {
     524      GetBoard(i)->Init();
     525      GetBoard(i)->SetFrequency(DRSFreq[i], true);
     526      GetBoard(i)->SoftTrigger();
     527
     528      if (GetBoard(i)->GetDRSType() == 3) {
     529        GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,11,0,20,0,0,0,0,0);
     530      }
     531      else GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,atof(Param[1]),0);
     532 
     533      GetBoard(i)->SetCalibrationDirectory(fCalibDataPath);
     534      for (int j=0; j<2; j++) {
     535        GetBoard(i)->GetResponseCalibration()->ResetCalibration();
     536        while (!GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {}
     537        PrintMessage("Calibration points recorded.\n");
     538        while (!GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {}
     539        PrintMessage("Calibration points fitted.\n");
     540        while (!GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {}
     541        PrintMessage("Offset calibration done.\n");
     542        if (!GetBoard(i)->GetResponseCalibration()->WriteCalibration(j)) break;
     543      }
     544    } // else for DRS2/3
     545    ACalib[i] = true;
     546    ACalibTemp[i] = GetBoard(i)->GetTemperature();
     547  } // Loop over boards
     548  PrintMessage("Amplitude calibration finished\n");
     549}
     550
     551// Do time calibration
     552void DAQReadout::cmd_tcalib() {
     553 
    463554  if (!IsDRSFreqSet()) {
    464     PrintMessage("Set sampling frequency first\n");
     555    PrintMessage("Set sampling frequency for all boards first\n");
    465556    return;
    466557  }
    467558     
    468   getcwd(str, sizeof(str));
    469   strcat(str,"/calib");
    470 
    471559  for (int i=FirstBoard; i<=LastBoard; i++) {
    472     PrintMessage("Creating calibration of board %d (serial number %d)\n", i, drs->GetBoard(i)->GetCMCSerialNumber());
    473 
    474     drs->GetBoard(i)->EnableTcal(1);
    475     if (drs->GetBoard(i)->GetChipVersion() == 3) drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,21,0,20,0,0,0,0,0);
    476     else drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,atof(Param[1]),0);
    477     drs->GetBoard(i)->SetCalibrationDirectory(str);
    478 
    479     for (int j=0; j<kNumberOfChips; j++) {
    480       drs->GetBoard(i)->GetResponseCalibration()->ResetCalibration();
    481 
    482       while (!drs->GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {}
    483       PrintMessage("Calibration points recorded.\n");
    484 
    485       while (!drs->GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {}
    486       PrintMessage("Calibration points fitted.\n");
    487 
    488       while (!drs->GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {}
    489       PrintMessage("Offset calibration done.\n");
    490 
    491       if (!drs->GetBoard(i)->GetResponseCalibration()->WriteCalibration(j)) break;
    492     }       
    493   } // Loop over boards
    494   PrintMessage("End of calibration\n");
    495   CalibrationRead = false;
     560    if (GetBoard(i)->GetDRSType() != 4 || GetBoard(i)->GetFirmwareVersion() < 13279) {
     561      PrintMessage("Time calibration needs DRS4 and minimum firmware version 13279, skipping board %d\n", i);
     562      continue;
     563    }
     564    if (!ACalib[i]) {
     565      PrintMessage("Amplitude calibration of board %d has to be done first, skipping this board\n", i);
     566      continue;
     567    }
     568    PrintMessage("Creating time calibration of board %d (serial #%04d)\n", i, GetBoard(i)->GetBoardSerialNumber());
     569   
     570    GetBoard(i)->SetFrequency(DRSFreq[i], true);
     571    if (GetBoard(i)->CalibrateTiming(this) != 1) {
     572      PrintMessage("Time calibration method returned error status, stopping calibration\n");
     573      return;
     574    }
     575
     576    TCalib[i] = true;
     577
     578    // Write calibration data to file
     579    float Time[kNumberOfChipsMax][kNumberOfBins];
     580    char *Filename;
     581    FILE *Calibfile;
     582        bool WriteOK = true;
     583       
     584    // Copy calibration data into array
     585        for (int Chip=0; Chip<GetBoard(i)->GetNumberOfChips(); Chip++) {
     586      GetBoard(i)->GetTime(Chip, Time[Chip], true, false);
     587        }
     588   
     589    if (asprintf(&Filename, "TCalib_%d_%.2fGHz.txt", GetBoard(i)->GetBoardSerialNumber(), DRSFreq[i]) == -1) {
     590      PrintMessage("Error: asprintf() failed, cannot generate filename (%s)\n", strerror(errno));
     591      return;
     592    }
     593    if ((Calibfile=fopen(Filename,"w")) == NULL) {
     594      PrintMessage("Error: Could not open file '%s' \n", Filename);     
     595    }
     596    else {
     597      if(fprintf(Calibfile, "# DRS time calibration\n") == -1) WriteOK = false;
     598
     599      for (int Bin=0; Bin<kNumberOfBins; Bin++) {
     600                for (int Chip=0; Chip<GetBoard(i)->GetNumberOfChips(); Chip++) {
     601          if(fprintf(Calibfile, "%.2f ", Time[Chip][Bin]) == -1) WriteOK = false;
     602                }
     603        if(fprintf(Calibfile, "\n") == -1) WriteOK = false;
     604          }
     605          if (fclose(Calibfile) != 0) PrintMessage("Error closing file '%s'\n", Filename);
     606        }
     607        if (!WriteOK) PrintMessage("Error writing to file '%s'\n", Filename);
     608        else PrintMessage("Calibration written to file '%s'\n", Filename);
     609       
     610    free(Filename);
     611  }
     612  PrintMessage("Time calibration finished\n");
    496613}
    497614
     
    500617  if (NParam>=2 && atof(Param[1])) {
    501618    SetDRSFrequency(atof(Param[1]), NParam==2 ? false : true);
    502     CalibrationRead = false;
    503619  }
    504620  else PrintUsage();
     
    509625  if (Match(Param[1], "on") || Match(Param[1], "off"))
    510626    for (int i=FirstBoard; i<=LastBoard; i++)
    511       (drs->GetBoard(i))->SetLED(Match(Param[1], "on") ? 1 : 0);     
     627      (GetBoard(i))->SetLED(Match(Param[1], "on") ? 1 : 0);     
    512628  else PrintUsage();
    513629}
     
    528644                " Disk space: %lu MByte\n"
    529645                " Socket state: %s\n"                             
    530                 " Total number of CMC boards: %d\n"
    531                 " Active CMC boards: %d\n",
     646                " Total number of DRS boards: %d\n"
     647                " Active DRS boards: %d\n",
    532648      daq_state_str[daq_state], daq_state==active ? (int) RunNumber:-1,
    533       daq_runtype_str[daq_runtype], NumEvents,
     649      daq_state==active ? daq_runtype_str[daq_runtype]:"n/a", NumEvents,
    534650      NumEventsRequested, fRawDataPath,
    535651      CheckDisk(fRawDataPath), Socket==-1 ? "disconnected":"connected",
     
    545661      for (int i=FirstBoard; i<=LastBoard; i++) {
    546662
    547         PrintMessage(" Mezz. board index:    %d\n"
    548                     " Slot:                 %d %s\n",i,((drs->GetBoard(i))->GetSlotNumber() >> 1)+2,((drs->GetBoard(i))->GetSlotNumber() & 1)==0 ? "upper":"lower");
    549         PrintMessage(" Chip version:         DRS%d\n"
    550                     " Board version:        %d\n"
    551                     " Serial number:        %d\n"
    552                     " Firmware revision:    %d\n"
    553                     " Temperature:          %1.1lf C\n"
    554                     " Status reg.:          0X%08X\n",
    555                     (drs->GetBoard(i))->GetChipVersion(),
    556                     (drs->GetBoard(i))->GetCMCVersion(),
    557                     (drs->GetBoard(i))->GetCMCSerialNumber(),
    558                     (drs->GetBoard(i))->GetFirmwareVersion(),
    559                     (drs->GetBoard(i))->GetTemperature(),
    560                     (drs->GetBoard(i))->GetStatusReg());
    561 
    562 
    563         if ((drs->GetBoard(i))->GetStatusReg() & BIT_RUNNING)
     663        PrintMessage("Board #%d in slot %d %s\n",i,((GetBoard(i))->GetSlotNumber() >> 1)+2,((GetBoard(i))->GetSlotNumber() & 1)==0 ? "upper":"lower");
     664        PrintMessage(" DRS%d   serial %d, firmware %d\n"
     665                    " Actual temperature:   %1.1lf C\n"
     666                    " Calibration temp.:    %1.1lf C\n"
     667                    " Status reg.:          0x%08X\n",
     668                    GetBoard(i)->GetDRSType(),
     669                    GetBoard(i)->GetBoardSerialNumber(),
     670                    GetBoard(i)->GetFirmwareVersion(),
     671                    GetBoard(i)->GetTemperature(),
     672                    ACalibTemp[i],
     673                    GetBoard(i)->GetStatusReg());
     674
     675
     676        if (GetBoard(i)->GetStatusReg() & BIT_RUNNING)
    564677          PrintMessage("   Domino wave running\n");
    565         if ((drs->GetBoard(i))->GetStatusReg() & BIT_NEW_FREQ1)
     678        if (GetBoard(i)->GetStatusReg() & BIT_NEW_FREQ1)
    566679          PrintMessage("   New Freq1 ready\n");
    567         if ((drs->GetBoard(i))->GetStatusReg() & BIT_NEW_FREQ2)
     680        if (GetBoard(i)->GetStatusReg() & BIT_NEW_FREQ2)
    568681          PrintMessage("   New Freq2 ready\n");
    569682
    570         PrintMessage(" Control reg.:         0X%08X\n", (drs->GetBoard(i))->GetCtrlReg());
    571         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_AUTOSTART)
     683        PrintMessage(" Control reg.:         0x%08X\n", (GetBoard(i))->GetCtrlReg());
     684        if (GetBoard(i)->GetCtrlReg() & BIT_AUTOSTART)
    572685          PrintMessage("   AUTOSTART enabled\n");
    573         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_DMODE)
     686        if (GetBoard(i)->GetCtrlReg() & BIT_DMODE)
    574687          PrintMessage("   DMODE circular\n");
    575688        else
    576689          PrintMessage("   DMODE single shot\n");
    577         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_LED)
     690        if (GetBoard(i)->GetCtrlReg() & BIT_LED)
    578691          PrintMessage("   LED\n");
    579         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_TCAL_EN)
     692        if (GetBoard(i)->GetCtrlReg() & BIT_TCAL_EN)
    580693          PrintMessage("   TCAL enabled\n");
    581         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_ZERO_SUPP)
    582           PrintMessage("   ZERO_SUPP enabled\n");
    583         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_FREQ_AUTO_ADJ)
     694        if (GetBoard(i)->GetCtrlReg() & BIT_TCAL_SOURCE)
     695          PrintMessage("   TCAL_SOURCE enabled\n");
     696        if (GetBoard(i)->GetCtrlReg() & BIT_FREQ_AUTO_ADJ)
    584697          PrintMessage("   FREQ_AUTO_ADJ enabled\n");
    585         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_ENABLE_TRIGGER)
     698        if (GetBoard(i)->GetCtrlReg() & BIT_ENABLE_TRIGGER1)
    586699          PrintMessage("   ENABLE_TRIGGER\n");
    587         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_LONG_START_PULSE)
     700        if (GetBoard(i)->GetCtrlReg() & BIT_LONG_START_PULSE)
    588701          PrintMessage("   LONG_START_PULSE\n");
    589         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_DELAYED_START)
    590           PrintMessage("   DELAYED_START\n");
    591         if ((drs->GetBoard(i))->GetCtrlReg() & BIT_ACAL_EN)
     702        if (GetBoard(i)->GetCtrlReg() & BIT_ACAL_EN)
    592703          PrintMessage("   ACAL enabled\n");
    593         PrintMessage(" Trigger bus:          0X%08X\n", (drs->GetBoard(i))->GetTriggerBus());
    594         if ((drs->GetBoard(i))->IsBusy()) {
    595           (drs->GetBoard(i))->ReadFrequency(0, &freq);
     704        PrintMessage(" Trigger bus:          0x%08X\n", GetBoard(i)->GetTriggerBus());
     705        if (GetBoard(i)->IsBusy()) {
     706          GetBoard(i)->ReadFrequency(0, &freq);
    596707          PrintMessage(" Frequency0:           %1.4lf GHz\n", freq);
    597           (drs->GetBoard(i))->ReadFrequency(1, &freq);
     708          GetBoard(i)->ReadFrequency(1, &freq);
    598709          PrintMessage(" Frequency1:           %1.4lf GHz\n", freq);
    599710        }
     
    609720  if (Match(Param[1],"all")) {
    610721    FirstBoard = 0;
    611     LastBoard = drs->GetNumberOfBoards()-1;
     722    LastBoard = GetNumberOfBoards()-1;
    612723  }
    613724  else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NumBoards) {
     
    621732  }
    622733  else PrintMessage("Cannot address board(s), out of range.\n");
    623   CalibrationRead = false;
    624734}
    625735
     
    677787  else if(NParam!=5) PrintUsage();
    678788  else for (int i=FirstBoard; i<=LastBoard; i++)
    679          for (int j=0; j<kNumberOfChips; j++)
    680            for (int k=0; k<kNumberOfChannels; k++)
     789         for (int j=0; j<GetBoard(i)->GetNumberOfChips(); j++)
     790           for (int k=0; k<GetBoard(i)->GetNumberOfChannels(); k++)
    681791             if ((atoi(Param[1])==i || Match(Param[1],"all")) &&
    682792                 (atoi(Param[2])==j || Match(Param[2],"all")) &&
     
    703813// Start domino wave
    704814void DAQReadout::StartDRS() {
    705   for (int i=FirstBoard; i<=LastBoard; i++) drs->GetBoard(i)->StartDomino();
     815  for (int i=FirstBoard; i<=LastBoard; i++) GetBoard(i)->StartDomino();
    706816}
    707817
    708818// Stop domino wave
    709819void DAQReadout::StopDRS() {
    710   for (int i=FirstBoard; i<=LastBoard; i++) drs->GetBoard(i)->SoftTrigger();
    711 }
    712 
    713 // Transfer data to memory
     820  for (int i=FirstBoard; i<=LastBoard; i++) GetBoard(i)->SoftTrigger();
     821}
     822
     823// Transfer amplitude-calibrated waveforms to memory
    714824void DAQReadout::ReadCalibratedDRSData() {
    715825
    716826  for (int i=FirstBoard; i<=LastBoard; i++) {
    717     (drs->GetBoard(i))->TransferWaves(kNumberOfChannels*kNumberOfChips);
    718     for (int j=0; j<kNumberOfChannels; j++) {
    719        drs->GetBoard(i)->GetWave(0, j, WaveForm[i][0][j], true); // Chip #1
    720        TriggerCell[i][0] = drs->GetBoard(i)->GetTriggerCell((unsigned int) 0);
    721        drs->GetBoard(i)->GetWave(1, j, WaveForm[i][1][j], true); // Chip #2
    722        TriggerCell[i][1] = drs->GetBoard(i)->GetTriggerCell((unsigned int) 1);
     827    GetBoard(i)->TransferWaves(GetBoard(i)->GetNumberOfChannels()*GetBoard(i)->GetNumberOfChips());
     828
     829    for (int j=0; j<GetBoard(i)->GetNumberOfChannels(); j++) {
     830      for (int k=0; k<GetBoard(i)->GetNumberOfChips(); k++) {
     831        GetBoard(i)->GetWave(k, j, WaveForm[i][k][j], true, GetBoard(i)->GetTriggerCell(k));
     832        TriggerCell[i][k] = GetBoard(i)->GetTriggerCell(k);
     833      }
    723834    }
    724835  }
     
    728839bool DAQReadout::ReadCalibration() {
    729840
    730   char dir[MAX_COM_SIZE];
    731 
    732   getcwd(dir, sizeof(dir));
    733   strcat(dir,"/calib");
    734841  for (int i=FirstBoard; i<=LastBoard; i++) {
    735     (drs->GetBoard(i))->SetCalibrationDirectory(dir);
    736     PrintMessage("Reading response calibration file for board %d from: \"%s\"\n", i, dir);
    737     for (int Chip=0; Chip<kNumberOfChips; Chip++)
    738       if (drs->GetBoard(i)->GetResponseCalibration()->ReadCalibration(Chip)==false) {
    739         CalibrationRead = false;
    740         return false;
     842    if (!TCalib[i]) PrintMessage("Warning: No time calibration for board %d\n", i);
     843   
     844    if (GetBoard(i)->GetDRSType() == 4) {
     845      if (ACalib[i] == false) return false;
     846    }
     847    else {
     848      if (!ACalib[i]) {
     849        GetBoard(i)->SetCalibrationDirectory(fCalibDataPath);
     850        PrintMessage("Reading response calibration file for board %d from: \"%s\"\n", i, fCalibDataPath);
     851        for (int Chip=0; Chip<GetBoard(i)->GetNumberOfChips(); Chip++) {
     852          if (GetBoard(i)->GetResponseCalibration()->ReadCalibration(Chip) == false) return false;
     853        }
     854        ACalib[i] = true;
    741855      }
    742   }
    743   CalibrationRead = true;
     856    }
     857  } // Loop over boards
    744858  return true;
    745859}
     
    758872void DAQReadout::SetDOMINOMode(int mode) {
    759873 
     874  for (int i=FirstBoard; i<=LastBoard; i++) {
     875    GetBoard(i)->SetDominoMode(mode==1 ? 1:0);
     876    PrintMessage("Domino mode of board %d switched to %s.\n",i,mode==1 ? "continuous":"single shot");
     877  }
     878}
     879
     880// Set DOMINO readout mode
     881void DAQReadout::SetDOMINOReadMode(int mode) {
     882
     883  for (int i=FirstBoard; i<=LastBoard; i++) {
     884    GetBoard(i)->SetReadoutMode(mode);
     885    PrintMessage("Start readout of board %d from %s.\n",i,mode==0 ? "first bin":"stop position");
     886  }
     887}
     888
     889// Set DOMINO wave mode
     890void DAQReadout::SetDOMINOWaveMode(int mode) {
     891
     892  for (int i=FirstBoard; i<=LastBoard; i++) {
     893    GetBoard(i)->SetDominoActive(mode);
     894    PrintMessage("Domino wave of board %d is %s during readout\n",i,mode==1 ? "running":"stopped");
     895  }
     896}
     897
     898// Enable hardware trigger of all boards
     899void DAQReadout::HWTrigger(int mode) {
     900
    760901  if (NumBoards)
    761902    for (int i=FirstBoard; i<=LastBoard; i++) {
    762       (drs->GetBoard(i))->SetDominoMode(mode==1 ? 1:0);
    763       PrintMessage("Domino mode of board %d switched to %s.\n",i,mode==1 ? "continuous":"single shot");
    764     }
    765   else PrintMessage("No DRS boards available\n");
    766 }
    767 
    768 // Set DOMINO readout mode
    769 void DAQReadout::SetDOMINOReadMode(int mode) {
    770 
    771   if (NumBoards)
    772     for (int i=FirstBoard; i<=LastBoard; i++) {
    773       (drs->GetBoard(i))->SetReadoutMode(mode==1 ? 1:0);
    774       PrintMessage("Start readout of board %d from %s.\n",i,mode==1 ? "first bin":"stop position");
    775     }
    776   else PrintMessage("No DRS boards available\n");
    777 }
    778 
    779 // Set DOMINO wave mode
    780 void DAQReadout::SetDOMINOWaveMode(int mode) {
    781 
    782   if (NumBoards)
    783     for (int i=FirstBoard; i<=LastBoard; i++) {
    784       (drs->GetBoard(i))->SetDominoActive(mode==1 ? 1:0);
    785       PrintMessage("Domino wave of board %d is %s during readout\n",i,mode==1 ? "running":"stopped");
    786     }
    787   else PrintMessage("No DRS boards available\n");
    788 }
    789 
    790 // Delayed start on/off
    791 void DAQReadout::SetDelayedStart(int mode) {
    792 
    793   if (NumBoards)
    794     for (int i=FirstBoard; i<=LastBoard; i++) {
    795       (drs->GetBoard(i))->SetDelayedStart(mode==1 ? 1:0);
    796        PrintMessage("Delayed start of board %d is %s\n",i,mode==1 ? "on":"off");
    797     }
    798   else PrintMessage("No DRS boards available\n");
    799 }
    800 
    801 // Enable hardware trigger of all boards
    802 void DAQReadout::HWTrigger(int mode) {
    803 
    804   if (NumBoards)
    805     for (int i=FirstBoard; i<=LastBoard; i++) {
    806       drs->GetBoard(i)->EnableTrigger(mode==1 ? 1:0);
     903      GetBoard(i)->EnableTrigger(mode, 0);
    807904      PrintMessage("Hardware trigger of board %d %s\n",i,mode==1 ? "enabled":"disabled");
    808905    }
     
    813910void DAQReadout::SetDRSFrequency(double freq, bool Regulation) {
    814911
    815   double currentfreq;
    816 
    817   PrintMessage("Setting frequency %s regulation:\n",Regulation ? "with":"without");
     912  PrintMessage("Setting frequency %s regulation\n",Regulation ? "with":"without");
     913 
    818914  for (int i=FirstBoard; i<=LastBoard; i++) {
    819     drs->GetBoard(i)->SetDebug(1);
    820 
    821     if (Regulation ? drs->GetBoard(i)->RegulateFrequency(freq) : drs->GetBoard(i)->SetFrequency(freq)) {
    822       drs->GetBoard(i)->ReadFrequency(0, &currentfreq);
    823       DRSFreq[i] = freq;
    824       PrintMessage("Domino wave of board %d is running at %1.3lf GHz\n",i,currentfreq);
    825     } else {
    826       DRSFreq[i] = 0;
    827       PrintMessage("Warning: Domino wave of board %d has changed but not reached the requested value\n",i);
    828     }
     915    if ((Regulation ? GetBoard(i)->RegulateFrequency(freq) :
     916    GetBoard(i)->SetFrequency(freq, true)) == 0) {
     917      PrintMessage("Warning: Board %d has not reached the requested value\n",i);
     918    }
     919
     920    double f;
     921    GetBoard(i)->ReadFrequency(0, &f);
     922    DRSFreq[i] = f;
     923    ACalib[i] = false;
     924    TCalib[i] = false;
     925    PrintMessage("Board %d is running at %1.3lf GHz\n",i,f);
    829926  }
    830927}
     
    834931
    835932  for (int i=FirstBoard; i<=LastBoard; i++)     
    836     if ((drs->GetBoard(i))->IsBusy()) return true;
     933    if ((GetBoard(i))->IsBusy()) return true;
    837934  return false;
    838935}
     
    842939
    843940  for (int i=FirstBoard; i<=LastBoard; i++)
    844     if (DRSFreq[i]==0) {
    845       PrintMessage("DRS sampling frequency of board %d not set!\n",i);
     941    if (DRSFreq[i] == 0) {
     942      PrintMessage("Sampling frequency of DRS board %d not set\n", i);
    846943      return false;
    847944    }
     
    9061003 
    9071004  RHeader->NBoards   = NumBoards==0 && daq_runtype==test ? 1 : (LastBoard - FirstBoard) + 1; 
    908   RHeader->NChips    = kNumberOfChips;
    909   RHeader->NChannels = kNumberOfChannels;
     1005  RHeader->NChips    = NumBoards==0 ? kNumberOfChipsMax : GetBoard(0)->GetNumberOfChips();
     1006  RHeader->NChannels = NumBoards==0 ? kNumberOfChannelsMax : GetBoard(0)->GetNumberOfChannels();
    9101007  RHeader->NBytes    = sizeof(short);
    9111008
     
    9191016 
    9201017  for (int i=FirstBoard; i<=LastBoard; i++) {
    921     BStruct[i].SerialNo    = drs->GetBoard(i)->GetCMCSerialNumber();     
    922     BStruct[i].BoardTemp   = drs->GetBoard(i)->GetTemperature();
     1018    BStruct[i].SerialNo    = GetBoard(i)->GetBoardSerialNumber();         
     1019    BStruct[i].BoardTemp   = GetBoard(i)->GetTemperature();
    9231020    BStruct[i].NomFreq     = DRSFreq[i];
    924     BStruct[i].ScaleFactor = drs->GetBoard(i)->GetPrecision();
     1021    BStruct[i].ScaleFactor = GetBoard(i)->GetPrecision();
    9251022  }
    9261023
     
    9901087
    9911088  // First chunk: trigger cells
    992   DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*kNumberOfChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) !
    993   DataPart[Count++].iov_len = RHeader->NBoards * kNumberOfChips * sizeof(int);
     1089  DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*RHeader->NChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) !
     1090  DataPart[Count++].iov_len = RHeader->NBoards * RHeader->NChips * sizeof(int);
    9941091  Size += DataPart[Count-1].iov_len;
    9951092
     
    9971094  for (int i=FirstBoard; (i<=LastBoard + (NumBoards==0)); i++) {
    9981095    for (unsigned int k=0; k<RHeader->NChips; k++) {
    999       Start = (TriggerCell[i][k]-fFirstSample+kNumberOfBins) % kNumberOfBins;  // Start bin for this chip
     1096      // Start bin
     1097      if (GetBoard(i)->GetDRSType() == 4) Start = 0;
     1098      else Start = (TriggerCell[i][k]-fFirstSample+kNumberOfBins) % kNumberOfBins;
    10001099      for (unsigned int l=0; l<RHeader->NChannels; l++) {
    10011100        DataPart[Count].iov_base = &WaveForm[i][k][l][Start];
     
    10311130               "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n"
    10321131               "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n"
    1033                "FirstVMESlot: %d\t\tLastVMESlot: %d\n"
     1132               "CalibDataPath: %s\n"
    10341133               "SlowDataPath: %s\tHVFeedbackConfig: %s\n",
    10351134    fLogFile,fMaxLogLines,fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB,
    1036     fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fSlowDataPath,fHVFeedbackConfig);
     1135    fMaxFileSizeMB,fCCPort,fCalibDataPath,fSlowDataPath,fHVFeedbackConfig);
    10371136}
    10381137
     
    10411140  PrintMessage("Usage: %s %s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters);
    10421141}
    1043          
     1142
     1143// Print progress (used in DRS class)
     1144void DAQReadout::Progress(int Progress) {
     1145  PrintMessage(MsgToConsole, "\rProgress: %d%%              ", Progress);
     1146  fflush(stdout);
     1147};
     1148 
    10441149// Print message to selected target
    10451150void DAQReadout::PrintMessage(int Target, const char *Format, ...) {
     
    12301335      else {
    12311336        double Period = ((double) rand())/RAND_MAX*20;
    1232         for (long unsigned int i=0; i<m->RHeader->NBoards*kNumberOfChips*kNumberOfChannels*kNumberOfBins; i++)
     1337        for (long unsigned int i=0; i<m->RHeader->NBoards*m->RHeader->NChips*m->RHeader->NChannels*m->RHeader->Samples; i++)
    12331338          *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000);
    12341339      }
     
    12661371  m->SlowDataClass->AddToEntry("%d %s %s %d %d %s", m->RunNumber, WriteError?"Error":"OK", daq_runtype_str[m->daq_runtype], m->NumEvents, m->FileNumber, m->RHeader->Description);
    12671372  if(m->SlowDataClass->ErrorCode != 0) {
    1268     m->PrintMessage("Error, could not write DAQ data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode));
     1373    m->PrintMessage("Error: Could not write DAQ slow data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode));
    12691374  }
    12701375
  • drsdaq/DAQReadout.h

    r114 r176  
    77#include <time.h>
    88#include <errno.h>
     9#include <unistd.h>
    910#include <sys/socket.h>
    1011#include <pthread.h>
     
    1819#include "HVFeedback.h"
    1920
    20 #define RUN_NUM_FILE "/ct3data/LastRunNumber"
     21#define RUN_NUM_FILE "/home/ogrimm/Data/LastRunNumber"
    2122
    2223#define MAX_PATH 256            // also used for filename length
     
    3132enum runtype_enum {data, pedestal, reserved, test};
    3233
    33 class DAQReadout {
     34class DAQReadout : public DRS, public DRSCallback {
    3435    time_t StartTime;
    3536
     
    4041    FILE *Logfile;   
    4142    void PrintUsage();
    42     bool CalibrationRead;
    4343       
    4444  public:
     
    4646    EventHeader* EHeader;
    4747   
    48     DRS *drs;
    49 
    50     short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins];
    51     int (*TriggerCell)[kNumberOfChips];
     48    short (*WaveForm)[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins];
     49    int (*TriggerCell)[kNumberOfChipsMax];
    5250
    5351    pthread_mutex_t control_mutex;
     
    5957    char fLogFile[MAX_PATH];
    6058    char fSlowDataPath[MAX_PATH];
     59    char fCalibDataPath[MAX_PATH];
    6160    unsigned int fMaxLogLines;
    6261    char fRawDataPath[MAX_PATH];
     
    6665    unsigned int fSamples;
    6766    int fCCPort;
    68     int fLastVMESlot;
    69     int fFirstVMESlot;
    7067    char fHVFeedbackConfig[MAX_PATH];
    7168    double fDefaultFrequency;
     
    7976    int LastBoard;
    8077    float *DRSFreq;             // DRS sampling frequency [GHz]
     78    bool *ACalib;
     79    double *ACalibTemp;
     80    bool *TCalib;
     81   
    8182    BoardStructure *BStruct;
    8283    state_enum   daq_state;
     
    9798    ~DAQReadout();
    9899
    99     void cmd_exit();      void cmd_help();
    100     void cmd_board();     void cmd_status();
    101     void cmd_led();       void cmd_freq();
    102     void cmd_calib();     void cmd_serial();
    103     void cmd_trigger();   void cmd_delayed();
    104     void cmd_wmode();     void cmd_rmode();
    105     void cmd_mode();      void cmd_read();
    106     void cmd_stop();      void cmd_test();
    107     void cmd_regtest();   void cmd_ramtest();
    108     void cmd_start();     void cmd_take();
    109     void cmd_config();    void cmd_events();
    110     void cmd_disk();      void cmd_uptime();
     100    void cmd_exit();       void cmd_help();
     101    void cmd_board();      void cmd_status();
     102    void cmd_led();        void cmd_freq();
     103    void cmd_acalib();     void cmd_serial();
     104    void cmd_trigger();    void cmd_centre();
     105        void cmd_refclk();
     106    void cmd_wmode();      void cmd_rmode();
     107    void cmd_dmode();      void cmd_read();
     108    void cmd_stop();       void cmd_chiptest();
     109    void cmd_eepromtest(); void cmd_tcalib();
     110    void cmd_regtest();    void cmd_ramtest();
     111    void cmd_start();      void cmd_take();
     112    void cmd_config();     void cmd_events();
     113    void cmd_disk();       void cmd_uptime();
    111114     
    112     void cmd_fmode();     void cmd_faverage();
    113     void cmd_ftarget();   void cmd_fgain();
    114     void cmd_fresponse(); void cmd_fconfig();
     115    void cmd_fmode();      void cmd_faverage();
     116    void cmd_ftarget();    void cmd_fgain();
     117    void cmd_fresponse();  void cmd_fconfig();
    115118
    116119    void CommandControl(char*); 
     
    136139    bool UpdateRunHeader(unsigned int, bool);
    137140    bool WriteEvent();
     141   
     142    void Progress(int);
    138143};
    139144
  • drsdaq/DRS/DRS.cc

    r132 r176  
    1 
    2 /********************************************************************\
    3 
    4   Name:         DRS.cc
    5 
     1/********************************************************************
     2
     3  Name:         DRS.cpp
    64  Created by:   Stefan Ritt, Matthias Schneebeli
    75
    8   Modified by:  Sebastian Commichau (2008)
    9                 Oliver Grimm (Nov 2009)
    10 
    11   Modification: This library works with:
    12                 - Concurrent Technolgies VME single board PC (VP 315)
    13                 - Struck VME controller (SIS 3100) => faster!
    14 
    15   Library functions for DRS board CMC card - requires DRS version 2 or 3
     6  Contents:     Library functions for DRS mezzanine and USB boards
     7
     8  $Id: DRS.cpp 14453 2009-10-22 10:51:29Z ritt $
    169
    1710\********************************************************************/
    1811
    19 #include "DRS.h"
    20 
    21 #define DEBUG 0
    22 
    23 // Minimal FPGA firmware version required for this library
    24 #define REQUIRED_FIRMWARE_VERSION_DRS2 5268
    25 #define REQUIRED_FIRMWARE_VERSION_DRS3 6981
     12#include <stdio.h>
     13#include <math.h>
     14#include <string.h>
     15#include <stdlib.h>
     16#include <time.h>
     17#include <assert.h>
     18#include <algorithm>
     19#include <sys/stat.h>
     20#include "strlcpy.h"
    2621
    2722#ifdef CT_VME
    28 #define MEM_SEGMENT 0XA000 // Size of the memory segment allocated by each DRS board for BLT
    29 #define BLT_TIMEOUT 1000   // Timeout for BLT [msec]
     23  #define MEM_SEGMENT 150000 // Size of the memory segment
    3024#endif
    3125
     26#ifdef _MSC_VER
     27#pragma warning(disable:4996)
     28#   include <windows.h>
     29#   include <direct.h>
     30#else
     31#   include <unistd.h>
     32#   include <sys/time.h>
     33inline void Sleep(useconds_t x)
     34{
     35   usleep(x * 1000);
     36}
     37#endif
     38
     39#ifdef _MSC_VER
     40#include <conio.h>
     41#define drs_kbhit() kbhit()
     42#else
     43#include <sys/ioctl.h>
    3244int drs_kbhit()
    3345{
    34   int n;
    35  
    36   ioctl(0, FIONREAD, &n);
    37   return (n > 0);
    38 }
    39 
    40 static inline int getch() { return getchar(); }
    41 inline void Sleep(useconds_t x) { usleep(x * 1000); }
    42 
    43 // VME addresses
    44 
    45 /* Assuming following DIP Switch settings:
    46    
    47 SW1-1: 1 (off)       Use geographical addressing (1=left, 21=right)
    48 SW1-2: 1 (off)       \
    49 SW1-3: 1 (off)        >  VME_WINSIZE = 8MB, subwindow = 1MB
    50 SW1-4: 0 (on)        /
    51 SW1-5: 0 (on)        Reserved
    52 SW1-6: 0 (on)        Reserved
    53 SW1-7: 0 (on)        Reserved
    54 SW1-8: 0 (on)        \
    55 SW2-1: 0 (on)         |
    56 SW2-2: 0 (on)         |
    57 SW2-3: 0 (on)         |
    58 SW2-4: 0 (on)         >  VME_ADDR_OFFSET = 0
    59 SW2-5: 0 (on)         |
    60 SW2-6: 0 (on)         |
    61 SW2-7: 0 (on)         |
    62 SW2-8: 0 (on)        /
    63 
    64 which gives
    65 VME base address = SlotNo * VME_WINSIZE + VME_ADDR_OFFSET
    66 = SlotNo * 0x80'0000 */
    67 
     46   int n;
     47
     48   ioctl(0, FIONREAD, &n);
     49   return (n > 0);
     50}
     51static inline int getch()
     52{
     53   return getchar();
     54}
     55#endif
     56
     57#include <DRS.h>
     58
     59#ifdef _MSC_VER
     60extern "C" {
     61#endif
     62
     63#include <mxml.h>
     64
     65#ifdef _MSC_VER
     66}
     67#endif
     68
     69/*---- minimal FPGA firmvare version required for this library -----*/
     70const int REQUIRED_FIRMWARE_VERSION_DRS2 = 5268;
     71const int REQUIRED_FIRMWARE_VERSION_DRS3 = 6981;
     72const int REQUIRED_FIRMWARE_VERSION_DRS4 = 13191;
     73
     74/*---- calibration methods to be stored in EEPROMs -----------------*/
     75
     76#define VCALIB_METHOD  1
     77#define TCALIB_METHOD  1
     78
     79/*---- VME addresses -----------------------------------------------*/
     80#if defined(HAVE_VME) || defined(CT_VME)
     81
     82/* assuming following DIP Switch settings:
     83
     84   SW1-1: 1 (off)       use geographical addressing (1=left, 21=right)
     85   SW1-2: 1 (off)       \
     86   SW1-3: 1 (off)        >  VME_WINSIZE = 8MB, subwindow = 1MB
     87   SW1-4: 0 (on)        /
     88   SW1-5: 0 (on)        reserverd
     89   SW1-6: 0 (on)        reserverd
     90   SW1-7: 0 (on)        reserverd
     91   SW1-8: 0 (on)       \
     92                        |
     93   SW2-1: 0 (on)        |
     94   SW2-2: 0 (on)        |
     95   SW2-3: 0 (on)        |
     96   SW2-4: 0 (on)        > VME_ADDR_OFFSET = 0
     97   SW2-5: 0 (on)        |
     98   SW2-6: 0 (on)        |
     99   SW2-7: 0 (on)        |
     100   SW2-8: 0 (on)       /
     101
     102   which gives
     103     VME base address = SlotNo * VME_WINSIZE + VME_ADDR_OFFSET
     104                      = SlotNo * 0x80'0000
     105*/
    68106#define GEVPC_BASE_ADDR           0x00000000
    69107#define GEVPC_WINSIZE               0x800000
     
    71109#define PMC1_OFFSET                  0x00000
    72110#define PMC2_OFFSET                  0x80000
    73 #define PMC_CTRL_OFFSET              0x00000  // All registers 32 bit!
     111#define PMC_CTRL_OFFSET              0x00000    /* all registers 32 bit */
    74112#define PMC_STATUS_OFFSET            0x10000
    75113#define PMC_FIFO_OFFSET              0x20000
    76114#define PMC_RAM_OFFSET               0x40000
    77 
    78 // DRS registers
    79 #define T_CTRL                     1
    80 #define T_STATUS                   2
    81 #define T_RAM                      3
    82 #define T_FIFO                     4
    83 #define REG_CTRL             0x00000    // 32-bit control reg
    84 #define REG_DAC_OFS          0x00004
    85 #define REG_DAC0             0x00004
    86 #define REG_DAC1             0x00006
    87 #define REG_DAC2             0x00008
    88 #define REG_DAC3             0x0000A
    89 #define REG_DAC4             0x0000C
    90 #define REG_DAC5             0x0000E
    91 #define REG_DAC6             0x00010
    92 #define REG_DAC7             0x00012
    93 #define REG_CHANNEL_CONFIG   0x00014
    94 #define REG_CHANNEL_SPAN     0x00016
    95 #define REG_FREQ_SET_HI      0x00018
    96 #define REG_FREQ_SET_LO      0x0001A
    97 #define REG_TRIG_DELAY       0x0001C
    98 #define REG_CALIB_TIMING     0x0001E
    99 #define REG_STATUS           0x00000
    100 #define REG_RDAC_OFS         0x0000A
    101 #define REG_RDAC0            0x00004
    102 #define REG_RDAC1            0x00006
    103 #define REG_RDAC2            0x00008
    104 #define REG_RDAC3            0x0000A
    105 #define REG_RDAC4            0x0000C
    106 #define REG_RDAC5            0x0000E
    107 #define REG_RDAC6            0x00010
    108 #define REG_RDAC7            0x00012
    109 #define REG_EVENTS_IN_FIFO   0x00014
    110 #define REG_EVENT_COUNT      0x00016
    111 #define REG_FREQ1            0x00018
    112 #define REG_FREQ2            0x0001A
    113 #define REG_TEMPERATURE      0x0001C
    114 #define REG_TRIGGER_BUS      0x0001E
    115 #define REG_SERIAL_CMC       0x00020
    116 #define REG_VERSION_FW       0x00022
     115#endif                          // HAVE_VME
     116/*---- USB addresses -----------------------------------------------*/
     117#define USB_TIMEOUT                     1000    // one second
     118#ifdef HAVE_USB
     119#define USB_CTRL_OFFSET                 0x00    /* all registers 32 bit */
     120#define USB_STATUS_OFFSET               0x40
     121#define USB_RAM_OFFSET                  0x80
     122#define USB_CMD_IDENT                      0    // Query identification
     123#define USB_CMD_ADDR                       1    // Address cycle
     124#define USB_CMD_READ                       2    // "VME" read <addr><size>
     125#define USB_CMD_WRITE                      3    // "VME" write <addr><size>
     126#define USB_CMD_READ12                     4    // 12-bit read <LSB><MSB>
     127#define USB_CMD_WRITE12                    5    // 12-bit write <LSB><MSB>
     128
     129#define USB2_CMD_READ                      1
     130#define USB2_CMD_WRITE                     2
     131#define USB2_CTRL_OFFSET             0x00000    /* all registers 32 bit */
     132#define USB2_STATUS_OFFSET           0x10000
     133#define USB2_FIFO_OFFSET             0x20000
     134#define USB2_RAM_OFFSET              0x40000
     135#endif                          // HAVE_USB
     136
     137/*------------------------------------------------------------------*/
    117138
    118139using namespace std;
    119140
    120 
    121 DRS::DRS() : fNumberOfBoards(0),
    122 #ifdef STRUCK_VME
    123              fVMEInterface(0),
     141#ifdef HAVE_USB
     142#define USB2_BUFFER_SIZE (1024*1024+10)
     143unsigned char static *usb2_buffer = NULL;
    124144#endif
    125              First_VME_Slot(0), Last_VME_Slot(7)
    126 { }
    127 
    128 
    129 /*------------------------------------------------------------------*/
    130 
    131 DRS::~DRS() {
    132  
    133   int i;
    134  
    135   for (i = 0; i < fNumberOfBoards; i++) {
    136     delete fBoard[i];
    137   }
    138  
     145
     146/*------------------------------------------------------------------*/
     147
     148DRS::DRS()
     149:  fNumberOfBoards(0)
     150#ifdef HAVE_VME
     151    , fVmeInterface(0)
     152#endif
     153{
     154#ifdef HAVE_USB
     155   MUSB_INTERFACE *usb_interface;
     156#endif
     157
     158  int index = 0, i = 0;
     159  memset(fError, 0, sizeof(fError));
     160
     161#if defined(HAVE_VME) || defined(CT_VME)
     162   unsigned short type, fw, magic, serial, temperature;
     163
     164#ifdef HAVE_VME
     165   mvme_addr_t addr;
     166
     167   if (mvme_open(&fVmeInterface, 0) == MVME_SUCCESS) {
     168      mvme_set_am(fVmeInterface, MVME_AM_A32);
     169      mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);     
     170#endif
    139171#ifdef CT_VME
    140   if (!CloseVME()) printf("VME connection closed\n");
    141   if (!CloseCMEM()) printf("CMEM closed\n");
    142 #endif
    143 
    144 #ifdef STRUCK_VME
    145   if (fVMEInterface != NULL)
    146     if (mvme_close(fVMEInterface));
    147         printf("VME connection closed\n");
    148 
    149 #endif
    150 
    151 }
    152 
    153 
    154 void DRS::InitialScan() {
    155 
    156   int index = 0;
    157  
    158   unsigned short Firmware, Serial, Temperature;
    159 
    160 #ifdef CT_VME
    161  
    162   unsigned int BoardAddress;
     172  unsigned int addr;
    163173   
    164   if (!OpenVME()) {
    165    
    166     printf("VME connection opened\n");
    167     if (!OpenCMEM()) printf("CMEM opened\n");
    168     else return;
    169    
     174  if (OpenVME() == VME_SUCCESS) {   
     175    if (OpenCMEM() != VME_SUCCESS) {
     176      printf("Error with OpenCMEM()\n");
     177      return;
     178    }
    170179    // Set master mapping input information
    171     MasterMap.vmebus_address    = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE; // Init VME board base address (derived from
    172                                                                            // the slot number => geographical addressing)
    173 
    174     MasterMap.window_size       = GEVPC_WINSIZE;                           // VME address window size
     180    MasterMap.window_size       = GEVPC_WINSIZE;
    175181    MasterMap.address_modifier  = VME_A32; 
    176182    MasterMap.options           = 0;
     183#endif
     184      /* check all VME slave slots */
     185      for (index = 2; index <= 10; index++) {     
     186#ifdef CT_VME
     187        MasterMap.vmebus_address        = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE; // VME board base address
     188        MasterMapVME(&MasterMapping[index]);
     189#endif
    177190     
    178     // Check all VME slave slots
    179     for (index = First_VME_Slot; index <= Last_VME_Slot; index++) {
    180        
    181       MasterMap.vmebus_address  = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE; // Update VME board base address
    182    
    183       if (DEBUG)
    184         printf("Checking VME slot %d (base address: 0X%08X)\n",index,MasterMap.vmebus_address);
    185                  
    186       MasterMapVME(&MasterMapping[index]);
    187      
    188       // **************************** Check PMC1 ****************************
    189       BoardAddress  = GEVPC_USER_FPGA;   // UsrFPGA base address
    190       BoardAddress += PMC1_OFFSET;       // PMC1 offset
    191      
    192       // Read firmware
    193       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_VERSION_FW, &Firmware);
    194      
    195       // Read serial number
    196       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_SERIAL_CMC, &Serial);
    197 
    198       // Read temperature register to see if CMC card is present
    199       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_TEMPERATURE, &Temperature);
    200      
    201       if (Firmware > 2400 && Firmware < 20000) {
    202        
    203         if (Temperature == 0XFFFF) {
    204           if (DEBUG)
    205             printf("No CMC board in slot %d\n", index);
    206         } else {
    207           if (DEBUG) {
    208             printf("Found CMC board in slot %d:\n", index);
    209             printf(" Firmware: %d\n",Firmware);
    210             printf(" Board serial nr.: %d\n",Serial);
    211             printf(" Temperature register: %d\n",Temperature);
    212           }
    213          
    214           fBoard[fNumberOfBoards] = new DRSBoard(MasterMapping[index], MasterMap.vmebus_address, BoardAddress, (index-2) << 1);
    215          
    216           if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
    217             fNumberOfBoards++;
    218           else
    219             if (DEBUG)
    220               printf("Error: wrong firmware version: board has %d, required is %d\n",
    221                      fBoard[fNumberOfBoards]->GetFirmwareVersion(),
    222                      fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
    223         }
    224       }
    225 
    226            
    227       // **************************** Check PMC2 ****************************
    228       BoardAddress  = GEVPC_USER_FPGA;   // UsrFPGA base address
    229       BoardAddress += PMC2_OFFSET;       // PMC2 offset
    230      
    231       // Read firmware
    232       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_VERSION_FW, &Firmware);
    233      
    234       // Read serial number
    235       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_SERIAL_CMC, &Serial);
    236      
    237       // Read temperature register to see if CMC card is present
    238       VME_ReadFastUShort(MasterMapping[index], BoardAddress + PMC_STATUS_OFFSET + REG_TEMPERATURE, &Temperature);
    239 
    240       if (Firmware > 2400 && Firmware < 20000) {
    241        
    242         if (Temperature == 0XFFFF) {
    243           printf("No CMC board in slot %d\n", index);
    244         } else {
    245           if (DEBUG) {
    246             printf("Found CMC board in slot %d:\n", index);
    247             printf(" Firmware: %d\n",Firmware);
    248             printf(" Board serial nr.: %d\n",Serial);
    249             printf(" Temperature register: %d\n",Temperature);
    250           }
    251                  
    252           fBoard[fNumberOfBoards] = new DRSBoard(MasterMapping[index], MasterMap.vmebus_address, BoardAddress, ((index-2) << 1) | 1);
    253          
    254           if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
    255             fNumberOfBoards++;
    256           else
    257             if (DEBUG)
    258               printf("Error: wrong firmware version: board has %d, required is %d\n",
    259                      fBoard[fNumberOfBoards]->GetFirmwareVersion(),
    260                      fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
    261         }
    262       }
    263       else
    264         MasterUnMapVME(MasterMapping[index]);
    265     }
    266     if (DEBUG) printf("Found %d DRS boards in VME crate\n", fNumberOfBoards);
    267   }
     191        /* check PMC1 and PMC2 */
     192        for (int pmc=0; pmc<2; pmc++) {
     193
     194#ifdef HAVE_VME
     195         addr = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE;        // VME board base address
     196         addr += GEVPC_USER_FPGA;       // UsrFPGA base address
     197         addr += (pmc == 0) ? PMC1_OFFSET : PMC2_OFFSET;   // offset
     198
     199         mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
     200         i = mvme_read(fVmeInterface, &magic, addr + PMC_STATUS_OFFSET + REG_MAGIC, 2);
    268201#endif
    269 #ifdef STRUCK_VME
    270 
    271   int i = 0;
    272 
    273   mvme_addr_t Address;
    274  
    275   if (mvme_open(&fVMEInterface, 0) == MVME_SUCCESS) {
    276    
    277     printf("VME connection opened\n");
    278 
    279     mvme_set_am(fVMEInterface, MVME_AM_A32);
    280     mvme_set_dmode(fVMEInterface, MVME_DMODE_D16);
    281    
    282     // Check all VME slave slots
    283     for (index = 2; index <= 21; index++) {
    284      
    285       // **************************** Check PMC1 ****************************
    286       Address = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE;  // VME board base address
    287       Address += GEVPC_USER_FPGA;                         // UsrFPGA base address
    288       Address += PMC1_OFFSET;                             // PMC1 offset
    289 
    290       // Read firmware
    291       i = mvme_read(fVMEInterface, &Firmware, Address + PMC_STATUS_OFFSET + REG_VERSION_FW, 2);
    292      
    293       if (i == 2) {
    294        
    295         // Read serial number
    296         mvme_read(fVMEInterface, &Serial, Address + PMC_STATUS_OFFSET + REG_SERIAL_CMC, 2);
    297        
    298         // Read temperature register to see if CMC card is present
    299         mvme_read(fVMEInterface, &Temperature, Address + PMC_STATUS_OFFSET + REG_TEMPERATURE, 2);
    300        
    301         if (Firmware > 2400 && Firmware < 20000) {
    302          
    303           if (Temperature == 0xFFFF) {
    304             printf("No CMC board in slot %d\n", index);
    305           } else {
    306             if (DEBUG) {
    307               printf("Found CMC board in slot %d:\n", index);
    308               printf(" Firmware: %d\n",Firmware);
    309               printf(" Board serial nr.: %d\n",Serial);
    310               printf(" Temperature register: %d\n",Temperature);
    311             }
    312            
    313             fBoard[fNumberOfBoards] = new DRSBoard(fVMEInterface, Address, (index-2) << 1);
    314            
    315             if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
    316               fNumberOfBoards++;
    317             else
    318               if (DEBUG)
    319                 printf("Error: wrong firmware version: board has %d, required is %d\n",
    320                        fBoard[fNumberOfBoards]->GetFirmwareVersion(),
    321                        fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
    322            
    323           }
    324         }
    325       }
    326      
    327       // **************************** Check PMC2 ****************************
    328       Address = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE;  // VME board base address
    329       Address += GEVPC_USER_FPGA;                         // UsrFPGA base address
    330       Address += PMC2_OFFSET;                             // PMC2 offset
    331      
    332       // Read firmware
    333       i = mvme_read(fVMEInterface, &Firmware, Address + PMC_STATUS_OFFSET + REG_VERSION_FW, 2);
    334 
    335       if (i == 2) {
    336 
    337         // Read serial number
    338         mvme_read(fVMEInterface, &Serial, Address + PMC_STATUS_OFFSET + REG_SERIAL_CMC, 2);
    339        
    340         // Read temperature register to see if CMC card is present
    341         mvme_read(fVMEInterface, &Temperature, Address + PMC_STATUS_OFFSET + REG_TEMPERATURE, 2);
    342        
    343         if (Firmware > 2400 && Firmware < 20000) {
    344          
    345           if (Temperature == 0xFFFF) {
    346             printf("No CMC board in slot %d\n", index);
    347           } else {
    348             if (DEBUG) {
    349               printf("Found CMC board in slot %d:\n", index);
    350               printf(" Firmware: %d\n",Firmware);
    351               printf(" Board serial nr.: %d\n",Serial);
    352               printf(" Temperature register: %d\n",Temperature);
    353             }
    354            
    355             fBoard[fNumberOfBoards] = new DRSBoard(fVMEInterface, Address, ((index-2) << 1) | 1);
    356        
    357             if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
    358               fNumberOfBoards++;
    359             else
    360               if (DEBUG)
    361                 printf("Error: wrong firmware version: board has %d, required is %d\n",
    362                        fBoard[fNumberOfBoards]->GetFirmwareVersion(),
    363                        fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
    364           }
    365         }
    366       }
    367     }
    368     if (DEBUG) printf("Found %d DRS boards in VME crate\n", fNumberOfBoards);
    369   }   
     202#ifdef CT_VME
     203         addr = 0;        // VME board base address
     204         addr += GEVPC_USER_FPGA;       // UsrFPGA base address
     205         addr += (pmc == 0) ? PMC1_OFFSET : PMC2_OFFSET;   // offset
     206         ErrorCode = VME_ReadSafeUShort(MasterMapping[index], addr + PMC_STATUS_OFFSET + REG_MAGIC, &magic);
     207         if (ErrorCode == VME_SUCCESS) i = 2;
     208         else i = 0;
    370209#endif
    371   else printf("Error: cannot access VME crate, check driver, power and connection\n");
    372 
    373 }
    374 
    375 
    376 /*------------------------------------------------------------------*/
    377 
     210         if (i == 2) {
     211            if (magic != 0xC0DE) {
     212               printf("Found old firmware, please upgrade immediately!\n");
     213#ifdef HAVE_VME
     214               fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, (index - 2) << 1 | pmc);
     215#endif
    378216#ifdef CT_VME
    379 DRSBoard::DRSBoard(int MasterMapping, unsigned int BaseAddress, unsigned int BoardAddress, int SlotNumber)
    380 #else
    381 DRSBoard::DRSBoard(MVME_INTERFACE *MVME_Interface, mvme_addr_t BaseAddress, int SlotNumber)
     217               fBoard[fNumberOfBoards] = new DRSBoard(MasterMapping[index], MasterMap.vmebus_address, addr, (index-2) << 1 | pmc);       
    382218#endif
    383   :fDAC_COFSA(0)
    384   ,fDAC_COFSB(0)
    385   ,fDAC_DRA(0)
    386   ,fDAC_DSA(0)
    387   ,fDAC_TLEVEL(0)
    388   ,fDAC_ACALIB(0)
    389   ,fDAC_DSB(0)
    390   ,fDAC_DRB(0)
    391   ,fDAC_COFS(0)
    392   ,fDAC_ADCOFS(0)
    393   ,fDAC_CLKOFS(0)
    394   ,fDAC_ROFS_1(0)
    395   ,fDAC_ROFS_2(0)
    396   ,fDAC_INOFS(0)
    397   ,fDAC_BIAS(0)
    398   ,fBaseAddress(BaseAddress)
     219               fNumberOfBoards++;
     220            } else {
     221
     222#ifdef HAVE_VME
     223               /* read board type */
     224               mvme_read(fVmeInterface, &type, addr + PMC_STATUS_OFFSET + REG_BOARD_TYPE, 2);
     225               /* read firmware number */
     226               mvme_read(fVmeInterface, &fw, addr + PMC_STATUS_OFFSET + REG_VERSION_FW, 2);
     227               /* read serial number */
     228               mvme_read(fVmeInterface, &serial, addr + PMC_STATUS_OFFSET + REG_SERIAL_BOARD, 2);
     229               /* read temperature register to see if CMC card is present */
     230               mvme_read(fVmeInterface, &temperature, addr + PMC_STATUS_OFFSET + REG_TEMPERATURE, 2);
     231
     232#endif
    399233#ifdef CT_VME
    400   ,fBoardAddress(BoardAddress)
    401   ,fMasterMapping(MasterMapping)
     234               /* read board type */
     235               VME_ReadFastUShort(MasterMapping[index], addr + PMC_STATUS_OFFSET + REG_BOARD_TYPE, &type);
     236               // Read firmware
     237               VME_ReadFastUShort(MasterMapping[index], addr + PMC_STATUS_OFFSET + REG_VERSION_FW, &fw);
     238               // Read serial number
     239               VME_ReadFastUShort(MasterMapping[index], addr + PMC_STATUS_OFFSET + REG_SERIAL_BOARD, &serial);
     240               // Read temperature register to see if CMC card is present
     241               VME_ReadFastUShort(MasterMapping[index], addr + PMC_STATUS_OFFSET + REG_TEMPERATURE, &temperature);
    402242#endif
    403 #ifdef STRUCK_VME
    404   ,fVMEInterface(MVME_Interface)
     243               type &= 0xFF;
     244               if (type == 2 || type == 3 || type == 4) {    // DRS2 or DRS3 or DRS4
     245                  if (temperature == 0xFFFF) {
     246                     printf("Found VME board in slot %d, fw %d, but no CMC board in %s slot\n", index, fw, (pmc==0) ? "upper" : "lower");
     247                  }
     248                  else {
     249                     printf("Found DRS%d board %2d in %s VME slot %2d, serial #%d, firmware revision %d\n", type, fNumberOfBoards, (pmc==0) ? "upper" : "lower", index, serial, fw);
     250
     251#ifdef HAVE_VME
     252                     fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, (index - 2) << 1 | pmc);
    405253#endif
    406   ,fRequiredFirmwareVersion(0)
    407   ,fFirmwareVersion(0)
    408   ,fChipVersion(0)
    409   ,fBoardVersion(0)
    410   ,fCMCSerialNumber(0)
    411   ,fCtrlBits(0)
    412   ,fNumberOfReadoutChannels(0)
    413   ,fExternalClockFrequency(0)
    414   ,fSlotNumber(SlotNumber)
    415   ,fFrequency(0)
    416   ,fDominoMode(0)
    417   ,fReadoutMode(0)
    418   ,fTriggerEnable(0)
    419   ,fDelayedStart(0)
    420   ,fTriggerCell(0)
    421   ,fMaxChips(0)
    422   ,fResponseCalibration(0)
    423   ,fTimeData(0)
    424   ,fNumberOfTimeData(0)
    425   ,fDebug(0)
    426   ,fTriggerStartBin(0)
    427   ,kRotateWave(0)
    428 {
    429   ConstructBoard();
    430 }
    431 
    432 
    433 /*------------------------------------------------------------------*/
    434 
    435 DRSBoard::~DRSBoard()
    436 {
    437   // Response Calibration
    438   delete fResponseCalibration;
    439  
    440   int i;
    441   // Time Calibration
    442   for (i = 0; i < fNumberOfTimeData; i++) {
    443     delete fTimeData[i];
    444   }
    445   delete[]fTimeData;
    446  
     254#ifdef CT_VME
     255                     fBoard[fNumberOfBoards] = new DRSBoard(MasterMapping[index], MasterMap.vmebus_address, addr, (index-2) << 1 | pmc);         
     256#endif
     257                     if (fBoard[fNumberOfBoards]->HasCorrectFirmware()) fNumberOfBoards++;
     258                     else {
     259                       sprintf(fError, "Wrong firmware version: board has %d, required is %d\n",
     260                                fBoard[fNumberOfBoards]->GetFirmwareVersion(),
     261                                fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
     262                       delete fBoard[fNumberOfBoards];
     263                     }
     264                  } // Temperature check
     265               } // Type check
     266            } // Magic check
     267         }
     268         } // pmc
     269      }
     270   } else printf("Cannot access VME crate, check driver, power and connection\n");
     271#endif                          // HAVE_VME
     272
     273#ifdef HAVE_USB
     274   unsigned char buffer[512];
     275   int found, one_found, usb_slot;
     276
     277   one_found = 0;
     278   usb_slot = 0;
     279   for (index = 0; index < 127; index++) {
     280      found = 0;
     281
     282      /* check for USB-Mezzanine test board */
     283      if (musb_open(&usb_interface, 0x10C4, 0x1175, index, 1, 0) == MUSB_SUCCESS) {
     284
     285         /* check ID */
     286         buffer[0] = USB_CMD_IDENT;
     287         musb_write(usb_interface, 2, buffer, 1, USB_TIMEOUT);
     288
     289         i = musb_read(usb_interface, 1, (char *) buffer, sizeof(buffer), USB_TIMEOUT);
     290         if (strcmp((char *) buffer, "USB_MEZZ2 V1.0") != 0) {
     291            /* no USB-Mezzanine board found */
     292            musb_close(usb_interface);
     293         } else {
     294            usb_interface->usb_type = 1;        // USB 1.1
     295            fBoard[fNumberOfBoards] = new DRSBoard(usb_interface, usb_slot++);
     296            if (fBoard[fNumberOfBoards]->HasCorrectFirmware()) {
     297               fNumberOfBoards++;
     298               found = 1;
     299               one_found = 1;
     300            } else
     301               sprintf(fError, "Wrong firmware version: board has %d, required is %d\n",
     302                       fBoard[fNumberOfBoards]->GetFirmwareVersion(),
     303                       fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
     304         }
     305      }
     306
     307      /* check for DRS4 evaluation board */
     308      if (musb_open(&usb_interface, 0x04B4, 0x1175, index, 1, 0) == MUSB_SUCCESS) {
     309
     310         /* check ID */
     311         struct usb_device_descriptor d;
     312         usb_get_descriptor(usb_interface->dev, USB_DT_DEVICE, 0, &d, sizeof(d));
     313         if (d.bcdDevice != 1) {
     314            /* no DRS evaluation board found */
     315            musb_close(usb_interface);
     316         } else {
     317
     318            /* drain any data from Cy7C68013 FIFO if FPGA startup caused erratic write */
     319            do {
     320               i = musb_read(usb_interface, 8, buffer, sizeof(buffer), 100);
     321               if (i > 0)
     322                  printf("%d bytes stuck in buffer\n", i);
     323            } while (i > 0);
     324
     325            usb_interface->usb_type = 2;        // USB 2.0
     326            fBoard[fNumberOfBoards] = new DRSBoard(usb_interface, usb_slot++);
     327            if (fBoard[fNumberOfBoards]->HasCorrectFirmware()) {
     328               fNumberOfBoards++;
     329               found = 1;
     330               one_found = 1;
     331            } else {
     332               sprintf(fError, "Wrong firmware version: board has %d, required is %d\n",
     333                      fBoard[fNumberOfBoards]->GetFirmwareVersion(),
     334                      fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
     335            }
     336         }
     337      }
     338
     339      if (!found) {
     340         if (!one_found)
     341            printf("USB successfully scanned, but no boards found\n");
     342         break;
     343      }
     344   }
     345#endif                          // HAVE_USB
     346
     347   return;
     348}
     349
     350/*------------------------------------------------------------------*/
     351
     352DRS::~DRS()
     353{
     354   int i;
     355   for (i = 0; i < fNumberOfBoards; i++) {
     356      delete fBoard[i];
     357   }
     358
     359#ifdef HAVE_USB
     360   if (usb2_buffer) {
     361      free(usb2_buffer);
     362      usb2_buffer = NULL;
     363   }
     364#endif
     365
     366#ifdef HAVE_VME
     367   mvme_close(fVmeInterface);
     368#endif
     369
    447370#ifdef CT_VME
    448   if (!FreeSegmentCMEM(CMEM_SegIdentifier) && DEBUG)
    449     printf("Memory segment %d (board #%d) freed\n",CMEM_SegIdentifier,fCMCSerialNumber);
     371  if (CloseVME() != VME_SUCCESS) printf("Error with CloseVME()\n");
     372  if (CloseCMEM()!= VME_SUCCESS) printf("Error with CloseCMEM()\n");
    450373#endif
    451374}
     
    453376/*------------------------------------------------------------------*/
    454377
    455 void DRSBoard::ConstructBoard()
    456 {
    457   fDebug = 0;
    458   fDominoMode = 1;
    459   fReadoutMode = 0;
    460   fTriggerEnable = 0;
    461   fCtrlBits = 0;
    462   fNumberOfReadoutChannels = 10;
    463   fExternalClockFrequency = 1000. / 30.;
    464  
    465   for (int i = 0; i < kNumberOfChips * kNumberOfChannels; i++)
    466     fWaveTransferred[i] = false;
    467  
    468   strcpy(fCalibDirectory, ".");
    469  
     378bool DRS::GetError(char *str, int size)
     379{
     380   if (fError[0])
     381      strlcpy(str, fError, size);
     382
     383   return fError[0] > 0;
     384}
     385
     386/*------------------------------------------------------------------*/
     387
     388#ifdef HAVE_USB
     389DRSBoard::DRSBoard(MUSB_INTERFACE * musb_interface, int usb_slot)
     390:  fDAC_COFSA(0)
     391    , fDAC_COFSB(0)
     392    , fDAC_DRA(0)
     393    , fDAC_DSA(0)
     394    , fDAC_TLEVEL(0)
     395    , fDAC_ACALIB(0)
     396    , fDAC_DSB(0)
     397    , fDAC_DRB(0)
     398    , fDAC_COFS(0)
     399    , fDAC_ADCOFS(0)
     400    , fDAC_CLKOFS(0)
     401    , fDAC_ROFS_1(0)
     402    , fDAC_ROFS_2(0)
     403    , fDAC_INOFS(0)
     404    , fDAC_BIAS(0)
     405    , fDRSType(0)
     406    , fBoardType(0)
     407    , fRequiredFirmwareVersion(0)
     408    , fFirmwareVersion(0)
     409    , fBoardSerialNumber(0)
     410    , fCtrlBits(0)
     411    , fNumberOfReadoutChannels(0)
     412    , fReadoutChannelConfig(0)
     413    , fADCClkPhase(0)
     414    , fADCClkInvert(0)
     415    , fExternalClockFrequency(0)
     416    , fUsbInterface(musb_interface)
     417#ifdef HAVE_VME
     418    , fVmeInterface(0)
     419    , fBaseAddress(0)
     420#endif
     421    , fSlotNumber(usb_slot)
     422    , fFrequency(0)
     423    , fDominoMode(0)
     424    , fDominoActive(0)
     425    , fChannelConfig(0)
     426    , fWSRLoop(0)
     427    , fReadoutMode(0)
     428    , fTriggerEnable1(0)
     429    , fTriggerEnable2(0)
     430    , fTriggerSource(0)
     431    , fTriggerDelay(0)
     432    , fDelayedStart(0)
     433    , fRange(0)
     434    , fCommonMode(0.8)
     435    , fAcalMode(0)
     436    , fAcalVolt(0)
     437    , fTcalFreq(0)
     438    , fTcalLevel(0)
     439    , fTcalPhase(0)
     440    , fMaxChips(0)
     441    , fResponseCalibration(0)
     442    , fCellCalibrationValid(false)
     443    , fCellCalibratedRange(0)
     444    , fTimingCalibrationValid(false)
     445    , fTimeData(0)
     446    , fNumberOfTimeData(0)
     447    , fDebug(0)
     448    , fTriggerStartBin(0)
     449{
     450   if (musb_interface->usb_type == 1)
     451      fTransport = TR_USB;
     452   else
     453      fTransport = TR_USB2;
     454   memset(fStopCell, 0, sizeof(fStopCell));
     455   ConstructBoard();
     456}
     457
     458#endif
     459
     460#ifdef HAVE_VME
     461/*------------------------------------------------------------------*/
     462
     463DRSBoard::DRSBoard(MVME_INTERFACE * mvme_interface, mvme_addr_t base_address, int slot_number)
     464:fDAC_COFSA(0)
     465, fDAC_COFSB(0)
     466, fDAC_DRA(0)
     467, fDAC_DSA(0)
     468, fDAC_TLEVEL(0)
     469, fDAC_ACALIB(0)
     470, fDAC_DSB(0)
     471, fDAC_DRB(0)
     472, fDAC_COFS(0)
     473, fDAC_ADCOFS(0)
     474, fDAC_CLKOFS(0)
     475, fDAC_ROFS_1(0)
     476, fDAC_ROFS_2(0)
     477, fDAC_INOFS(0)
     478, fDAC_BIAS(0)
     479, fDRSType(0)
     480, fBoardType(0)
     481, fRequiredFirmwareVersion(0)
     482, fFirmwareVersion(0)
     483, fBoardSerialNumber(0)
     484, fTransport(TR_VME)
     485, fCtrlBits(0)
     486, fNumberOfReadoutChannels(0)
     487, fReadoutChannelConfig(0)
     488, fADCClkPhase(0)
     489, fADCClkInvert(0)
     490, fExternalClockFrequency(0)
     491#ifdef HAVE_USB
     492, fUsbInterface(0)
     493#endif
     494#ifdef HAVE_VME
     495, fVmeInterface(mvme_interface)
     496, fBaseAddress(base_address)
     497, fSlotNumber(slot_number)
     498#endif
     499, fFrequency(0)
     500, fRefClock(0)
     501, fDominoMode(1)
     502, fDominoActive(1)
     503, fChannelConfig(0)
     504, fWSRLoop(1)
     505, fReadoutMode(0)
     506, fTriggerEnable1(0)
     507, fTriggerEnable2(0)
     508, fTriggerSource(0)
     509, fTriggerDelay(0)
     510, fDelayedStart(0)
     511, fRange(0)
     512, fCommonMode(0.8)
     513, fAcalMode(0)
     514, fAcalVolt(0)
     515, fTcalFreq(0)
     516, fTcalLevel(0)
     517, fTcalPhase(0)
     518, fMaxChips(0)
     519, fResponseCalibration(0)
     520, fTimeData(0)
     521, fNumberOfTimeData(0)
     522, fDebug(0)
     523, fTriggerStartBin(0)
     524{
     525   ConstructBoard();
     526}
     527
     528#endif
     529
    470530#ifdef CT_VME
    471   if (DEBUG) {
    472     printf("Base address:  0X%08X\n",fBaseAddress);
    473     printf("Board address: 0X%08X\n",fBoardAddress);
    474     printf("0X%08X\n",fBaseAddress+fBoardAddress);
    475   }
    476 #endif
    477   ReadSerialNumber();
    478  
    479   // Check for required firmware version
    480   if (!HasCorrectFirmware())
    481     return;
    482  
    483   if (DEBUG)
    484     printf("Board version: %d\n",fBoardVersion);
    485 
    486   if (fBoardVersion == 1) {
    487    
    488     fDAC_COFSA  = 0;
    489     fDAC_COFSB  = 1;
    490     fDAC_DRA    = 2;
    491     fDAC_DSA    = 3;
    492     fDAC_TLEVEL = 4;
    493     fDAC_ACALIB = 5;
    494     fDAC_DSB    = 6;
    495     fDAC_DRB    = 7;
    496    
    497   } else if (fBoardVersion == 2 || fBoardVersion == 3) {
    498    
    499     fDAC_COFS   = 0;
    500     fDAC_DSA    = 1;
    501     fDAC_DSB    = 2;
    502     fDAC_TLEVEL = 3;
    503     fDAC_CLKOFS = 5;
    504     fDAC_ACALIB = 6;
    505     fDAC_ADCOFS = 7;
    506    
    507   } else if (fBoardVersion == 4) {
    508    
    509     fDAC_ROFS_1 = 0;
    510     fDAC_DSA    = 1;
    511     fDAC_DSB    = 2;
    512     fDAC_ROFS_2 = 3;
    513     fDAC_BIAS   = 4;
    514     fDAC_ADCOFS = 7;
    515     fDAC_INOFS  = 5;
    516     fDAC_ACALIB = 6;
    517   }
    518  
    519   // Response Calibration
    520   fResponseCalibration = new ResponseCalibration(this);
    521  
    522   // Time Calibration
    523   fTimeData = new DRSBoard::TimeData *[kNumberOfChips];
    524   fNumberOfTimeData = 0;
    525 
    526 #ifdef CT_VME
     531/*------------------------------------------------------------------*/
     532
     533DRSBoard::DRSBoard(int MasterMapping, unsigned int base_address, unsigned int BoardAddress, int slot_number)
     534:fDAC_COFSA(0)
     535, fDAC_COFSB(0)
     536, fDAC_DRA(0)
     537, fDAC_DSA(0)
     538, fDAC_TLEVEL(0)
     539, fDAC_ACALIB(0)
     540, fDAC_DSB(0)
     541, fDAC_DRB(0)
     542, fDAC_COFS(0)
     543, fDAC_ADCOFS(0)
     544, fDAC_CLKOFS(0)
     545, fDAC_ROFS_1(0)
     546, fDAC_ROFS_2(0)
     547, fDAC_INOFS(0)
     548, fDAC_BIAS(0)
     549, fDRSType(0)
     550, fBoardType(0)
     551, fRequiredFirmwareVersion(0)
     552, fFirmwareVersion(0)
     553, fBoardSerialNumber(0)
     554, fTransport(TR_VME)
     555, fCtrlBits(0)
     556, fNumberOfReadoutChannels(0)
     557, fReadoutChannelConfig(0)
     558, fADCClkPhase(0)
     559, fADCClkInvert(0)
     560, fExternalClockFrequency(0)
     561, fBaseAddress(base_address)
     562, fBoardAddress(BoardAddress)
     563, fMasterMapping(MasterMapping)
     564, fSlotNumber(slot_number)
     565, fFrequency(0)
     566, fRefClock(0)
     567, fDominoMode(1)
     568, fDominoActive(1)
     569, fChannelConfig(0)
     570, fWSRLoop(1)
     571, fReadoutMode(0)
     572, fTriggerEnable1(0)
     573, fTriggerEnable2(0)
     574, fTriggerSource(0)
     575, fTriggerDelay(0)
     576, fDelayedStart(0)
     577, fRange(0)
     578, fCommonMode(0.8)
     579, fAcalMode(0)
     580, fAcalVolt(0)
     581, fTcalFreq(0)
     582, fTcalLevel(0)
     583, fTcalPhase(0)
     584, fMaxChips(0)
     585, fResponseCalibration(0)
     586, fTimeData(0)
     587, fNumberOfTimeData(0)
     588, fDebug(0)
     589, fTriggerStartBin(0)
     590{
    527591  // Allocate contiguous memory for BLT
    528592  AllocateSegmentCMEM(MEM_SEGMENT,&CMEM_SegIdentifier);
    529   if (DEBUG)
    530     printf("Memory segment %d (board #%d) allocated\n",CMEM_SegIdentifier,fCMCSerialNumber);
    531 
    532593  AssignPhysicalSegAddressCMEM(CMEM_SegIdentifier, &PCIAddress);
    533594  AssignVirtualSegAddressCMEM(CMEM_SegIdentifier, &VirtualAddress);
    534   if (DEBUG)
    535     printf("Physical address: 0X%08X, virtual address: 0X%08X\n", (unsigned int)PCIAddress,(unsigned int)VirtualAddress);
     595  ConstructBoard();
     596}
    536597#endif
    537598
    538 }
    539 
    540 /*------------------------------------------------------------------*/
    541 
    542 void DRSBoard::PrintBinary32(unsigned int i) {
    543 
    544   int k;
    545 
    546   for (k=31;k>=0;k--)
    547     if ((i & (1 << k)) !=0) {
    548         if ((k)%8)
    549         printf("1");
    550         else
    551         printf("1 ");
    552     }
    553     else {
    554         if ((k)%8)
    555         printf("0");
    556         else
    557         printf("0 ");
    558     }
    559   printf("\n");
    560 }
    561 
    562 /*------------------------------------------------------------------*/
    563 
    564 long int DRSBoard::GetMicroSeconds() {
    565 
    566   struct tm * timeinfo;
    567   time_t rawtime;
     599/*------------------------------------------------------------------*/
     600
     601DRSBoard::~DRSBoard()
     602{
     603   int i;
     604#ifdef HAVE_USB
     605   if (fTransport == TR_USB || fTransport == TR_USB2)
     606      musb_close(fUsbInterface);
     607#endif
     608
     609   // Response Calibration
     610   delete fResponseCalibration;
     611
     612   // Time Calibration
     613   for (i = 0; i < fNumberOfTimeData; i++) {
     614      delete fTimeData[i];
     615   }
     616   delete[]fTimeData;
     617   
     618#ifdef CT_VME
     619  FreeSegmentCMEM(CMEM_SegIdentifier);
     620#endif
     621
     622}
     623
     624/*------------------------------------------------------------------*/
     625
     626void DRSBoard::ConstructBoard()
     627{
     628   unsigned char buffer[2];
     629
     630   fDebug = 0;
     631   fWSRLoop = 1;
     632   fCtrlBits = 0;
     633
     634   fExternalClockFrequency = 1000. / 30.;
     635   strcpy(fCalibDirectory, ".");
     636
     637   /* check board communication */
     638   if (Read(T_STATUS, buffer, REG_MAGIC, 2) < 0) {
     639      InitFPGA();
     640      if (Read(T_STATUS, buffer, REG_MAGIC, 2) < 0)
     641         return;
     642   }
     643
     644   ReadSerialNumber();
     645
     646   /* check for required firmware version */
     647   if (!HasCorrectFirmware())
     648      return;
     649
     650   /* set correct reference clock */
     651   if (fBoardType == 5)
     652      fRefClock = 60;
     653   else
     654      fRefClock = 33;
     655
     656   /* get mode from hardware */
     657   if (fDRSType == 4) {
     658      fDominoMode = (GetConfigReg() & BIT_CONFIG_DMODE) > 0;
     659   } else {
     660      fDominoMode = (GetCtrlReg() & BIT_DMODE) > 0;
     661   }
     662   fTriggerEnable1 = (GetConfigReg() & BIT_ENABLE_TRIGGER1) > 0;
     663   fTriggerEnable2 = (GetConfigReg() & BIT_ENABLE_TRIGGER2) > 0;
     664   fTriggerSource = ((GetConfigReg() & BIT_TR_SOURCE1) > 0) | (((GetConfigReg() & BIT_TR_SOURCE2) > 0) << 1);
     665   fReadoutMode = (GetConfigReg() & BIT_READOUT_MODE) > 0;
     666   fADCClkInvert = (GetConfigReg() & BIT_ADCCLK_INVERT) > 0;
     667   fDominoActive = (GetConfigReg() & BIT_DACTIVE) > 0;
     668   ReadFrequency(0, &fFrequency);
     669   if (fFrequency < 0.1 || fFrequency > 6)
     670      fFrequency = 1;
     671
     672   /* initialize number of channels */
     673   if (fDRSType == 4) {
     674      if (fBoardType == 6) {
     675         unsigned short d;
     676         Read(T_CTRL, &d, REG_CHANNEL_MODE, 2);
     677         fReadoutChannelConfig = d & 0xFF;
     678         if (d == 7)
     679            fNumberOfReadoutChannels = 9;
     680         else
     681            fNumberOfReadoutChannels = 5;
     682      } else
     683         fNumberOfReadoutChannels = 9;
     684   } else
     685      fNumberOfReadoutChannels = 10;
     686
     687   if (fBoardType == 1) {
     688      fDAC_COFSA = 0;
     689      fDAC_COFSB = 1;
     690      fDAC_DRA = 2;
     691      fDAC_DSA = 3;
     692      fDAC_TLEVEL = 4;
     693      fDAC_ACALIB = 5;
     694      fDAC_DSB = 6;
     695      fDAC_DRB = 7;
     696   } else if (fBoardType == 2 || fBoardType == 3) {
     697      fDAC_COFS = 0;
     698      fDAC_DSA = 1;
     699      fDAC_DSB = 2;
     700      fDAC_TLEVEL = 3;
     701      fDAC_CLKOFS = 5;
     702      fDAC_ACALIB = 6;
     703      fDAC_ADCOFS = 7;
     704   } else if (fBoardType == 4) {
     705      fDAC_ROFS_1 = 0;
     706      fDAC_DSA = 1;
     707      fDAC_DSB = 2;
     708      fDAC_ROFS_2 = 3;
     709      fDAC_BIAS = 4;
     710      fDAC_INOFS = 5;
     711      fDAC_ACALIB = 6;
     712      fDAC_ADCOFS = 7;
     713   } else if (fBoardType == 5) {
     714      fDAC_ROFS_1 = 0;
     715      fDAC_CMOFS = 1;
     716      fDAC_CALN = 2;
     717      fDAC_CALP = 3;
     718      fDAC_BIAS = 4;
     719      fDAC_TLEVEL = 5;
     720      fDAC_ONOFS = 6;
     721   } else if (fBoardType == 6) {
     722      fDAC_ONOFS = 0;
     723      fDAC_CMOFSP = 1;
     724      fDAC_CALN = 2;
     725      fDAC_CALP = 3;
     726      fDAC_CMOFSN = 5;
     727      fDAC_ROFS_1 = 6;
     728      fDAC_BIAS = 7;
     729   }
     730
     731   if (fDRSType == 4) {
     732      ReadCalibration();
     733   } else {
     734      // Response Calibration
     735      fResponseCalibration = new ResponseCalibration(this);
     736
     737      // Time Calibration
     738      fTimeData = new DRSBoard::TimeData *[kNumberOfChipsMax];
     739      fNumberOfTimeData = 0;
     740   }
     741}
     742
     743/*------------------------------------------------------------------*/
     744
     745void DRSBoard::ReadSerialNumber()
     746{
     747   unsigned char buffer[2];
     748   int number;
     749
     750   // check magic number
     751   if (Read(T_STATUS, buffer, REG_MAGIC, 2) < 0) {
     752      printf("Cannot read from board\n");
     753      return;
     754   }
     755
     756   number = (static_cast < int >(buffer[1]) << 8) +buffer[0];
     757   if (number != 0xC0DE) {
     758      printf("Invalid magic number: %04X\n", number);
     759      return;
     760   }
     761   
     762   // read board type
     763   Read(T_STATUS, buffer, REG_BOARD_TYPE, 2);
     764   fDRSType = buffer[0];
     765   fBoardType = buffer[1];
     766
     767   // read firmware version
     768   Read(T_STATUS, buffer, REG_VERSION_FW, 2);
     769   fFirmwareVersion = (static_cast < int >(buffer[1]) << 8) +buffer[0];
     770
     771   // retrieve board serial number
     772   Read(T_STATUS, buffer, REG_SERIAL_BOARD, 2);
     773   number = (static_cast < int >(buffer[1]) << 8) +buffer[0];
     774   fBoardSerialNumber = number;
     775
     776   // determine DRS type and board type for old boards from setial number
     777   if (fBoardType == 0) {
     778      // determine board version from serial number
     779      if (number >= 2000 && number < 5000) {
     780         fBoardType = 6;
     781         fDRSType = 4;
     782      } else if (number >= 1000) {
     783         fBoardType = 4;
     784         fDRSType = 3;
     785      } else if (number >= 100)
     786         fBoardType = 3;
     787      else if (number > 0)
     788         fBoardType = 2;
     789      else {
     790         fBoardType = 3;
     791         fDRSType = 2;
     792         fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS2;
     793      }
     794   }
     795
     796   // set constants according to board type
     797   if (fBoardType == 6)
     798      fNumberOfChips = 4;
     799   else
     800      fNumberOfChips = 2;
     801
     802   if (fDRSType == 4)
     803      fNumberOfChannels = 9;
     804   else
     805      fNumberOfChannels = 10;
     806
     807   // retrieve firmware version
     808   if (fDRSType == 2)
     809      fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS2;
     810   if (fDRSType == 3)
     811      fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS3;
     812   if (fDRSType == 4)
     813      fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS4;
     814
     815}
     816
     817/*------------------------------------------------------------------*/
     818
     819void DRSBoard::ReadCalibration(void)
     820{
     821   unsigned short buf[1024*9*2];
     822   int i, j, chip;
     823
     824   fCellCalibrationValid = false;
     825   fTimingCalibrationValid = false;
     826
     827   memset(fCellOffset,  0, sizeof(fCellOffset));
     828   memset(fCellGain,    0, sizeof(fCellGain));
     829   memset(fCellOffset2, 0, sizeof(fCellOffset2));
     830   memset(fCellT,       0, sizeof(fCellT));
     831
     832   /* read offsets and gain from eeprom */
     833   if (fBoardType == 5) {
     834      ReadEEPROM(0, buf, 16);
     835
     836      /* check voltage calibration method */
     837      if ((buf[2] & 0xFF) == VCALIB_METHOD)
     838         fCellCalibrationValid = true;
     839      else {
     840         fCellCalibratedRange = 0;
     841         return;
     842      }
     843
     844      /* check timing calibration method */
     845      if ((buf[4] & 0xFF) == TCALIB_METHOD)
     846         fTimingCalibrationValid = true;
     847      else {
     848         fTimingCalibratedFrequency = 0;
     849      }
     850
     851      fCellCalibratedRange = ((int) (buf[2] >> 8)) / 100.0; // -50 ... +50 => -0.5 V ... +0.5 V
     852      fTimingCalibratedFrequency = buf[6] / 65525.0 * 6; // 0 ... 65535 => 0 ... 6 GHz
     853
     854      ReadEEPROM(1, buf, 1024*32);
     855      for (i=0 ; i<8 ; i++)
     856         for (j=0 ; j<1024; j++) {
     857            fCellOffset[i][j] = buf[(i*1024+j)*2];
     858            fCellGain[i][j]   = buf[(i*1024+j)*2 + 1]/65535.0*0.4+0.7;
     859         }
     860
     861      ReadEEPROM(2, buf, 1024*5*4);
     862      for (i=0 ; i<1 ; i++)
     863         for (j=0 ; j<1024; j++) {
     864            fCellOffset[i+8][j] = buf[(i*1024+j)*2];
     865            fCellGain[i+8][j]   = buf[(i*1024+j)*2 + 1]/65535.0*0.4+0.7;
     866         }
     867
     868      for (i=0 ; i<4 ; i++)
     869         for (j=0 ; j<1024; j++) {
     870            fCellOffset2[i*2][j]   = buf[2*1024+((i*2)*1024+j)*2];
     871            fCellOffset2[i*2+1][j] = buf[2*1024+((i*2)*1024+j)*2+1];
     872         }
     873
     874   } else if (fBoardType == 6) {
     875      ReadEEPROM(0, buf, 16);
     876
     877      /* check voltage calibration method */
     878      if ((buf[2] & 0xFF) == VCALIB_METHOD)
     879         fCellCalibrationValid = true;
     880      else {
     881         fCellCalibratedRange = 0;
     882         return;
     883      }
     884
     885      /* check timing calibration method */
     886      if ((buf[4] & 0xFF) == TCALIB_METHOD)
     887         fTimingCalibrationValid = true;
     888      else {
     889         fTimingCalibratedFrequency = 0;
     890      }
     891
     892      fCellCalibratedRange = ((int) (buf[2] >> 8)) / 100.0; // -50 ... +50 => -0.5 V ... +0.5 V
     893      fTimingCalibratedFrequency = buf[6] / 65525.0 * 6; // 0 ... 65535 => 0 ... 6 GHz
     894
     895      for (chip=0 ; chip<4 ; chip++) {
     896         ReadEEPROM(1+chip, buf, 1024*32);
     897         for (i=0 ; i<8 ; i++)
     898            for (j=0 ; j<1024; j++) {
     899               fCellOffset[i+chip*9][j] = buf[(i*1024+j)*2];
     900               fCellGain[i+chip*9][j]   = buf[(i*1024+j)*2 + 1]/65535.0*0.4+0.7;
     901            }
     902      }
     903
     904      ReadEEPROM(5, buf, 1024*4*4);
     905      for (chip=0 ; chip<4 ; chip++)
     906         for (j=0 ; j<1024; j++) {
     907            fCellOffset[8+chip*9][j] = buf[j*2+chip*0x0800];
     908            fCellGain[8+chip*9][j]   = buf[j*2+1+chip*0x0800]/65535.0*0.4+0.7;
     909         }
     910
     911      ReadEEPROM(7, buf, 1024*32);
     912      for (i=0 ; i<8 ; i++) {
     913         for (j=0 ; j<1024; j++) {
     914            fCellOffset2[i][j]   = buf[i*0x800 + j*2];
     915            fCellOffset2[i+9][j] = buf[i*0x800 + j*2+1];
     916         }
     917      }
     918
     919      ReadEEPROM(8, buf, 1024*32);
     920      for (i=0 ; i<8 ; i++) {
     921         for (j=0 ; j<1024; j++) {
     922            fCellOffset2[i+18][j] = buf[i*0x800 + j*2];
     923            fCellOffset2[i+27][j] = buf[i*0x800 + j*2+1];
     924         }
     925      }
     926
     927   }
     928   else return;
     929
     930   /* read timing calibration from eeprom */
     931   if (fBoardType == 5) {
     932      if (!fTimingCalibrationValid) {
     933         for (i=0 ; i<1024 ; i++)
     934            fCellT[0][i] = 1/fFrequency*i;
     935      } else {
     936         ReadEEPROM(0, buf, 1024*sizeof(short)*2);
     937         fCellT[0][0] = 0;
     938         for (i=1 ; i<1024; i++)
     939            fCellT[0][i] = fCellT[0][i-1] + buf[i*2+1]/10000.0;
     940      }
     941   } else if (fBoardType == 6) {
     942      if (!fTimingCalibrationValid) {
     943         for (i=0 ; i<1024 ; i++)
     944            for (j=0 ; j<4 ; j++)
     945               fCellT[j][i] = 1/fFrequency*i;
     946      } else {
     947         ReadEEPROM(6, buf, 1024*sizeof(short)*4);
     948         for (j=0 ; j<4 ; j++)
     949            fCellT[j][0] = 0;
     950         for (i=1 ; i<1024; i++) {
     951            fCellT[0][i] = fCellT[0][i-1] + buf[i*2]/10000.0;
     952            fCellT[1][i] = fCellT[1][i-1] + buf[i*2+1]/10000.0;
     953            fCellT[2][i] = fCellT[2][i-1] + buf[i*2+0x800]/10000.0;
     954            fCellT[3][i] = fCellT[3][i-1] + buf[i*2+0x800+1]/10000.0;
     955         }
     956      }
     957   }
     958}
     959
     960/*------------------------------------------------------------------*/
     961
     962bool DRSBoard::HasCorrectFirmware()
     963{
     964   /* check for required firmware version */
     965   return (fFirmwareVersion >= fRequiredFirmwareVersion);
     966}
     967
     968/*------------------------------------------------------------------*/
     969
     970int DRSBoard::InitFPGA(void)
     971{
     972
     973#ifdef HAVE_USB
     974   if (fTransport == TR_USB2) {
     975      unsigned char buffer[1];
     976      int i, status;
     977
     978      /* blink Cy7C68013A LED and issue an FPGA reset */
     979      buffer[0] = 0;            // LED off
     980      musb_write(fUsbInterface, 1, buffer, 1, 100);
     981      Sleep(50);
     982
     983      buffer[0] = 1;            // LED on
     984      musb_write(fUsbInterface, 1, buffer, 1, 100);
     985
     986      /* wait until EEPROM page #0 has been read */
     987      for (i=0 ; i<100 ; i++) {
     988         Read(T_STATUS, &status, REG_STATUS, 4);
     989         if ((status & BIT_SERIAL_BUSY) == 0)
     990            break;
     991         Sleep(10);
     992      }
     993   }
     994#endif
     995
     996   return 1;
     997}
     998
     999int DRSBoard::Write(int type, unsigned int addr, void *data, int size)
     1000{
     1001   // Generic write function
     1002
     1003#ifdef CT_VME
     1004  if (size > MEM_SEGMENT) size = MEM_SEGMENT;
    5681005 
    569   struct timezone tz;
    570   struct timeval actual_time;   // Actual time
     1006  if (type == T_CTRL) addr += PMC_CTRL_OFFSET;
     1007  else if (type == T_STATUS) addr += PMC_STATUS_OFFSET;
     1008  else if (type == T_RAM) addr += PMC_RAM_OFFSET;
     1009  else return 0;
    5711010 
    572   gettimeofday(&actual_time, &tz);
    573  
    574   time(&rawtime);
    575  
    576   timeinfo = gmtime(&rawtime);  // Get UTC (or GMT timezone).
    577  
    578   return (timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec)*1000000 + actual_time.tv_usec;
    579 
    580 }
    581 
    582 
    583 /*------------------------------------------------------------------*/
    584 
    585 int DRSBoard::TestRead(unsigned int n, int type) {
    586 
    587   float delta;
    588   float mbps;
    589 
    590   int errors = 0;
    591  
    592   const int size = 0X10000; // bytes
    593  
    594 #ifdef STRUCK_VME
    595 
    596   long int ts1, ts2;
    597  
    598   unsigned int Address = fBaseAddress + PMC_RAM_OFFSET;
    599 
    600   int read = 0, i;
    601 
    602   unsigned char data[size];
    603    
    604   printf("**************************************************\n");
    605 
    606   if (type==0) {
    607     mvme_set_dmode(fVMEInterface, MVME_DMODE_D32);
    608     mvme_set_blt(fVMEInterface, MVME_BLT_BLT32);
    609     printf(" Mode: VMEbus A32/D32 DMA read [64 kB]\n");
     1011  if (size == 1) {
     1012    ErrorCode = VME_WriteSafeUChar(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned char*>(data)));   
     1013  }
     1014  else if (size == 2) { 
     1015    ErrorCode = VME_WriteSafeUShort(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned short*>(data)));
    6101016  }
    611   else if (type==1) {
    612     mvme_set_dmode(fVMEInterface, MVME_DMODE_D32);
    613     mvme_set_blt(fVMEInterface,MVME_BLT_MBLT64);
    614     printf(" Mode: VMEbus A32/D64 DMA read [64 kB]\n");
     1017  else if (size == 4) { 
     1018    ErrorCode = VME_WriteSafeUInt(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned int*>(data)));
     1019  }
     1020  else { 
     1021    // Copy to contiguous block of memory at VirtualAddress
     1022    memcpy((void *) VirtualAddress, data, size);
     1023
     1024    // Assign fields for BLT and perform BLT
     1025    BLT_List.list_of_items[0].vmebus_address       = fBaseAddress + fBoardAddress + PMC_RAM_OFFSET;
     1026    BLT_List.list_of_items[0].system_iobus_address = PCIAddress;
     1027    BLT_List.list_of_items[0].size_requested       = size;
     1028    BLT_List.list_of_items[0].control_word         = VME_DMA_D64W | VME_A32;
     1029    BLT_List.number_of_items = 1;
     1030    ErrorCode = VME_BlockTransfer(&BLT_List,-1);
    6151031  }
    616   else if (type==2) {
    617     mvme_set_dmode(fVMEInterface, MVME_DMODE_D64);
    618     mvme_set_blt(fVMEInterface, MVME_BLT_2EVME);
    619     printf(" Mode: VMEbus A32/D64 2eVME read [64 kB]\n");
    620   }
    621 
    622   ts1 = GetMicroSeconds();
    623 
    624   for (unsigned int j=0;j<n;j++) {
    625     read = mvme_read(fVMEInterface, static_cast<unsigned char*>(data), Address, size);
    626    
    627     while (read != size) {
    628 
    629       errors++;
    630       printf("Only read %d out of %d, retry with %d: ", read, size, size-read);
    631       i = mvme_read(fVMEInterface, static_cast<unsigned char*>(data) + read/4, Address + read, size - read);
    632       printf("read %d\n", i);
    633       if (i == 0) {
    634         printf("Error reading VME\n");
    635         return read;
    636       }
    637       read += i;
    638     }
    639   }
    640 
    641   ts2 = GetMicroSeconds();
    642 
    643   delta = (ts2 - ts1)/1000000.;
    644 
    645   mbps  = n * read * 1.0/(delta * 1024. * 1024.);
    646 
    647   printf(" %d BLT(s) finished...\n",n);
    648  
    649   if (!errors)
    650     printf(" %d errors... success!\n",errors);
    651   else
    652     printf(" %d errors...\n",errors);
    653  
    654   printf(" Duration: %.3f s\n", delta);
    655   printf(" Rate: %.3f MB/s\n", mbps);
    656 
    657   printf("**************************************************\n");
    658  
    659 #endif
    660 #ifdef CT_VME
    661   tstamp ts1, ts2;
    662 
    663   unsigned int ret;
    664 
    665   ret = ts_open(1, TS_DUMMY);
    666   if (ret)
    667   {
    668     rcc_error_print(stdout, ret);
    669     exit(-2);
    670   }
    671 
    672   printf("**************************************************\n");
    673 
    674   // Assign fields for BLT
    675   BLT_List.number_of_items                       = 1;
    676   BLT_List.list_of_items[0].vmebus_address       = fBaseAddress + fBoardAddress + PMC_RAM_OFFSET;
    677   BLT_List.list_of_items[0].system_iobus_address = PCIAddress;
    678   BLT_List.list_of_items[0].size_requested       = size;
    679 
    680   if (type==0) {
    681     BLT_List.list_of_items[0].control_word         = VME_DMA_D32R | VME_A32;
    682     printf(" Mode: VMEbus A32/D32 DMA read [64 kB]\n");
    683   }
    684   else if (type==1) {
    685     BLT_List.list_of_items[0].control_word         = VME_DMA_D64R | VME_A32;
    686     printf(" Mode: VMEbus A32/D64 DMA read [64 kB]\n");
    687   }
    688   else if (type==2) {
    689     printf("Warning: current interface does not support 2exx transfer mode!\n");
     1032  if (ErrorCode != VME_SUCCESS) {
     1033    VME_ErrorPrint(ErrorCode);
    6901034    return 0;
    6911035  }
    692 
    693   printf("  VMEbus address:   0X%08X\n", BLT_List.list_of_items[0].vmebus_address);   
    694   printf(" Contiguous buffer:\n");
    695   printf("  Physical address: 0X%08X\n", (unsigned int)PCIAddress);
    696   printf("  Virtual address:  0X%08X\n", (unsigned int)VirtualAddress);
    697  
    698   ts_clock(&ts1);
    699 
    700   for (unsigned int i=0;i<n;i++)
    701     // Perfom BLT
    702     if ((ErrorCode = VME_BlockTransfer(&BLT_List,BLT_TIMEOUT)) != VME_SUCCESS) {
    703       VME_ErrorString(ErrorCode,ErrorString);
    704       printf(" VME (BLT): %s\n",ErrorString);
    705      
    706       errors++;
    707       return -1;
    708     }   
    709 
    710   ts_clock(&ts2);
    711   delta = ts_duration(ts1, ts2);
    712   mbps = n * size * 1.0 / (delta * 1024. * 1024.);
    713    
    714   printf(" %d BLT(s) finished...\n",n);
    715 
    716   if (!errors)
    717     printf(" %d errors... success!\n",errors);
    718   else
    719     printf(" %d errors...\n",errors);
    720 
    721   printf(" Duration: %.3f s\n", delta);
    722   printf(" Rate: %.3f MB/s\n", mbps);
    723 
    724   ret = ts_close(TS_DUMMY);
    725   if (ret)
    726   {
    727     rcc_error_print(stdout, ret);
    728     exit(-2);
    729   }
    730 
    731   printf("**************************************************\n");
     1036  else return size;
    7321037#endif
    7331038
    734   return 0;
    735 }
    736 
    737 /*------------------------------------------------------------------*/
    738 
    739 void DRSBoard::ReadSerialNumber()
    740 {
    741   unsigned char buffer[2];
    742   char str[80];
    743   int number;
    744  
    745   Read(T_STATUS, buffer, REG_VERSION_FW, 2);
    746   fFirmwareVersion = (static_cast<int>(buffer[1]) << 8) + buffer[0];
    747  
    748   // Retrieve board serial number
    749   Read(T_STATUS, buffer, REG_SERIAL_CMC, 2);
    750   number = (static_cast<int>(buffer[1]) << 8) + buffer[0];
    751   fCMCSerialNumber = number;
    752  
    753   // Determine DRS chip number from serial number
    754   fChipVersion = number < 1000 ? 2 : 3;
    755  
    756   if (number == 0xFFFF) {
    757     printf("Found new mezzanine board. Please select DRS version (2/[3]): ");
    758     fgets(str, sizeof(str), stdin);
    759     if (atoi(str) == 2)
    760       fChipVersion = 2;
    761     else
    762       fChipVersion = 3;
    763   }
    764  
    765   // Retrieve firmware version
    766   if (fChipVersion == 2)
    767     fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS2;
    768   if (fChipVersion == 3)
    769     fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS3;
    770  
    771  
    772   // Determine board version from serial number
    773   if (number >= 1000)
    774     fBoardVersion = 4;
    775   else if (number >= 100)
    776     fBoardVersion = 3;
    777   else if (number > 0)
    778     fBoardVersion = 2;
    779   else {
    780     fBoardVersion = 4;
    781     fChipVersion = 3;
    782     fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS3;
    783   }
    784  
    785   //Fixme (SCC 03032008): change function FlashEEPROM accordingly!
    786   //fChipVersion = 2;
    787   //fBoardVersion = 3;
    788   //fRequiredFirmwareVersion = REQUIRED_FIRMWARE_VERSION_DRS2;
    789 }
    790 
    791 /*------------------------------------------------------------------*/
    792 
    793 bool DRSBoard::HasCorrectFirmware()
    794 {
    795   // Check firmware version
    796   return (fFirmwareVersion >= fRequiredFirmwareVersion);
    797 }
    798 
    799 /*------------------------------------------------------------------*/
    800 
    801 int DRSBoard::Write(int type, unsigned int addr, void *data, int size)
    802 {
    803 
    804   // Generic write function
    805 
    806 #ifdef CT_VME
    807   if (size > MEM_SEGMENT)
    808     size = MEM_SEGMENT;
    809  
    810   if (type == T_CTRL)
    811     addr += PMC_CTRL_OFFSET;
    812   else if (type == T_STATUS)
    813     addr += PMC_STATUS_OFFSET;
    814   else if (type == T_RAM)
    815     addr += PMC_RAM_OFFSET;
    816  
    817   if (size == 1) {
    818    
    819     VME_WriteSafeUChar(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned char*>(data)));
    820    
    821   } else if (size == 2) {
    822    
    823     VME_WriteSafeUShort(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned short*>(data)));
    824    
    825   } else if (size == 4) {
    826    
    827     VME_WriteSafeUInt(fMasterMapping, fBoardAddress + addr, *(static_cast<unsigned int*>(data)));
    828    
    829   } else {
    830    
    831     // Copy contiguous block of memory starting from VirtualAddress
    832     memcpy((void *) VirtualAddress, data, size);
    833 
    834     // Assign fields for BLT
    835     BLT_List.list_of_items[0].vmebus_address       = fBaseAddress + fBoardAddress + PMC_RAM_OFFSET;
    836     BLT_List.list_of_items[0].system_iobus_address = PCIAddress;
    837     BLT_List.list_of_items[0].size_requested       = MEM_SEGMENT;
    838     BLT_List.list_of_items[0].control_word         = VME_DMA_D64W | VME_A32;
    839    
    840     BLT_List.number_of_items = 1;
    841 
    842     // Perfom BLT
    843     if ((ErrorCode = VME_BlockTransfer(&BLT_List,BLT_TIMEOUT)) != VME_SUCCESS) {
    844       VME_ErrorString(ErrorCode,ErrorString);
    845       printf("VME (BLT): %s\n",ErrorString);
    846     }   
    847   }
    848 
    849 #endif
    850 #ifdef STRUCK_VME 
    851  
    852   unsigned int base_addr;
    853  
    854   base_addr = fBaseAddress;
    855  
    856   if (type == T_CTRL)
    857     base_addr += PMC_CTRL_OFFSET;
    858   else if (type == T_STATUS)
    859     base_addr += PMC_STATUS_OFFSET;
    860   else if (type == T_RAM)
    861     base_addr += PMC_RAM_OFFSET;
    862  
    863   if (size == 1) {
    864     // 8-bit write access
    865     mvme_set_dmode(fVMEInterface, MVME_DMODE_D8);
    866     mvme_write(fVMEInterface, base_addr + addr, static_cast<mvme_locaddr_t*>(data), size);
    867   } else if (size == 2) {
    868     // 16-bit write access
    869     mvme_set_dmode(fVMEInterface, MVME_DMODE_D16);
    870     mvme_write(fVMEInterface, base_addr + addr, static_cast<mvme_locaddr_t*>(data), size);
    871   } else {
    872     mvme_set_dmode(fVMEInterface, MVME_DMODE_D32);
    873    
    874     // As long as no block transfer is supported, do pseudo block transfer
    875     mvme_set_blt(fVMEInterface, MVME_BLT_NONE);
    876    
    877     mvme_write(fVMEInterface, base_addr + addr, static_cast<mvme_locaddr_t*>(data), size);
    878   }
    879  
    880 #endif
    881 
    882   return size;
     1039   if (fTransport == TR_VME) {
     1040
     1041#ifdef HAVE_VME
     1042      unsigned int base_addr;
     1043
     1044      base_addr = fBaseAddress;
     1045
     1046      if (type == T_CTRL)
     1047         base_addr += PMC_CTRL_OFFSET;
     1048      else if (type == T_STATUS)
     1049         base_addr += PMC_STATUS_OFFSET;
     1050      else if (type == T_RAM)
     1051         base_addr += PMC_RAM_OFFSET;
     1052
     1053      if (size == 1) {
     1054         /* 8-bit write access */
     1055         mvme_set_dmode(fVmeInterface, MVME_DMODE_D8);
     1056         mvme_write(fVmeInterface, base_addr + addr, static_cast < mvme_locaddr_t * >(data), size);
     1057      } else if (size == 2) {
     1058         /* 16-bit write access */
     1059         mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
     1060         mvme_write(fVmeInterface, base_addr + addr, static_cast < mvme_locaddr_t * >(data), size);
     1061      } else {
     1062         mvme_set_dmode(fVmeInterface, MVME_DMODE_D32);
     1063
     1064         /* as long as no block transfer is supported, do pseudo block transfer */
     1065         mvme_set_blt(fVmeInterface, MVME_BLT_NONE);
     1066
     1067         mvme_write(fVmeInterface, base_addr + addr, static_cast < mvme_locaddr_t * >(data), size);
     1068      }
     1069
     1070      return size;
     1071#endif                          // HAVE_VME
     1072
     1073   } else if (fTransport == TR_USB) {
     1074#ifdef HAVE_USB
     1075      unsigned char buffer[64], ack;
     1076      unsigned int base_addr;
     1077      int i, j, n;
     1078
     1079      if (type == T_CTRL)
     1080         base_addr = USB_CTRL_OFFSET;
     1081      else if (type == T_STATUS)
     1082         base_addr = USB_STATUS_OFFSET;
     1083      else if (type == T_RAM)
     1084         base_addr = USB_RAM_OFFSET;
     1085      else
     1086         base_addr = 0;
     1087
     1088      if (type != T_RAM) {
     1089
     1090         /*---- register access ----*/
     1091
     1092         if (size == 2) {
     1093            /* word swapping: first 16 bit sit at upper address */
     1094            if ((addr % 4) == 0)
     1095               addr = addr + 2;
     1096            else
     1097               addr = addr - 2;
     1098         }
     1099
     1100         buffer[0] = USB_CMD_WRITE;
     1101         buffer[1] = base_addr + addr;
     1102         buffer[2] = size;
     1103
     1104         for (i = 0; i < size; i++)
     1105            buffer[3 + i] = *((unsigned char *) data + i);
     1106
     1107         /* try 10 times */
     1108         ack = 0;
     1109         for (i = 0; i < 10; i++) {
     1110            n = musb_write(fUsbInterface, 2, buffer, 3 + size, USB_TIMEOUT);
     1111            if (n == 3 + size) {
     1112               for (j = 0; j < 10; j++) {
     1113                  /* wait for acknowledge */
     1114                  n = musb_read(fUsbInterface, 1, &ack, 1, USB_TIMEOUT);
     1115                  if (n == 1 && ack == 1)
     1116                     break;
     1117
     1118                  printf("Redo receive\n");
     1119               }
     1120            }
     1121
     1122            if (ack == 1)
     1123               return size;
     1124
     1125            printf("Redo send\n");
     1126         }
     1127      } else {
     1128
     1129         /*---- RAM access ----*/
     1130
     1131         buffer[0] = USB_CMD_ADDR;
     1132         buffer[1] = base_addr + addr;
     1133         musb_write(fUsbInterface, 2, buffer, 2, USB_TIMEOUT);
     1134
     1135         /* chop buffer into 60-byte packets */
     1136         for (i = 0; i <= (size - 1) / 60; i++) {
     1137            n = size - i * 60;
     1138            if (n > 60)
     1139               n = 60;
     1140            buffer[0] = USB_CMD_WRITE12;
     1141            buffer[1] = n;
     1142
     1143            for (j = 0; j < n; j++)
     1144               buffer[2 + j] = *((unsigned char *) data + j + i * 60);
     1145
     1146            musb_write(fUsbInterface, 2, buffer, 2 + n, USB_TIMEOUT);
     1147
     1148            for (j = 0; j < 10; j++) {
     1149               /* wait for acknowledge */
     1150               n = musb_read(fUsbInterface, 1, &ack, 1, USB_TIMEOUT);
     1151               if (n == 1 && ack == 1)
     1152                  break;
     1153
     1154               printf("Redo receive acknowledge\n");
     1155            }
     1156         }
     1157
     1158         return size;
     1159      }
     1160#endif                          // HAVE_USB
     1161   } else if (fTransport == TR_USB2) {
     1162#ifdef HAVE_USB
     1163      unsigned int base_addr;
     1164      int i;
     1165
     1166      if (usb2_buffer == NULL)
     1167         usb2_buffer = (unsigned char *) malloc(USB2_BUFFER_SIZE);
     1168      assert(usb2_buffer);
     1169
     1170      /* only accept even address and number of bytes */
     1171      assert(addr % 2 == 0);
     1172      assert(size % 2 == 0);
     1173
     1174      /* check for maximum size */
     1175      assert(size <= USB2_BUFFER_SIZE - 10);
     1176
     1177      if (type == T_CTRL)
     1178         base_addr = USB2_CTRL_OFFSET;
     1179      else if (type == T_STATUS)
     1180         base_addr = USB2_STATUS_OFFSET;
     1181      else if (type == T_FIFO)
     1182         base_addr = USB2_FIFO_OFFSET;
     1183      else if (type == T_RAM)
     1184         base_addr = USB2_RAM_OFFSET;
     1185      else
     1186         base_addr = 0;
     1187
     1188      if (type != T_RAM && size == 2) {
     1189         /* word swapping: first 16 bit sit at upper address */
     1190         if ((addr % 4) == 0)
     1191            addr = addr + 2;
     1192         else
     1193            addr = addr - 2;
     1194      }
     1195
     1196      addr += base_addr;
     1197
     1198      usb2_buffer[0] = USB2_CMD_WRITE;
     1199      usb2_buffer[1] = 0;
     1200
     1201      usb2_buffer[2] = (addr >> 0) & 0xFF;
     1202      usb2_buffer[3] = (addr >> 8) & 0xFF;
     1203      usb2_buffer[4] = (addr >> 16) & 0xFF;
     1204      usb2_buffer[5] = (addr >> 24) & 0xFF;
     1205
     1206      usb2_buffer[6] = (size >> 0) & 0xFF;
     1207      usb2_buffer[7] = (size >> 8) & 0xFF;
     1208      usb2_buffer[8] = (size >> 16) & 0xFF;
     1209      usb2_buffer[9] = (size >> 24) & 0xFF;
     1210
     1211      for (i = 0; i < size; i++)
     1212         usb2_buffer[10 + i] = *((unsigned char *) data + i);
     1213
     1214      i = musb_write(fUsbInterface, 4, usb2_buffer, 10 + size, USB_TIMEOUT);
     1215      if (i != 10 + size)
     1216         printf("musb_write error: %d\n", i);
     1217
     1218      return i;
     1219#endif                          // HAVE_USB
     1220   }
     1221
     1222   return 0;
    8831223}
    8841224
     
    8871227int DRSBoard::Read(int type, void *data, unsigned int addr, int size)
    8881228{
    889 
    890   // Generic read function
    891  
     1229   // Generic read function
     1230
    8921231#ifdef CT_VME
    893 
    8941232  if (size > MEM_SEGMENT) size = MEM_SEGMENT;
    8951233
     
    8981236  else if (type == T_RAM) addr += PMC_RAM_OFFSET;
    8991237  else if (type == T_FIFO) addr += PMC_FIFO_OFFSET;
    900 
     1238  else return 0;
     1239 
    9011240  if (size == 1) {
    902     VME_ReadFastUChar(fMasterMapping, fBoardAddress + addr, static_cast<unsigned char*>(data));
     1241    ErrorCode = VME_ReadSafeUChar(fMasterMapping, fBoardAddress + addr, static_cast<unsigned char*>(data));
    9031242  } else if (size == 2) {   
    904     VME_ReadFastUShort(fMasterMapping, fBoardAddress + addr, static_cast<unsigned short*>(data));
     1243    ErrorCode = VME_ReadSafeUShort(fMasterMapping, fBoardAddress + addr, static_cast<unsigned short*>(data));
    9051244  } else if (size == 4) {
    906     VME_ReadFastUInt(fMasterMapping, fBoardAddress + addr, static_cast<unsigned int*>(data));
     1245    ErrorCode = VME_ReadSafeUInt(fMasterMapping, fBoardAddress + addr, static_cast<unsigned int*>(data));
    9071246  } else {
    9081247
    909     // Assign fields for BLT
     1248    // Assign fields and perform BLT
    9101249    BLT_List.list_of_items[0].vmebus_address       = fBaseAddress + fBoardAddress + PMC_RAM_OFFSET;
    9111250    BLT_List.list_of_items[0].system_iobus_address = PCIAddress;
    912     BLT_List.list_of_items[0].size_requested       = MEM_SEGMENT;
     1251    BLT_List.list_of_items[0].size_requested       = size;
    9131252    BLT_List.list_of_items[0].control_word         = VME_DMA_D64R | VME_A32;
    9141253    BLT_List.number_of_items = 1;
    915 
    916     // Perfom BLT
    917     if ((ErrorCode = VME_BlockTransfer(&BLT_List,BLT_TIMEOUT)) != VME_SUCCESS) {
    918       VME_ErrorString(ErrorCode,ErrorString);
    919       printf("VME (BLT): %s\n",ErrorString);
    920     }   
     1254    ErrorCode = VME_BlockTransfer(&BLT_List, -1);
    9211255   
    9221256    // Copy contiguous block of memory starting from VirtualAddress
    923     memcpy(data, (void *) VirtualAddress ,size);
     1257    memcpy(data, (void *) VirtualAddress, size);
    9241258  }
    925   return size;
    926 
    927 #endif
    928 #ifdef STRUCK_VME
    929 
    930   unsigned int base_addr;
    931   int n, i;
    932  
    933   base_addr = fBaseAddress;
    934  
    935   if (type == T_CTRL)
    936     base_addr += PMC_CTRL_OFFSET;
    937   else if (type == T_STATUS)
    938     base_addr += PMC_STATUS_OFFSET;
    939   else if (type == T_RAM)
    940     base_addr += PMC_RAM_OFFSET;
    941   else if (type == T_FIFO)
    942     base_addr += PMC_FIFO_OFFSET;
    943  
    944   mvme_set_dmode(fVMEInterface, MVME_DMODE_D32);
    945  
    946   n = 0;
    947   if (size == 1) {
    948     // 8-bit read access
    949     mvme_set_dmode(fVMEInterface, MVME_DMODE_D8);
    950     n = mvme_read(fVMEInterface, static_cast<mvme_locaddr_t*>(data), base_addr + addr, size);
    951   } else if (size == 2) {
    952     // 16-bit read access
    953     mvme_set_dmode(fVMEInterface, MVME_DMODE_D16);
    954     n = mvme_read(fVMEInterface, static_cast<mvme_locaddr_t*>(data), base_addr + addr, size);
    955   } else {
    956     mvme_set_dmode(fVMEInterface, MVME_DMODE_D32);
    957  
    958     //mvme_set_blt(fVMEInterface, MVME_BLT_NONE); // Pseudo block transfer
    959     mvme_set_blt(fVMEInterface, MVME_BLT_2EVME);  // Use 2eVME if implemented
    960     //mvme_set_blt(fVMEInterface, MVME_BLT_MBLT64);  // Use MBLT64 if implemented
    961     //mvme_set_blt(fVMEInterface, MVME_BLT_2ESST);  // Use 2eSST if implemented
    962 
    963     n = mvme_read(fVMEInterface, static_cast<mvme_locaddr_t*>(data), base_addr + addr, size);
    964     while (n != size) {
    965       printf("Only read %d out of %d, retry with %d: ", n, size, size-n);
    966       i = mvme_read(fVMEInterface, static_cast<mvme_locaddr_t*>(data)+n/4, base_addr + addr + n, size-n);
    967       printf("read %d\n", i);
    968       if (i == 0) {
    969         printf("Error reading VME\n");
    970         return n;
    971       }
    972       n += i;
    973     }
    974    
    975     //for (i = 0; i < size; i += 4)
    976     //mvme_read(fVMEInterface, (mvme_locaddr_t *)((char *)data+i), base_addr + addr+i, 4);
    977   }
    978   return n;
    979 
    980 #endif
    981 
    982 }
    983 
    984 
    985 /*------------------------------------------------------------------*/
    986 
    987 void DRSBoard::SetLED(int state)
    988 {
    989   // Set LED state
    990   if (state)
    991     fCtrlBits |= BIT_LED;
    992   else
    993     fCtrlBits &= ~BIT_LED;
    994   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    995 }
    996 
    997 /*------------------------------------------------------------------*/
    998 
    999 void DRSBoard::SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels)
    1000 {
    1001   // Set number of channels
    1002   unsigned short d;
    1003  
    1004   if (lastChannel < 0 || lastChannel > 10) {
    1005     printf("Invalid number of channels: %d (must be between 0 and 10)\n", lastChannel);
    1006     return;
    1007   }
    1008  
    1009   if (fChipVersion == 2) {
    1010     // Register must contain last channel to read out starting from 9
    1011     d = 9 - lastChannel;
    1012     Write(T_CTRL, REG_CHANNEL_CONFIG, &d, 2);
    1013   } else if (fChipVersion == 3) {
    1014     // Upper four bits of register must contain last channel to read out starting from 9
    1015     d = (firstChannel << 4) | lastChannel;
    1016     Write(T_CTRL, REG_CHANNEL_SPAN, &d, 2);
    1017    
    1018     // Set bit pattern for write shift register
    1019     switch (nConfigChannels ) {
    1020     case  1: d = 0x001; break;
    1021     case  2: d = 0x041; break;
    1022     case  3: d = 0x111; break;
    1023     case  4: d = 0x249; break;
    1024     case  6: d = 0x555; break;
    1025     case 12: d = 0xFFF; break;
    1026     default:
    1027       printf("Invalid channel configuration\n");
    1028     }
    1029     Write(T_CTRL, REG_CHANNEL_CONFIG, &d, 2);
    1030   }
    1031  
    1032   fNumberOfReadoutChannels = lastChannel - firstChannel + 1;
    1033 }
    1034 
    1035 /*------------------------------------------------------------------*/
    1036 
    1037 void DRSBoard::SetNumberOfChannels(int nChannels)
    1038 {
    1039   SetChannelConfig(0, nChannels-1, 12);
    1040 }
    1041 
    1042 /*------------------------------------------------------------------*/
    1043 
    1044 int DRSBoard::SetDAC(unsigned char channel, double value)
    1045 {
    1046   // Set DAC value
    1047   unsigned short d;
    1048  
    1049   // Normalize to 2.5V for 16 bit
    1050   d = static_cast<unsigned short>(value / 2.5 * 0xFFFF + 0.5);
    1051  
    1052   Write(T_CTRL, REG_DAC_OFS + (channel * 2), &d, 2);
    1053   return 1;
    1054 }
    1055 
    1056 /*------------------------------------------------------------------*/
    1057 
    1058 int DRSBoard::ReadDAC(unsigned char channel, double *value)
    1059 {
    1060   // Readback DAC value from control register
    1061   unsigned char buffer[2];
    1062  
    1063   // Map 0->1, 1->0, 2->3, 3->2, etc.
    1064   // ofs = channel + 1 - 2*(channel % 2);
    1065  
    1066   Read(T_CTRL, buffer, REG_DAC_OFS + (channel * 2), 2);
    1067  
    1068   // Normalize to 2.5V for 16 bit
    1069   *value = 2.5 * (buffer[0] + (buffer[1] << 8)) / 0xFFFF;
    1070  
    1071   return 1;
    1072 }
    1073 
    1074 /*------------------------------------------------------------------*/
    1075 
    1076 int DRSBoard::GetRegulationDAC(double *value)
    1077 {
    1078   // Get DAC value from status register (-> freq. regulation)
    1079   unsigned char buffer[2];
    1080  
    1081   if (fBoardVersion == 1)
    1082     Read(T_STATUS, buffer, REG_RDAC3, 2);
    1083   else if (fBoardVersion == 2 || fBoardVersion == 3 || fBoardVersion == 4)
    1084     Read(T_STATUS, buffer, REG_RDAC1, 2);
    1085  
    1086   // Normalize to 2.5V for 16 bit
    1087   *value = 2.5 * (buffer[0] + (buffer[1] << 8)) / 0xFFFF;
    1088  
    1089   return 1;
    1090 }
    1091 
    1092 /*------------------------------------------------------------------*/
    1093 
    1094 int DRSBoard::StartDomino()
    1095 {
    1096   // Start domino sampling
    1097   fCtrlBits |= BIT_START_TRIG;
    1098   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1099   fCtrlBits &= ~BIT_START_TRIG;
    1100  
    1101   return 1;
    1102 }
    1103 
    1104 /*------------------------------------------------------------------*/
    1105 
    1106 int DRSBoard::Reinit()
    1107 {
    1108   // Stop domino sampling
    1109   // Reset readout state machine
    1110   // Reset FIFO counters
    1111   fCtrlBits |= BIT_REINIT_TRIG;
    1112   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1113   fCtrlBits &= ~BIT_REINIT_TRIG;
    1114  
    1115   return 1;
    1116 }
    1117 
    1118 /*------------------------------------------------------------------*/
    1119 
    1120 int DRSBoard::Init()
    1121 {
    1122   // Reinitialize
    1123   fCtrlBits |= BIT_REINIT_TRIG;        // Reset readout state machine
    1124   fCtrlBits &= ~BIT_FREQ_AUTO_ADJ;     // Turn auto. freq regul. off
    1125   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1126   fCtrlBits &= ~BIT_REINIT_TRIG;
    1127  
    1128   // Set default DAC voltages
    1129  
    1130   if (fBoardVersion == 1) {
    1131     // Set max. domino speed
    1132     SetDAC(fDAC_DRA, 2.5);
    1133     SetDAC(fDAC_DSA, 2.5);
    1134     SetDAC(fDAC_DRB, 2.5);
    1135     SetDAC(fDAC_DSB, 2.5);
    1136     // Set readout offset
    1137     SetDAC(fDAC_COFSA, 0.9);
    1138     SetDAC(fDAC_COFSB, 0.9);
    1139     SetDAC(fDAC_TLEVEL, 1.7);
    1140   } else if (fBoardVersion == 2 || fBoardVersion == 3) {
    1141     // Set max. domino speed
    1142     SetDAC(fDAC_DSA, 2.5);
    1143     SetDAC(fDAC_DSB, 2.5);
    1144    
    1145     // Set readout offset
    1146     SetDAC(fDAC_COFS, 0.9);
    1147     SetDAC(fDAC_TLEVEL, 1.7);
    1148     SetDAC(fDAC_ADCOFS, 1.7);  // 1.7 for DC coupling, 1.25 for AC
    1149     SetDAC(fDAC_CLKOFS, 1);
    1150   } else if (fBoardVersion == 4) {
    1151     // Set max. domino speed
    1152     SetDAC(fDAC_DSA, 2.5);
    1153     SetDAC(fDAC_DSB, 2.5);
    1154    
    1155     // Set readout offset
    1156     SetDAC(fDAC_ROFS_1, 1.25);   // LVDS level
    1157     SetDAC(fDAC_ROFS_2, 0.85);   // Linear range  0.1V ... 1.1V
    1158    
    1159     SetDAC(fDAC_ADCOFS, 1.25);
    1160     SetDAC(fDAC_ACALIB, 0.5);
    1161     SetDAC(fDAC_INOFS, 0.6);
    1162     SetDAC(fDAC_BIAS, 0.70);     // A bit above the internal bias of 0.68V
    1163   }
    1164  
    1165   // Set default number of channels per chip
    1166   SetChannelConfig(0, fNumberOfReadoutChannels-1, 12);
    1167   SetDominoMode(fDominoMode);
    1168   SetReadoutMode(fReadoutMode);
    1169   EnableTrigger(fTriggerEnable);
    1170  
    1171   // Disable calibration
    1172   EnableAcal(0, 0);
    1173   SetCalibTiming(0, 0);
    1174  
    1175   return 1;
    1176 }
    1177 
    1178 /*------------------------------------------------------------------*/
    1179 
    1180 int DRSBoard::SetDominoMode(unsigned char mode)
    1181 {
    1182   // Set domino mode
    1183   // mode == 0: single sweep
    1184   // mode == 1: run continously
    1185   //
    1186   fDominoMode = mode;
    1187   if (mode)
    1188     fCtrlBits |= BIT_DMODE;
    1189   else
    1190     fCtrlBits &= ~BIT_DMODE;
    1191  
    1192   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1193  
    1194   return 1;
    1195 }
    1196 
    1197 /*------------------------------------------------------------------*/
    1198 
    1199 int DRSBoard::SetDominoActive(unsigned char mode)
    1200 {
    1201   // Set domino activity
    1202   // mode == 0: stop during readout
    1203   // mode == 1: keep domino wave running
    1204   //
    1205   fDominoMode = mode;
    1206   if (mode)
    1207     fCtrlBits |= BIT_DACTIVE;
    1208   else
    1209     fCtrlBits &= ~BIT_DACTIVE;
    1210  
    1211   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1212  
    1213   return 1;
    1214 }
    1215 
    1216 /*------------------------------------------------------------------*/
    1217 
    1218 int DRSBoard::SetReadoutMode(unsigned char mode)
    1219 {
    1220   // Set readout mode
    1221   // mode == 0: start from first bin
    1222   // mode == 1: start from domino stop
    1223   //
    1224   fReadoutMode = mode;
    1225   if (mode)
    1226     fCtrlBits |= BIT_READOUT_MODE;
    1227   else
    1228     fCtrlBits &= ~BIT_READOUT_MODE;
    1229  
    1230   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1231  
    1232   return 1;
    1233 }
    1234 
    1235 /*------------------------------------------------------------------*/
    1236 
    1237 int DRSBoard::SoftTrigger(void)
    1238 {
    1239   // Send a software trigger
    1240   fCtrlBits |= BIT_SOFT_TRIG;
    1241   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1242   fCtrlBits &= ~BIT_SOFT_TRIG;
    1243  
    1244   return 1;
    1245 }
    1246 
    1247 /*------------------------------------------------------------------*/
    1248 
    1249 int DRSBoard::EnableTrigger(int mode)
    1250 {
    1251   // Enable external trigger
    1252   fTriggerEnable = mode;
    1253   if (mode)
    1254     fCtrlBits |= BIT_ENABLE_TRIGGER;
    1255   else
    1256     fCtrlBits &= ~BIT_ENABLE_TRIGGER;
    1257  
    1258   if (mode == 2)
    1259     fCtrlBits |= BIT_TRIGGER_DELAYED;
    1260   else
    1261     fCtrlBits &= ~BIT_TRIGGER_DELAYED;
    1262  
    1263   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1264  
    1265   return 1;
    1266 }
    1267 
    1268 /*------------------------------------------------------------------*/
    1269 
    1270 int DRSBoard::SetDelayedStart(int flag)
    1271 {
    1272   // Enable external trigger
    1273   fDelayedStart = flag;
    1274   if (flag)
    1275     fCtrlBits |= BIT_DELAYED_START;
    1276   else
    1277     fCtrlBits &= ~BIT_DELAYED_START;
    1278  
    1279   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1280  
    1281   return 1;
    1282 }
    1283 
    1284 /*------------------------------------------------------------------*/
    1285 
    1286 int DRSBoard::IsBusy()
    1287 {
    1288   // Get running flag
    1289   unsigned int status;
    1290  
    1291   Read(T_STATUS, &status, REG_STATUS, 4);
    1292   return (status & BIT_RUNNING) > 0;
    1293 }
    1294 
    1295 /*------------------------------------------------------------------*/
    1296 
    1297 int DRSBoard::IsNewFreq(unsigned char chipIndex)
    1298 {
    1299   unsigned int status;
    1300  
    1301   Read(T_STATUS, &status, REG_STATUS, 4);
    1302   if (chipIndex == 0)
    1303     return (status & BIT_NEW_FREQ1) > 0;
    1304   return (status & BIT_NEW_FREQ2) > 0;
    1305 }
    1306 
    1307 /*------------------------------------------------------------------*/
    1308 
    1309 int DRSBoard::ReadFrequency(unsigned char chipIndex, double *f)
    1310 {
    1311   // Read domino sampling frequency
    1312   unsigned char buffer[2];
    1313  
    1314   if (chipIndex == 0)
    1315     Read(T_STATUS, buffer, REG_FREQ1, 2);
    1316   else
    1317     Read(T_STATUS, buffer, REG_FREQ2, 2);
    1318  
    1319   *f = (static_cast<unsigned int>(buffer[1]) << 8) + buffer[0];
    1320  
    1321   // Convert counts to frequency
    1322   if (*f != 0)
    1323     *f = 1024 * 200 * (32.768E6 * 4) / (*f) / 1E9;
    1324  
    1325   return 1;
    1326 }
    1327 
    1328 /*------------------------------------------------------------------*/
    1329 
    1330 double DRSBoard::VoltToFreq(double volt)
    1331 {
    1332   if (fChipVersion == 3) {
    1333     if (volt <= 1.2001)
    1334       return (volt - 0.6) / 0.2;
    1335     else
    1336       return 0.73/0.28 + sqrt((0.73/0.28)*(0.73/0.28)-2.2/0.14+volt/0.14);
    1337   } else
    1338     return (volt - 0.5) / 0.2;
    1339 }
    1340 
    1341 /*------------------------------------------------------------------*/
    1342 
    1343 double DRSBoard::FreqToVolt(double freq)
    1344 {
    1345   if (fChipVersion == 3) {
    1346     if (freq <= 3)
    1347       return 0.6 + 0.2 * freq;
    1348     else
    1349       return 2.2 - 0.73 * freq + 0.14 * freq * freq;
    1350   } else
    1351     return 0.55 + 0.25 * freq;
    1352 }
    1353 
    1354 /*------------------------------------------------------------------*/
    1355 
    1356 int DRSBoard::SetFrequency(double demand)
    1357 {
    1358   // Set domino sampling frequency
    1359   double freq, voltage, delta_voltage;
    1360   unsigned short target;
    1361   int i, index, timeout;
    1362   int dominoModeSave = fDominoMode;
    1363   int triggerEnableSave = fTriggerEnable;
    1364  
    1365   SetDominoMode(1);
    1366   EnableTrigger(0);
    1367   EnableAcal(0, 0);
    1368  
    1369   fFrequency = demand;
    1370  
    1371   // Turn automatic adjustment off
    1372   fCtrlBits &= ~BIT_FREQ_AUTO_ADJ;
    1373  
    1374   // Disable external trigger
    1375   fCtrlBits &= ~BIT_ENABLE_TRIGGER;
    1376  
    1377   // Set start pulse length for future DRSBoard_domino_start()
    1378   if (fChipVersion == 2) {
    1379     if (demand < 0.8)
    1380       fCtrlBits |= BIT_LONG_START_PULSE;
    1381     else
    1382       fCtrlBits &= ~BIT_LONG_START_PULSE;
    1383    
    1384     Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1385   }
    1386  
    1387   // Stop any running domino wave
    1388   Reinit();
    1389  
    1390   // Estimate DAC setting
    1391   voltage = FreqToVolt(demand);
    1392  
    1393   SetDAC(fDAC_DSA, voltage);
    1394   SetDAC(fDAC_DSB, voltage);
    1395  
    1396   // Wait until new DAC value has settled
    1397   Sleep(10);
    1398  
    1399   // Restart domino wave
    1400   StartDomino();
    1401  
    1402   target = static_cast<unsigned short>(1024 * 200 * (32.768E6 * 4) / demand / 1E9);
    1403  
    1404   // Iterate over both DRS chips
    1405   for (index = 0; index < 2; index++) {
    1406    
    1407     // Starting voltage
    1408     voltage = FreqToVolt(demand);
    1409    
    1410     for (i = 0; i < 100; i++) {
    1411      
    1412       // Wait until measurement finished
    1413       for (timeout = 0; timeout < 1000; timeout++)
    1414         if (IsNewFreq(index))
    1415           break;
    1416      
    1417       freq = 0;
    1418       if (timeout == 1000)
    1419         break;
    1420      
    1421       ReadFrequency(index, &freq);
    1422      
    1423       delta_voltage = FreqToVolt(demand) - FreqToVolt(freq);
    1424      
    1425       if (fDebug) {
    1426         if (fabs(freq - demand) < 0.001)
    1427           printf("CHIP #%d, iter%3d: %1.5lf(%05d) %7.5lf\n", index, i, voltage,
    1428                  static_cast<int>(voltage / 2.5 * 65535 + 0.5), freq);
    1429         else
    1430           printf("CHIP #%d, iter%3d: %1.5lf(%05d) %7.5lf %+5d\n", index, i, voltage,
    1431                  static_cast<int>(voltage / 2.5 * 65535 + 0.5), freq,
    1432                  static_cast<int>(delta_voltage / 2.5 * 65535 + 0.5));
    1433       }
    1434      
    1435       if (fabs(freq - demand) < 0.001)
    1436         break;
    1437      
    1438       voltage += delta_voltage;
    1439       if (voltage > 2.5)
    1440         voltage = 2.5;
    1441       if (voltage < 0)
    1442         voltage = 0;
    1443      
    1444       if (freq == 0)
    1445         break;
    1446      
    1447       if (index == 0)
    1448         SetDAC(fDAC_DSA, voltage);
    1449       else
    1450         SetDAC(fDAC_DSB, voltage);
    1451      
    1452       Sleep(10);
    1453     }
    1454     if (i == 100 || freq == 0 || timeout == 1000) {
    1455       printf("Board %d: could not set frequency of CHIP #%d to %1.3f GHz\n", GetCMCSerialNumber(), index, demand);
    1456       return 0;
    1457     }
    1458   }
    1459  
    1460   SetDominoMode(dominoModeSave);
    1461   EnableTrigger(triggerEnableSave);
    1462   return 1;
    1463 }
    1464 
    1465 /*------------------------------------------------------------------*/
    1466 
    1467 int DRSBoard::RegulateFrequency(double demand)
    1468 {
    1469   // Set frequency regulation
    1470   unsigned short target, target_hi, target_lo;
    1471  
    1472   if (demand < 0.42 || demand > 5.2)
    1473     return 0;
    1474  
    1475   fFrequency = demand;
    1476  
    1477   // First iterate DAC value from host
    1478   if (!SetFrequency(demand))
    1479     return 0;
    1480  
    1481   // Convert frequency in GHz into counts for 200 cycles
    1482   target = static_cast<unsigned short>(1024 * 200 * (32.768E6 * 4) / demand / 1E9);
    1483   target_hi = target + 6;
    1484   target_lo = target - 6;
    1485   Write(T_CTRL, REG_FREQ_SET_HI, &target_hi, 2);
    1486   Write(T_CTRL, REG_FREQ_SET_LO, &target_lo, 2);
    1487  
    1488   // Turn on regulation
    1489   fCtrlBits |= BIT_FREQ_AUTO_ADJ;
    1490   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    1491  
    1492   // Optional monitoring code ...
    1493 #if 0
    1494   do {
    1495     double freq;
    1496     unsigned short dac, cnt;
    1497    
    1498     ReadFrequency(0, &freq);
    1499    
    1500     if (fBoardVersion == 1)
    1501       Read(T_STATUS, &dac, REG_RDAC3, 2);
    1502     else if (fBoardVersion == 2 || fBoardVersion == 3)
    1503       Read(T_STATUS, &dac, REG_RDAC1, 2);
    1504    
    1505     Read(T_STATUS, &cnt, REG_FREQ1, 2);
    1506    
    1507     if (cnt < 65535)
    1508       printf("%5d %5d %5d %1.5lf\n", dac, target, cnt, freq);
    1509    
    1510     Sleep(500);
    1511   } while (1);
    1512 #endif
    1513  
    1514   return 1;
    1515 }
    1516 
    1517 /*------------------------------------------------------------------*/
    1518 
    1519 void DRSBoard::RegisterTest()
    1520 {
    1521   // Register test
    1522 #define N_REG 8
    1523  
    1524   int i, n, n_err;
    1525   unsigned int buffer[N_REG], ret[N_REG];
    1526  
    1527   printf("**************************************************\n");
    1528 
    1529   n_err = 0;
    1530   for (n = 0; n < 100; n++) {
    1531     for (i = 0; i < N_REG; i++)
    1532       buffer[i] = (rand() << 16) | rand();
    1533     Write(T_CTRL, 0, buffer, sizeof(buffer));
    1534    
    1535     memset(ret, 0, sizeof(ret));
    1536     i = Read(T_CTRL, ret, 0, sizeof(ret));
    1537    
    1538     while (i != sizeof(ret)) {
    1539       printf(" Read error!\n");
    1540       return;
    1541     }
    1542    
    1543     for (i = 0; i < N_REG; i++)
    1544       if (buffer[i] != ret[i]) {
    1545         n_err++;
    1546         printf(" Error Reg.%d: %08X - %08X\n", i, buffer[i], ret[i]);
    1547       }
    1548       else
    1549         printf(" OK   : %08X\n", buffer[i]);
    1550   }
    1551  
    1552   printf(" Register test: %d errors\n", n_err);
    1553   printf("**************************************************\n");
    1554 }
    1555 
    1556 /*------------------------------------------------------------------*/
    1557 
    1558 int DRSBoard::RAMTest(int flag)
    1559 {
    1560 #define N_DWORDS (40*1024/4)
    1561  
    1562   // RAM test
    1563   int i, j, n, l=0;
    1564   unsigned int buffer[N_DWORDS], ret[N_DWORDS];
    1565   time_t now;
    1566  
    1567   // Integrity test
    1568   printf("**************************************************\n");
    1569   printf(" Integrity:\n");
    1570   printf("  Buffer size (bytes): %d (%1.1lfk)\n", static_cast<int>(sizeof(ret)), sizeof(ret) / 1024.0);
    1571   if (flag & 1) {
    1572     for (i = 0; i < N_DWORDS; i++)
    1573       buffer[i] = (rand() | rand() << 16) & 0x00FFFFFF;      // Random 24-bit values
    1574     //buffer[i] = i;
    1575    
    1576     // Reset FIFO
    1577     Reinit();
    1578    
    1579     Write(T_RAM, 0, buffer, sizeof(buffer));
    1580     memset(ret, 0, sizeof(ret));
    1581    
    1582     Read(T_FIFO, ret, 0, sizeof(ret));
    1583     Reinit();
    1584    
    1585     for (i = n = 0; i < N_DWORDS; i++) {
    1586       if (buffer[i] != ret[i])
    1587         n++;
    1588     }
    1589    
    1590     printf("  %d errors\n", n);
    1591   }
    1592  
    1593   // Speed test
    1594   if (flag & 2) {
    1595 
    1596     printf(" Speed:\n");
    1597 
    1598     // Read continously to determine speed
    1599     time(&now);
    1600     while (now == time(NULL));
    1601     time(&now);
    1602     i = n = 0;
    1603     do {
    1604       memset(ret, 0, sizeof(ret));
    1605      
    1606       for (j = 0; j < 10; j++) {
    1607         Read(T_RAM, ret, 0, sizeof(ret));
    1608         i += sizeof(ret);
    1609       }
    1610      
    1611       if (flag & 1) {
    1612         for (j = 0; j < N_DWORDS; j++)
    1613           if (buffer[j] != ret[j])
    1614             n++;
    1615       }
    1616      
    1617       if (now != time(NULL)) {
    1618         if (flag & 1)
    1619           printf("  %d read/s, %1.2lf MB/s, %d errors\n", static_cast<int>(i / sizeof(ret)), i / 1024.0 / 1024.0,
    1620                  n);
    1621         else
    1622           printf("  %d read/s, %1.2lf MB/s\n", static_cast<int>(i / sizeof(ret)), i / 1024.0 / 1024.0);
    1623         time(&now);
    1624         i = 0;   l++;
    1625       }
    1626     } while (l<5);
    1627   }
    1628  
    1629   printf("**************************************************\n");
    1630 
    1631   return 0;
    1632 }
    1633 
    1634 /*------------------------------------------------------------------*/
    1635 
    1636 void DRSBoard::SetVoltageOffset(double offset1, double offset2)
    1637 {
    1638   if (fChipVersion == 3) {
    1639     SetDAC(fDAC_ROFS_1, 0.95 - offset1);
    1640     SetDAC(fDAC_ROFS_2, 0.95 - offset2);
    1641   } else if (fChipVersion == 2)
    1642     SetDAC(fDAC_COFS, 0.9 - offset1);
    1643 }
    1644 
    1645 /*------------------------------------------------------------------*/
    1646 
    1647 int DRSBoard::SetExternalClockFrequency(double frequencyMHz)
    1648 {
    1649   // Set the frequency of the external clock
    1650   fExternalClockFrequency = frequencyMHz;
    1651   return 0;
    1652 }
    1653 
    1654 /*------------------------------------------------------------------*/
    1655 
    1656 double DRSBoard::GetExternalClockFrequency()
    1657 {
    1658   // Return the frequency of the external clock
    1659   return fExternalClockFrequency;
    1660 }
    1661 
    1662 /*------------------------------------------------------------------*/
    1663 
    1664 int DRSBoard::TransferWaves(int numberOfChannels)
    1665 {
    1666   return TransferWaves(fWaveforms,numberOfChannels);
    1667 }
    1668 
    1669 /*------------------------------------------------------------------*/
    1670 
    1671 int DRSBoard::TransferWaves(unsigned char *p, int numberOfChannels)
    1672 {
    1673   return TransferWaves(p, 0, numberOfChannels-1);
    1674 }
    1675 
    1676 /*------------------------------------------------------------------*/
    1677 
    1678 int DRSBoard::TransferWaves(int firstChannel, int lastChannel)
    1679 {
    1680   return TransferWaves(fWaveforms, firstChannel, lastChannel);
    1681 }
    1682 
    1683 /*------------------------------------------------------------------*/
    1684 
    1685 int DRSBoard::TransferWaves(unsigned char *p, int firstChannel, int lastChannel)
    1686 {
    1687 
    1688   // Transfer all waveforms at once
    1689   int i, n, offset, n_requested;
    1690  
    1691   if (lastChannel < 0 || lastChannel > kNumberOfChips*kNumberOfChannels) {
    1692     printf("Error: Invalid channel index %d\n", lastChannel);
     1259
     1260  if (ErrorCode != VME_SUCCESS) {
     1261    VME_ErrorPrint(ErrorCode);
    16931262    return 0;
    16941263  }
     1264  else return size;
     1265#endif
     1266
     1267   if (fTransport == TR_VME) {
     1268
     1269#ifdef HAVE_VME
     1270      unsigned int base_addr;
     1271      int n, i;
     1272
     1273      base_addr = fBaseAddress;
     1274
     1275      if (type == T_CTRL)
     1276         base_addr += PMC_CTRL_OFFSET;
     1277      else if (type == T_STATUS)
     1278         base_addr += PMC_STATUS_OFFSET;
     1279      else if (type == T_RAM)
     1280         base_addr += PMC_RAM_OFFSET;
     1281      else if (type == T_FIFO)
     1282         base_addr += PMC_FIFO_OFFSET;
     1283
     1284      mvme_set_dmode(fVmeInterface, MVME_DMODE_D32);
     1285
     1286      n = 0;
     1287      if (size == 1) {
     1288         /* 8-bit read access */
     1289         mvme_set_dmode(fVmeInterface, MVME_DMODE_D8);
     1290         n = mvme_read(fVmeInterface, static_cast < mvme_locaddr_t * >(data), base_addr + addr, size);
     1291      } else if (size == 2) {
     1292         /* 16-bit read access */
     1293         mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
     1294         n = mvme_read(fVmeInterface, static_cast < mvme_locaddr_t * >(data), base_addr + addr, size);
     1295      } else {
     1296         mvme_set_dmode(fVmeInterface, MVME_DMODE_D32);
     1297
     1298         //mvme_set_blt(fVmeInterface, MVME_BLT_NONE); // pseudo block transfer
     1299         mvme_set_blt(fVmeInterface, MVME_BLT_2EVME);   // 2eVME if implemented
     1300         n = mvme_read(fVmeInterface, static_cast < mvme_locaddr_t * >(data), base_addr + addr, size);
     1301         while (n != size) {
     1302            printf("Only read %d out of %d, retry with %d: ", n, size, size - n);
     1303            i = mvme_read(fVmeInterface, static_cast < mvme_locaddr_t * >(data) + n / 4, base_addr + addr + n,
     1304                          size - n);
     1305            printf("read %d\n", i);
     1306            if (i == 0) {
     1307               printf("Error reading VME\n");
     1308               return n;
     1309            }
     1310            n += i;
     1311         }
     1312
     1313         //for (i = 0; i < size; i += 4)
     1314         //   mvme_read(fVmeInterface, (mvme_locaddr_t *)((char *)data+i), base_addr + addr+i, 4);
     1315      }
     1316      return n;
     1317
     1318#endif                          // HAVE_VME
     1319   } else if (fTransport == TR_USB) {
     1320#ifdef HAVE_USB
     1321      unsigned char buffer[64];
     1322      unsigned int base_addr;
     1323      int i, j, ret, n;
     1324
     1325      if (type == T_CTRL)
     1326         base_addr = USB_CTRL_OFFSET;
     1327      else if (type == T_STATUS)
     1328         base_addr = USB_STATUS_OFFSET;
     1329      else if (type == T_RAM)
     1330         base_addr = USB_RAM_OFFSET;
     1331      else
     1332         assert(0);             // FIFO not implemented
     1333
     1334      if (type != T_RAM) {
     1335
     1336         /*---- register access ----*/
     1337
     1338         if (size == 2) {
     1339            /* word swapping: first 16 bit sit at uppder address */
     1340            if ((addr % 4) == 0)
     1341               addr = addr + 2;
     1342            else
     1343               addr = addr - 2;
     1344         }
     1345
     1346         buffer[0] = USB_CMD_READ;
     1347         buffer[1] = base_addr + addr;
     1348         buffer[2] = size;
     1349
     1350         musb_write(fUsbInterface, 2, buffer, 2 + size, USB_TIMEOUT);
     1351         i = musb_read(fUsbInterface, 1, data, size, USB_TIMEOUT);
     1352
     1353         if (i != size)
     1354            return 0;
     1355
     1356         return size;
     1357      } else {
     1358
     1359         /*---- RAM access ----*/
     1360
     1361         /* in RAM mode, only the 2048-byte page can be selected */
     1362         buffer[0] = USB_CMD_ADDR;
     1363         buffer[1] = base_addr + (addr >> 11);
     1364         musb_write(fUsbInterface, 2, buffer, 2, USB_TIMEOUT);
     1365
     1366         /* receive data in 60-byte packets */
     1367         for (i = 0; i <= (size - 1) / 60; i++) {
     1368            n = size - i * 60;
     1369            if (n > 60)
     1370               n = 60;
     1371            buffer[0] = USB_CMD_READ12;
     1372            buffer[1] = n;
     1373            musb_write(fUsbInterface, 2, buffer, 2, USB_TIMEOUT);
     1374
     1375            ret = musb_read(fUsbInterface, 1, buffer, n, USB_TIMEOUT);
     1376
     1377            if (ret != n) {
     1378               /* try again */
     1379               ret = musb_read(fUsbInterface, 1, buffer, n, USB_TIMEOUT);
     1380               if (ret != n)
     1381                  return 0;
     1382            }
     1383
     1384            for (j = 0; j < ret; j++)
     1385               *((unsigned char *) data + j + i * 60) = buffer[j];
     1386         }
     1387
     1388         return size;
     1389      }
     1390#endif                          // HAVE_USB
     1391   } else if (fTransport == TR_USB2) {
     1392#ifdef HAVE_USB
     1393      unsigned char buffer[10];
     1394      unsigned int base_addr;
     1395      int i;
     1396
     1397      /* only accept even address and number of bytes */
     1398      assert(addr % 2 == 0);
     1399      assert(size % 2 == 0);
     1400
     1401      /* check for maximum size */
     1402      assert(size <= USB2_BUFFER_SIZE - 10);
     1403
     1404      if (type == T_CTRL)
     1405         base_addr = USB2_CTRL_OFFSET;
     1406      else if (type == T_STATUS)
     1407         base_addr = USB2_STATUS_OFFSET;
     1408      else if (type == T_FIFO)
     1409         base_addr = USB2_FIFO_OFFSET;
     1410      else if (type == T_RAM)
     1411         base_addr = USB2_RAM_OFFSET;
     1412      else
     1413         base_addr = 0;
     1414
     1415      if (type != T_RAM && size == 2) {
     1416         /* word swapping: first 16 bit sit at upper address */
     1417         if ((addr % 4) == 0)
     1418            addr = addr + 2;
     1419         else
     1420            addr = addr - 2;
     1421      }
     1422
     1423      addr += base_addr;
     1424
     1425      buffer[0] = USB2_CMD_READ;
     1426      buffer[1] = 0;
     1427
     1428      buffer[2] = (addr >> 0) & 0xFF;
     1429      buffer[3] = (addr >> 8) & 0xFF;
     1430      buffer[4] = (addr >> 16) & 0xFF;
     1431      buffer[5] = (addr >> 24) & 0xFF;
     1432
     1433      buffer[6] = (size >> 0) & 0xFF;
     1434      buffer[7] = (size >> 8) & 0xFF;
     1435      buffer[8] = (size >> 16) & 0xFF;
     1436      buffer[9] = (size >> 24) & 0xFF;
     1437
     1438      i = musb_write(fUsbInterface, 4, buffer, 10, USB_TIMEOUT);
     1439      if (i != 10)
     1440         printf("musb_read error %d\n", i);
     1441
     1442      i = musb_read(fUsbInterface, 8, data, size, USB_TIMEOUT);
     1443      return i;
     1444#endif                          // HAVE_USB
     1445   }
     1446
     1447   return 0;
     1448}
     1449
     1450/*------------------------------------------------------------------*/
     1451
     1452void DRSBoard::SetLED(int state)
     1453{
     1454   // Set LED state
     1455   if (state)
     1456      fCtrlBits |= BIT_LED;
     1457   else
     1458      fCtrlBits &= ~BIT_LED;
     1459   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1460}
     1461
     1462/*------------------------------------------------------------------*/
     1463
     1464void DRSBoard::SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels)
     1465{
     1466   // Set number of channels
     1467   unsigned short d;
     1468
     1469   if (lastChannel < 0 || lastChannel > 10) {
     1470      printf("Invalid number of channels: %d (must be between 0 and 10)\n", lastChannel);
     1471      return;
     1472   }
     1473
     1474   if (fDRSType == 2) {
     1475      // register must contain last channel to read out starting from 9
     1476      d = 9 - lastChannel;
     1477      Write(T_CTRL, REG_CHANNEL_CONFIG, &d, 2);
     1478   } else if (fDRSType == 3) {
     1479      // upper four bits of register must contain last channel to read out starting from 9
     1480      d = (firstChannel << 4) | lastChannel;
     1481      Write(T_CTRL, REG_CHANNEL_MODE, &d, 2);
     1482
     1483      // set bit pattern for write shift register
     1484      switch (nConfigChannels) {
     1485      case 1:
     1486         d = 0x001;
     1487         break;
     1488      case 2:
     1489         d = 0x041;
     1490         break;
     1491      case 3:
     1492         d = 0x111;
     1493         break;
     1494      case 4:
     1495         d = 0x249;
     1496         break;
     1497      case 6:
     1498         d = 0x555;
     1499         break;
     1500      case 12:
     1501         d = 0xFFF;
     1502         break;
     1503      default:
     1504         printf("Invalid channel configuration\n");
     1505      }
     1506      Write(T_CTRL, REG_CHANNEL_CONFIG, &d, 2);
     1507   } else if (fDRSType == 4) {
     1508      if (fBoardType == 6) {
     1509         // determined channel readout mode A/C[even/odd], B/D[even/odd] or A/B/C/D
     1510         fReadoutChannelConfig = firstChannel;
     1511         Read(T_CTRL, &d, REG_CHANNEL_MODE, 2);
     1512         d = (d & 0xFF00) | firstChannel; // keep higher 8 bits which are ADClkPhase
     1513         Write(T_CTRL, REG_CHANNEL_MODE, &d, 2);
     1514      } else {
     1515         // upper four bits of register must contain last channel to read out starting from 9
     1516         Read(T_CTRL, &d, REG_CHANNEL_MODE, 2);
     1517         d = (d & 0xFF00) | (firstChannel << 4) | lastChannel; // keep higher 8 bits which are ADClkPhase
     1518         Write(T_CTRL, REG_CHANNEL_MODE, &d, 2);
     1519      }
     1520
     1521      // set bit pattern for write shift register
     1522      fChannelConfig = 0;
     1523      switch (nConfigChannels) {
     1524      case 1:
     1525         fChannelConfig = 0x01;
     1526         break;
     1527      case 2:
     1528         fChannelConfig = 0x11;
     1529         break;
     1530      case 4:
     1531         fChannelConfig = 0x55;
     1532         break;
     1533      case 8:
     1534         fChannelConfig = 0xFF;
     1535         break;
     1536      default:
     1537         printf("Invalid channel configuration\n");
     1538      }
     1539      d = fChannelConfig | (fDominoMode << 8) | (1 << 9) | (fWSRLoop << 10) | (0xF8 << 8);
     1540
     1541      Write(T_CTRL, REG_CHANNEL_CONFIG, &d, 2);
     1542   }
     1543
     1544   if (fBoardType == 6) {
     1545      if (fReadoutChannelConfig == 7)
     1546         fNumberOfReadoutChannels = 9;
     1547      else
     1548         fNumberOfReadoutChannels = 5;
     1549   } else {
     1550      fNumberOfReadoutChannels = lastChannel - firstChannel + 1;
     1551   }
     1552}
     1553
     1554/*------------------------------------------------------------------*/
     1555
     1556void DRSBoard::SetNumberOfChannels(int nChannels)
     1557{
     1558   SetChannelConfig(0, nChannels - 1, 12);
     1559}
     1560
     1561/*------------------------------------------------------------------*/
     1562
     1563void DRSBoard::SetADCClkPhase(int phase, bool invert)
     1564{
     1565   unsigned short d;
     1566
     1567   /* Set the clock phase of the ADC via the variable phase shift
     1568      in the Xilinx DCM. One unit is equal to the clock period / 256,
     1569      so at 30 MHz this is about 130ps. The possible range at 30 MHz
     1570      is -87 ... +87 */
     1571
     1572   // keep lower 8 bits which are the channel mode
     1573   Read(T_CTRL, &d, REG_ADCCLK_PHASE, 2);
     1574   d = (d & 0x00FF) | (phase << 8);
     1575   Write(T_CTRL, REG_ADCCLK_PHASE, &d, 2);
     1576
     1577   if (invert)
     1578      fCtrlBits |= BIT_ADCCLK_INVERT;
     1579   else
     1580      fCtrlBits &= ~BIT_ADCCLK_INVERT;
     1581   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1582
     1583   fADCClkPhase = phase;
     1584   fADCClkInvert = invert;
     1585}
     1586
     1587/*------------------------------------------------------------------*/
     1588
     1589void DRSBoard::SetWarmup(unsigned int microseconds)
     1590{
     1591   /* Set the "warmup" time. When starting the domino wave, the DRS4
     1592      chip together with its power supply need some time to stabilize
     1593      before high resolution data can be taken (jumping baseline
     1594      problem). This sets the time in ticks of 900ns before triggers
     1595      are accepted */
     1596
     1597   unsigned short ticks;
     1598
     1599   if (microseconds == 0)
     1600      ticks = 0;
     1601   else
     1602      ticks = (unsigned short) (microseconds / 0.9 + 0.5) - 1;
     1603   Write(T_CTRL, REG_WARMUP, &ticks, 2);
     1604}
     1605
     1606/*------------------------------------------------------------------*/
     1607
     1608void DRSBoard::SetCooldown(unsigned int microseconds)
     1609{
     1610   /* Set the "cooldown" time. When stopping the domino wave, the
     1611      power supply needs some time to stabilize before high resolution
     1612      data can read out (slanted baseline problem). This sets the
     1613      time in ticks of 900 ns before the readout is started */
     1614
     1615   unsigned short ticks;
     1616
     1617   ticks = (unsigned short) (microseconds / 0.9 + 0.5) - 1;
     1618   Write(T_CTRL, REG_COOLDOWN, &ticks, 2);
     1619}
     1620
     1621/*------------------------------------------------------------------*/
     1622
     1623int DRSBoard::SetDAC(unsigned char channel, double value)
     1624{
     1625   // Set DAC value
     1626   unsigned short d;
     1627
     1628   /* normalize to 2.5V for 16 bit */
     1629   if (value < 0)
     1630      value = 0;
     1631   if (value > 2.5)
     1632      value = 2.5;
     1633   d = static_cast < unsigned short >(value / 2.5 * 0xFFFF + 0.5);
     1634
     1635   Write(T_CTRL, REG_DAC_OFS + (channel * 2), &d, 2);
     1636
     1637   return 1;
     1638}
     1639
     1640/*------------------------------------------------------------------*/
     1641
     1642int DRSBoard::ReadDAC(unsigned char channel, double *value)
     1643{
     1644   // Readback DAC value from control register
     1645   unsigned char buffer[2];
     1646
     1647   /* map 0->1, 1->0, 2->3, 3->2, etc. */
     1648   //ofs = channel + 1 - 2*(channel % 2);
     1649
     1650   Read(T_CTRL, buffer, REG_DAC_OFS + (channel * 2), 2);
     1651
     1652   /* normalize to 2.5V for 16 bit */
     1653   *value = 2.5 * (buffer[0] + (buffer[1] << 8)) / 0xFFFF;
     1654
     1655   return 1;
     1656}
     1657
     1658/*------------------------------------------------------------------*/
     1659
     1660int DRSBoard::GetRegulationDAC(double *value)
     1661{
     1662   // Get DAC value from status register (-> freq. regulation)
     1663   unsigned char buffer[2];
     1664
     1665   if (fBoardType == 1)
     1666      Read(T_STATUS, buffer, REG_RDAC3, 2);
     1667   else if (fBoardType == 2 || fBoardType == 3 || fBoardType == 4)
     1668      Read(T_STATUS, buffer, REG_RDAC1, 2);
     1669
     1670   /* normalize to 2.5V for 16 bit */
     1671   *value = 2.5 * (buffer[0] + (buffer[1] << 8)) / 0xFFFF;
     1672
     1673   return 1;
     1674}
     1675
     1676/*------------------------------------------------------------------*/
     1677
     1678int DRSBoard::StartDomino()
     1679{
     1680   // Start domino sampling
     1681   fCtrlBits |= BIT_START_TRIG;
     1682   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1683   fCtrlBits &= ~BIT_START_TRIG;
     1684
     1685   return 1;
     1686}
     1687
     1688/*------------------------------------------------------------------*/
     1689
     1690int DRSBoard::Reinit()
     1691{
     1692   // Stop domino sampling
     1693   // reset readout state machine
     1694   // reset FIFO counters
     1695   fCtrlBits |= BIT_REINIT_TRIG;
     1696   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1697   fCtrlBits &= ~BIT_REINIT_TRIG;
     1698
     1699   return 1;
     1700}
     1701
     1702/*------------------------------------------------------------------*/
     1703
     1704int DRSBoard::Init()
     1705{
     1706   // Init FPGA on USB2 board
     1707   InitFPGA();
     1708
     1709   // Default values
     1710
     1711   // Reinitialize
     1712   fCtrlBits |= BIT_REINIT_TRIG;        // reset readout state machine
     1713   if (fDRSType == 2)
     1714      fCtrlBits &= ~BIT_FREQ_AUTO_ADJ;  // turn auto. freq regul. off
     1715   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1716   fCtrlBits &= ~BIT_REINIT_TRIG;
     1717
     1718   if (fBoardType == 1) {
     1719      // set max. domino speed
     1720      SetDAC(fDAC_DRA, 2.5);
     1721      SetDAC(fDAC_DSA, 2.5);
     1722      SetDAC(fDAC_DRB, 2.5);
     1723      SetDAC(fDAC_DSB, 2.5);
     1724      // set readout offset
     1725      SetDAC(fDAC_COFSA, 0.9);
     1726      SetDAC(fDAC_COFSB, 0.9);
     1727      SetDAC(fDAC_TLEVEL, 1.7);
     1728   } else if (fBoardType == 2 || fBoardType == 3) {
     1729      // set max. domino speed
     1730      SetDAC(fDAC_DSA, 2.5);
     1731      SetDAC(fDAC_DSB, 2.5);
     1732
     1733      // set readout offset
     1734      SetDAC(fDAC_COFS, 0.9);
     1735      SetDAC(fDAC_TLEVEL, 1.7);
     1736      SetDAC(fDAC_ADCOFS, 1.7); // 1.7 for DC coupling, 1.25 for AC
     1737      SetDAC(fDAC_CLKOFS, 1);
     1738   } else if (fBoardType == 4) {
     1739      // set max. domino speed
     1740      SetDAC(fDAC_DSA, 2.5);
     1741      SetDAC(fDAC_DSB, 2.5);
     1742
     1743      // set readout offset
     1744      SetDAC(fDAC_ROFS_1, 1.25);        // LVDS level
     1745      //SetDAC(fDAC_ROFS_2, 0.85);   // linear range  0.1V ... 1.1V
     1746      SetDAC(fDAC_ROFS_2, 1.05);        // differential input from Lecce splitter
     1747
     1748      SetDAC(fDAC_ADCOFS, 1.25);
     1749      SetDAC(fDAC_ACALIB, 0.5);
     1750      SetDAC(fDAC_INOFS, 0.6);
     1751      SetDAC(fDAC_BIAS, 0.70);  // a bit above the internal bias of 0.68V
     1752   
     1753   } else if (fBoardType == 5) {
     1754      // DRS4 USB Evaluation Board 1.1 + 2.0
     1755
     1756      // set max. domino speed
     1757      SetDAC(fDAC_DSA, 2.5);
     1758
     1759      // set readout offset
     1760      fROFS = 1.6;              // differential input range -0.5V ... +0.5V
     1761      fRange = 0;
     1762      SetDAC(fDAC_ROFS_1, fROFS);
     1763
     1764      // set common mode offset
     1765      fCommonMode = 0.8;        // 0.8V +- 0.5V inside NMOS range
     1766      SetDAC(fDAC_CMOFS, fCommonMode);
     1767
     1768      // calibration voltage
     1769      SetDAC(fDAC_CALP, fCommonMode);
     1770      SetDAC(fDAC_CALN, fCommonMode);
     1771
     1772      // OUT- offset
     1773      SetDAC(fDAC_ONOFS, 1.25);
     1774
     1775      SetDAC(fDAC_BIAS, 0.70);
     1776
     1777   } else if (fBoardType == 6) {
     1778      // DRS4 Mezzanine Board 1.0
     1779     
     1780      // set readout offset
     1781      fROFS = 1.6;              // differential input range -0.5V ... +0.5V
     1782      fRange = 0;
     1783      SetDAC(fDAC_ROFS_1, fROFS);
     1784
     1785      // set common mode offset
     1786      fCommonMode = 0.8;        // 0.8V +- 0.5V inside NMOS range
     1787      SetDAC(fDAC_CMOFSP, fCommonMode);
     1788      SetDAC(fDAC_CMOFSN, fCommonMode);
     1789
     1790      // calibration voltage
     1791      SetDAC(fDAC_CALN, fCommonMode);
     1792      SetDAC(fDAC_CALP, fCommonMode);
     1793
     1794      // OUT- offset
     1795      SetDAC(fDAC_ONOFS, 1.25);
     1796
     1797      SetDAC(fDAC_BIAS, 0.70);
     1798   }
     1799
     1800   /* set default number of channels per chip */
     1801   if (fDRSType == 4) {
     1802      if (fTransport == TR_USB2)
     1803         SetChannelConfig(0, fNumberOfReadoutChannels - 1, 8);
     1804      else
     1805         SetChannelConfig(7, fNumberOfReadoutChannels - 1, 8);
     1806   } else
     1807      SetChannelConfig(0, fNumberOfReadoutChannels - 1, 12);
     1808
     1809   // set ADC clock phase
     1810   if (fBoardType == 5) {
     1811      fADCClkPhase = 0;
     1812      fADCClkInvert = 0;
     1813   } else if (fBoardType == 6) {
     1814      fADCClkPhase = 60;
     1815      fADCClkInvert = 0;
     1816   }
     1817
     1818   // default settings
     1819   fDominoMode = 1;
     1820   fReadoutMode = 1;
     1821   fTriggerEnable1 = 0;
     1822   fTriggerEnable2 = 0;
     1823   fTriggerSource = 0;
     1824   fTriggerDelay = 0;
     1825   fFrequency = 1;
     1826   fDominoActive = 1;
     1827
     1828   // get some settings from hardware
     1829   fRange = GetCalibratedInputRange();
     1830   if (fRange < 0 || fRange > 0.5)
     1831      fRange = 0;
     1832   fFrequency = GetCalibratedFrequency();
     1833   if (fFrequency < 0.1 || fFrequency > 6)
     1834      fFrequency = 1;
     1835
     1836   SetDominoMode(fDominoMode);
     1837   SetReadoutMode(fReadoutMode);
     1838   EnableTrigger(fTriggerEnable1, fTriggerEnable2);
     1839   SetTriggerSource(fTriggerSource);
     1840   SetTriggerDelay(fTriggerDelay);
     1841   SetDominoActive(fDominoActive);
     1842   SetFrequency(fFrequency, true);
     1843   SetInputRange(fRange);
     1844   if (fBoardType == 5)
     1845      SelectClockSource(0); // FPGA clock
     1846   if (fBoardType == 6) {
     1847      SetADCClkPhase(fADCClkPhase, fADCClkInvert);
     1848      SetWarmup(0);
     1849      SetCooldown(100);
     1850   }
     1851
     1852   /* disable calibration signals */
     1853   EnableAcal(0, 0);
     1854   SetCalibTiming(0, 0);
     1855
     1856   return 1;
     1857}
     1858
     1859/*------------------------------------------------------------------*/
     1860
     1861int DRSBoard::SetDominoMode(unsigned char mode)
     1862{
     1863   // Set domino mode
     1864   // mode == 0: single sweep
     1865   // mode == 1: run continously
     1866   //
     1867   fDominoMode = mode;
     1868
     1869   if (fDRSType == 4) {
     1870      unsigned short d;
     1871      Read(T_CTRL, &d, REG_CONFIG, 2);
     1872      fChannelConfig = d & 0xFF;
     1873
     1874      d = fChannelConfig | (fDominoMode << 8) | (1 << 9) | (fWSRLoop << 10) | (0xF8 << 8);
     1875      Write(T_CTRL, REG_CONFIG, &d, 2);
     1876   } else {
     1877      if (mode)
     1878         fCtrlBits |= BIT_DMODE;
     1879      else
     1880         fCtrlBits &= ~BIT_DMODE;
     1881
     1882      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1883   }
     1884
     1885   return 1;
     1886}
     1887
     1888/*------------------------------------------------------------------*/
     1889
     1890int DRSBoard::SetDominoActive(unsigned char mode)
     1891{
     1892   // Set domino activity
     1893   // mode == 0: stop during readout
     1894   // mode == 1: keep domino wave running
     1895   //
     1896   fDominoActive = mode;
     1897   if (mode)
     1898      fCtrlBits |= BIT_DACTIVE;
     1899   else
     1900      fCtrlBits &= ~BIT_DACTIVE;
     1901
     1902   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1903
     1904   return 1;
     1905}
     1906
     1907/*------------------------------------------------------------------*/
     1908
     1909int DRSBoard::SetReadoutMode(unsigned char mode)
     1910{
     1911   // Set readout mode
     1912   // mode == 0: start from first bin
     1913   // mode == 1: start from domino stop
     1914   //
     1915   fReadoutMode = mode;
     1916   if (mode)
     1917      fCtrlBits |= BIT_READOUT_MODE;
     1918   else
     1919      fCtrlBits &= ~BIT_READOUT_MODE;
     1920
     1921   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1922
     1923   return 1;
     1924}
     1925
     1926/*------------------------------------------------------------------*/
     1927
     1928int DRSBoard::SoftTrigger(void)
     1929{
     1930   // Send a software trigger
     1931   fCtrlBits |= BIT_SOFT_TRIG;
     1932   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1933   fCtrlBits &= ~BIT_SOFT_TRIG;
     1934
     1935   return 1;
     1936}
     1937
     1938/*------------------------------------------------------------------*/
     1939
     1940int DRSBoard::EnableTrigger(int flag1, int flag2)
     1941{
     1942   // Enable external trigger
     1943   fTriggerEnable1 = flag1;
     1944   fTriggerEnable2 = flag2;
     1945   if (flag1)
     1946      fCtrlBits |= BIT_ENABLE_TRIGGER1;
     1947   else
     1948      fCtrlBits &= ~BIT_ENABLE_TRIGGER1;
     1949
     1950   if (flag2)
     1951      fCtrlBits |= BIT_ENABLE_TRIGGER2;
     1952   else
     1953      fCtrlBits &= ~BIT_ENABLE_TRIGGER2;
     1954
     1955   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1956
     1957   return 1;
     1958}
     1959
     1960/*------------------------------------------------------------------*/
     1961
     1962int DRSBoard::SetDelayedTrigger(int flag)
     1963{
     1964   // Select delayed trigger from trigger bus
     1965   if (flag)
     1966      fCtrlBits |= BIT_TRIGGER_DELAYED;
     1967   else
     1968      fCtrlBits &= ~BIT_TRIGGER_DELAYED;
     1969
     1970   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1971
     1972   return 1;
     1973}
     1974
     1975/*------------------------------------------------------------------*/
     1976
     1977int DRSBoard::SetTriggerLevel(double voltage, bool negative)
     1978{
     1979   if (fBoardType == 5) {
     1980      fTcalLevel = negative;
     1981
     1982      if (negative)
     1983         fCtrlBits |= BIT_NEG_TRIGGER;
     1984      else
     1985         fCtrlBits &= ~BIT_NEG_TRIGGER;
     1986
     1987      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     1988
     1989      return SetDAC(fDAC_TLEVEL, voltage/2 + 0.8);
     1990   }
     1991
     1992   return 0;
     1993}
     1994
     1995/*------------------------------------------------------------------*/
     1996
     1997int DRSBoard::SetTriggerDelay(int delay)
     1998{
     1999   short ticks;
     2000   int delay0;
     2001
     2002   if (fBoardType == 5 || fBoardType == 6) {
     2003      fTriggerDelay = delay;
     2004
     2005      if (fBoardType == 5) {
     2006         // Adjust trigger delay to middle of window
     2007         delay0 = (int) ((kNumberOfBins/fFrequency) / 2);
     2008         delay0 -= 33; // internal trigger delay is about 33 ns
     2009      } else
     2010         delay0 = 0; // treat delay as addition to minimal delay
     2011
     2012      // convert delay in ns into ticks, ~4*580 ps per quad LUT
     2013      ticks = (unsigned short) ((delay0 + delay) / 2.3 + 0.5);
     2014      if (ticks > 255)
     2015         ticks = 255;
     2016      if (ticks < 0)
     2017         ticks = 0;
     2018      Write(T_CTRL, REG_TRG_DELAY, &ticks, 2);
     2019
     2020      return 1;
     2021   }
     2022
     2023   return 0;
     2024}
     2025
     2026/*------------------------------------------------------------------*/
     2027
     2028int DRSBoard::SetTriggerSource(int source)
     2029{
     2030   // Set trigger source
     2031   // 0=CH1, 1=CH2, 2=CH3, 3=CH4
     2032   if (source & 1)
     2033      fCtrlBits |= BIT_TR_SOURCE1;
     2034   else
     2035      fCtrlBits &= ~BIT_TR_SOURCE1;
     2036   if (source & 2)
     2037      fCtrlBits |= BIT_TR_SOURCE2;
     2038   else
     2039      fCtrlBits &= ~BIT_TR_SOURCE2;
     2040
     2041   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2042
     2043   return 1;
     2044}
     2045
     2046/*------------------------------------------------------------------*/
     2047
     2048int DRSBoard::SetDelayedStart(int flag)
     2049{
     2050   // Enable external trigger
     2051   fDelayedStart = flag;
     2052   if (flag)
     2053      fCtrlBits |= BIT_DELAYED_START;
     2054   else
     2055      fCtrlBits &= ~BIT_DELAYED_START;
     2056
     2057   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2058
     2059   return 1;
     2060}
     2061
     2062/*------------------------------------------------------------------*/
     2063
     2064int DRSBoard::SetTranspMode(int flag)
     2065{
     2066   // Enable/disable transparent mode
     2067   fTranspMode = flag;
     2068   if (flag)
     2069      fCtrlBits |= BIT_TRANSP_MODE;
     2070   else
     2071      fCtrlBits &= ~BIT_TRANSP_MODE;
     2072
     2073   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2074
     2075   return 1;
     2076}
     2077
     2078/*------------------------------------------------------------------*/
     2079
     2080int DRSBoard::SetStandbyMode(int flag)
     2081{
     2082   // Enable/disable standby mode
     2083   fTranspMode = flag;
     2084   if (flag)
     2085      fCtrlBits |= BIT_STANDBY_MODE;
     2086   else
     2087      fCtrlBits &= ~BIT_STANDBY_MODE;
     2088
     2089   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2090
     2091   return 1;
     2092}
     2093
     2094/*------------------------------------------------------------------*/
     2095
     2096int DRSBoard::IsBusy()
     2097{
     2098   // Get running flag
     2099   unsigned int status;
     2100
     2101   Read(T_STATUS, &status, REG_STATUS, 4);
     2102   return (status & BIT_RUNNING) > 0;
     2103}
     2104
     2105/*------------------------------------------------------------------*/
     2106
     2107int DRSBoard::IsPLLLocked()
     2108{
     2109   // Get running flag
     2110   unsigned int status;
     2111
     2112   Read(T_STATUS, &status, REG_STATUS, 4);
     2113   if (GetBoardType() == 6)
     2114      return ((status >> 1) & 0x0F) == 0x0F;
     2115   return (status & BIT_PLL_LOCKED0) > 0;
     2116}
     2117
     2118/*------------------------------------------------------------------*/
     2119
     2120int DRSBoard::IsLMKLocked()
     2121{
     2122   // Get running flag
     2123   unsigned int status;
     2124
     2125   Read(T_STATUS, &status, REG_STATUS, 4);
     2126   if (GetBoardType() == 6)
     2127      return (status & BIT_LMK_LOCKED) > 0;
     2128   return 0;
     2129}
     2130
     2131/*------------------------------------------------------------------*/
     2132
     2133int DRSBoard::IsNewFreq(unsigned char chipIndex)
     2134{
     2135   unsigned int status;
     2136
     2137   Read(T_STATUS, &status, REG_STATUS, 4);
     2138   if (chipIndex == 0)
     2139      return (status & BIT_NEW_FREQ1) > 0;
     2140   return (status & BIT_NEW_FREQ2) > 0;
     2141}
     2142
     2143/*------------------------------------------------------------------*/
     2144
     2145int DRSBoard::ReadFrequency(unsigned char chipIndex, double *f)
     2146{
     2147   if (fDRSType == 4) {
     2148
     2149      if (fBoardType == 6) {
     2150         *f = fFrequency;
     2151         return 1;
     2152      }
     2153
     2154      unsigned short ticks;
     2155
     2156      Read(T_CTRL, &ticks, REG_FREQ_SET, 2);
     2157      ticks += 2;
     2158
     2159      /* convert rounded ticks back to frequency */
     2160      if (ticks > 2)
     2161         *f = 1.024 / ticks * fRefClock;
     2162      else
     2163         *f = 0;
     2164   } else {
     2165      // Read domino sampling frequency
     2166      unsigned char buffer[2];
     2167
     2168      if (chipIndex == 0)
     2169         Read(T_STATUS, buffer, REG_FREQ1, 2);
     2170      else
     2171         Read(T_STATUS, buffer, REG_FREQ2, 2);
     2172
     2173      *f = (static_cast < unsigned int >(buffer[1]) << 8) +buffer[0];
     2174
     2175      /* convert counts to frequency */
     2176      if (*f != 0)
     2177         *f = 1024 * 200 * (32.768E6 * 4) / (*f) / 1E9;
     2178   }
     2179
     2180   return 1;
     2181}
     2182
     2183/*------------------------------------------------------------------*/
     2184
     2185double DRSBoard::VoltToFreq(double volt)
     2186{
     2187   if (fDRSType == 3) {
     2188      if (volt <= 1.2001)
     2189         return (volt - 0.6) / 0.2;
     2190      else
     2191         return 0.73 / 0.28 + sqrt((0.73 / 0.28) * (0.73 / 0.28) - 2.2 / 0.14 + volt / 0.14);
     2192   } else
     2193      return (volt - 0.5) / 0.2;
     2194}
     2195
     2196/*------------------------------------------------------------------*/
     2197
     2198double DRSBoard::FreqToVolt(double freq)
     2199{
     2200   if (fDRSType == 3) {
     2201      if (freq <= 3)
     2202         return 0.6 + 0.2 * freq;
     2203      else
     2204         return 2.2 - 0.73 * freq + 0.14 * freq * freq;
     2205   } else
     2206      return 0.55 + 0.25 * freq;
     2207}
     2208
     2209/*------------------------------------------------------------------*/
     2210
     2211int DRSBoard::ConfigureLMK(double sampFreq, bool freqChange, int calFreq, int calPhase)
     2212{
     2213   unsigned int data[] = { 0x80000100,   // RESET=1
     2214                           0x0007FF00,   // CLKOUT0: EN=1, DIV=FF (=510) MUX=Div&Delay
     2215                           0x00000101,   // CLKOUT1: Disabled
     2216                           0x0082000B,   // R11: DIV4=0
     2217                           0x028780AD,   // R13: VCO settings
     2218                           0x0830000E,   // R14: PLL settings
     2219                           0xC000000F }; // R15: PLL settings
     2220
     2221   /* calculate dividing ratio */
     2222   int divider, vco_divider, n_counter, r_counter;
     2223   unsigned int status;
     2224   double clk, vco;
     2225
     2226   if (fTransport == TR_USB2) {
     2227      /* 30 MHz clock */
     2228      data[4]     = 0x028780AD;  // R13 according to CodeLoader 4
     2229      clk         = 30;
     2230      if (sampFreq < 1) {
     2231         r_counter   = 1;
     2232         vco_divider = 8;
     2233         n_counter   = 5;
     2234      } else {
     2235         r_counter   = 1;
     2236         vco_divider = 5;
     2237         n_counter   = 8;
     2238      }
     2239   } else {
     2240     
     2241      if (fCtrlBits & BIT_REFCLK_SOURCE) {
     2242         /* 19.44 MHz clock */
     2243         data[4]     = 0x0284C0AD;  // R13 according to CodeLoader 4
     2244         clk         = 19.44; // global clock through P2
     2245
     2246         r_counter   = 2;
     2247         vco_divider = 8;
     2248         n_counter   = 16;
     2249      } else {
     2250         /* 33 MHz clock */
     2251         data[4]     = 0x028840AD;  // R13 according to CodeLoader 4
     2252         clk         = 33; // FPGA clock
     2253
     2254         r_counter   = 2;
     2255         vco_divider = 8;
     2256         n_counter   = 9;
     2257      }
     2258   }
     2259
     2260   vco = clk/r_counter*n_counter*vco_divider;
     2261   divider = (int) ((vco / vco_divider / (sampFreq/2.048) / 2.0) + 0.5);
     2262
     2263   /* return exact frequency */
     2264   fFrequency = vco/vco_divider/(divider*2)*2.048;
     2265
     2266   /* return exact timing calibration frequency */
     2267   fTCALFrequency = vco/vco_divider;
     2268
     2269   /* change registers accordingly */
     2270   data[1] = 0x00070000 | (divider << 8);   // R0
     2271   data[5] = 0x0830000E | (r_counter << 8); // R14
     2272   data[6] = 0xC000000F | (n_counter << 8) | (vco_divider << 26); // R15
     2273
     2274   /* enable TCA output if requested */
     2275   if (calFreq) {
     2276      if (calFreq == 1)
     2277         data[2] = 0x00050001 | (  1<<8) ; // 148.5 MHz  (33 MHz PLL)
     2278                                           // 150 MHz    (30 MHz PLL)
     2279                                           // 155.52 MHz (19.44 MHz PLL)
     2280      else if (calFreq == 2)
     2281         data[2] = 0x00070001 | (  4<<8);  // above values divided by 8
     2282      else if (calFreq == 3)
     2283         data[2] = 0x00070001 | (255<<8);  // above values divided by 510
     2284   }
     2285
     2286   /* set delay to adjsut phase */
     2287   if (calPhase > 0)
     2288      data[2] |= (( calPhase & 0x0F) << 4);
     2289   else if (calPhase < 0)
     2290      data[1] |= ((-calPhase & 0x0F) << 4);
     2291
     2292   if (freqChange) {
     2293      /* set all registers */   
     2294      for (int i=0 ; i<(int)(sizeof(data)/sizeof(unsigned int)) ; i++) {
     2295         Write(T_CTRL, REG_LMK_LSB, &data[i], 2);
     2296         Write(T_CTRL, REG_LMK_MSB, ((char *)&data[i])+2, 2);
     2297         // poll on serial_busy flag
     2298         for (int j=0 ; j<100 ; j++) {
     2299            Read(T_STATUS, &status, REG_STATUS, 4);
     2300            if ((status & BIT_SERIAL_BUSY) == 0)
     2301               break;
     2302         }
     2303      }
     2304   } else {
     2305      /* only enable/disable timing calibration frequency */
     2306      Write(T_CTRL, REG_LMK_LSB, &data[1], 2);
     2307      Write(T_CTRL, REG_LMK_MSB, ((char *)&data[1])+2, 2);
     2308
     2309      /* poll on serial_busy flag */
     2310      for (int j=0 ; j<100 ; j++) {
     2311         Read(T_STATUS, &status, REG_STATUS, 4);
     2312         if ((status & BIT_SERIAL_BUSY) == 0)
     2313            break;
     2314      }
     2315
     2316      Write(T_CTRL, REG_LMK_LSB, &data[2], 2);
     2317      Write(T_CTRL, REG_LMK_MSB, ((char *)&data[2])+2, 2);
     2318
     2319      /* poll on serial_busy flag */
     2320      for (int j=0 ; j<100 ; j++) {
     2321         Read(T_STATUS, &status, REG_STATUS, 4);
     2322         if ((status & BIT_SERIAL_BUSY) == 0)
     2323            break;
     2324      }
     2325   }
     2326
     2327   return 1;
     2328}
     2329
     2330/*------------------------------------------------------------------*/
     2331
     2332int DRSBoard::SetFrequency(double demand, bool wait)
     2333{
     2334   // Set domino sampling frequency
     2335   double freq, voltage, delta_voltage;
     2336   unsigned short ticks;
     2337   int i, index, timeout;
     2338   int dominoModeSave = fDominoMode;
     2339   int triggerEnableSave1 = fTriggerEnable1;
     2340   int triggerEnableSave2 = fTriggerEnable2;
     2341
     2342   if (fDRSType == 4) {
     2343      /* allowed range is 100 MHz to 6 GHz */
     2344      if (demand > 6 || demand < 0.1)
     2345         return 0;
     2346
     2347      if (fBoardType == 6)
     2348         return ConfigureLMK(demand, true, fTcalFreq, fTcalPhase);
     2349
     2350      /* convert frequency in GHz into ticks counted by reference clock */
     2351      if (demand == 0)
     2352         ticks = 0;             // turn off frequency generation
     2353      else
     2354         ticks = static_cast < unsigned short >(1.024 / demand * fRefClock + 0.5);
     2355
     2356      ticks -= 2;               // firmware counter need two additional clock cycles
     2357      Write(T_CTRL, REG_FREQ_SET, &ticks, 2);
     2358      ticks += 2;
     2359
     2360      /* convert rounded ticks back to frequency */
     2361      if (demand > 0)
     2362         demand = 1.024 / ticks * fRefClock;
     2363      fFrequency = demand;
     2364
     2365      /* wait for PLL lock if asekd */
     2366      if (wait) {
     2367         StartDomino();
     2368         for (i=0 ; i<1000 ; i++)
     2369         if (GetStatusReg() & BIT_PLL_LOCKED0)
     2370            break;
     2371         if (i==100) {
     2372            printf("PLL did not lock for frequency %lf\n", demand);
     2373            return 0;
     2374         }
     2375      }
     2376   } else {                     // fDRSType == 4
     2377      SetDominoMode(1);
     2378      EnableTrigger(0, 0);
     2379      EnableAcal(0, 0);
     2380
     2381      fFrequency = demand;
     2382
     2383      /* turn automatic adjustment off */
     2384      fCtrlBits &= ~BIT_FREQ_AUTO_ADJ;
     2385
     2386      /* disable external trigger */
     2387      fCtrlBits &= ~BIT_ENABLE_TRIGGER1;
     2388      fCtrlBits &= ~BIT_ENABLE_TRIGGER2;
     2389
     2390      /* set start pulse length for future DRSBoard_domino_start() */
     2391      if (fDRSType == 2) {
     2392         if (demand < 0.8)
     2393            fCtrlBits |= BIT_LONG_START_PULSE;
     2394         else
     2395            fCtrlBits &= ~BIT_LONG_START_PULSE;
     2396
     2397         Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2398      }
     2399
     2400      /* stop any running domino wave */
     2401      Reinit();
     2402
     2403      /* estimate DAC setting */
     2404      voltage = FreqToVolt(demand);
     2405
     2406      SetDAC(fDAC_DSA, voltage);
     2407      SetDAC(fDAC_DSB, voltage);
     2408
     2409      /* wait until new DAC value has settled */
     2410      Sleep(10);
     2411
     2412      /* restart domino wave */
     2413      StartDomino();
     2414
     2415      ticks = static_cast < unsigned short >(1024 * 200 * (32.768E6 * 4) / demand / 1E9);
     2416
     2417      /* iterate over both DRS chips */
     2418      for (index = 0; index < 2; index++) {
     2419
     2420         /* starting voltage */
     2421         voltage = FreqToVolt(demand);
     2422
     2423         for (i = 0; i < 100; i++) {
     2424
     2425            /* wait until measurement finished */
     2426            for (timeout = 0; timeout < 1000; timeout++)
     2427               if (IsNewFreq(index))
     2428                  break;
     2429
     2430            freq = 0;
     2431            if (timeout == 1000)
     2432               break;
     2433
     2434            ReadFrequency(index, &freq);
     2435
     2436            delta_voltage = FreqToVolt(demand) - FreqToVolt(freq);
     2437
     2438            if (fDebug) {
     2439               if (fabs(freq - demand) < 0.001)
     2440                  printf("CHIP-%d, iter%3d: %1.5lf(%05d) %7.5lf\n", index, i, voltage,
     2441                         static_cast < int >(voltage / 2.5 * 65535 + 0.5), freq);
     2442               else
     2443                  printf("CHIP-%d, iter%3d: %1.5lf(%05d) %7.5lf %+5d\n", index, i, voltage,
     2444                         static_cast < int >(voltage / 2.5 * 65535 + 0.5), freq,
     2445                         static_cast < int >(delta_voltage / 2.5 * 65535 + 0.5));
     2446            }
     2447
     2448            if (fabs(freq - demand) < 0.001)
     2449               break;
     2450
     2451            voltage += delta_voltage;
     2452            if (voltage > 2.5)
     2453               voltage = 2.5;
     2454            if (voltage < 0)
     2455               voltage = 0;
     2456
     2457            if (freq == 0)
     2458               break;
     2459
     2460            if (index == 0)
     2461               SetDAC(fDAC_DSA, voltage);
     2462            else
     2463               SetDAC(fDAC_DSB, voltage);
     2464
     2465            Sleep(10);
     2466         }
     2467         if (i == 100 || freq == 0 || timeout == 1000) {
     2468            printf("Board %d --> Could not set frequency of CHIP-#%d to %1.3f GHz\n", GetBoardSerialNumber(),
     2469                   index, demand);
     2470            return 0;
     2471         }
     2472      }
     2473
     2474      SetDominoMode(dominoModeSave);
     2475      EnableTrigger(triggerEnableSave1, triggerEnableSave2);
     2476   }
     2477
     2478   return 1;
     2479}
     2480
     2481/*------------------------------------------------------------------*/
     2482
     2483int DRSBoard::RegulateFrequency(double demand)
     2484{
     2485   // Set frequency regulation
     2486   unsigned short target, target_hi, target_lo;
     2487
     2488   if (demand < 0.42 || demand > 5.2)
     2489      return 0;
     2490
     2491   fFrequency = demand;
     2492
     2493   /* first iterate DAC value from host */
     2494   if (!SetFrequency(demand, true))
     2495      return 0;
     2496
     2497   /* convert frequency in GHz into counts for 200 cycles */
     2498   target = static_cast < unsigned short >(1024 * 200 * (32.768E6 * 4) / demand / 1E9);
     2499   target_hi = target + 6;
     2500   target_lo = target - 6;
     2501   Write(T_CTRL, REG_FREQ_SET_HI, &target_hi, 2);
     2502   Write(T_CTRL, REG_FREQ_SET_LO, &target_lo, 2);
     2503
     2504   /* turn on regulation */
     2505   fCtrlBits |= BIT_FREQ_AUTO_ADJ;
     2506   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     2507
     2508   /* optional monitoring code ... */
     2509#if 0
     2510   do {
     2511      double freq;
     2512      unsigned short dac, cnt;
     2513
     2514      ReadFrequency(0, &freq);
     2515
     2516      if (fBoardType == 1)
     2517         Read(T_STATUS, &dac, REG_RDAC3, 2);
     2518      else if (fBoardType == 2 || fBoardType == 3)
     2519         Read(T_STATUS, &dac, REG_RDAC1, 2);
     2520
     2521      Read(T_STATUS, &cnt, REG_FREQ1, 2);
     2522
     2523      if (cnt < 65535)
     2524         printf("%5d %5d %5d %1.5lf\n", dac, target, cnt, freq);
     2525
     2526      Sleep(500);
     2527   } while (1);
     2528#endif
     2529
     2530   return 1;
     2531}
     2532
     2533/*------------------------------------------------------------------*/
     2534
     2535void DRSBoard::RegisterTest()
     2536{
     2537   // Register test
     2538#define N_REG 8
     2539
     2540   int i, n, n_err;
     2541   unsigned int buffer[N_REG], ret[N_REG];
     2542
     2543   /* test single register */
     2544   buffer[0] = 0x12345678;
     2545   Write(T_CTRL, 0, buffer, 4);
     2546   memset(ret, 0, sizeof(ret));
     2547   i = Read(T_CTRL, ret, 0, 4);
     2548   while (i != 4)
     2549      printf("Read error single register!\n");
     2550
     2551   printf("Reg.0: %08X - %08X\n", buffer[0], ret[0]);
     2552
     2553   n_err = 0;
     2554   for (n = 0; n < 100; n++) {
     2555      for (i = 0; i < N_REG; i++)
     2556         buffer[i] = (rand() << 16) | rand();
     2557      Write(T_CTRL, 0, buffer, sizeof(buffer));
     2558
     2559      memset(ret, 0, sizeof(ret));
     2560      i = Read(T_CTRL, ret, 0, sizeof(ret));
     2561      while (i != sizeof(ret)) {
     2562         printf("Read error!\n");
     2563         return;
     2564      }
     2565
     2566      for (i = 0; i < N_REG; i++) {
     2567         if (n == 0)
     2568            printf("Reg.%d: %08X - %08X\n", i, buffer[i], ret[i]);
     2569         if (buffer[i] != ret[i]) {
     2570            n_err++;
     2571         }
     2572      }
     2573   }
     2574
     2575   printf("Register test: %d errors\n", n_err);
     2576}
     2577
     2578/*------------------------------------------------------------------*/
     2579
     2580int DRSBoard::RAMTest(int flag)
     2581{
     2582#define MAX_N_BYTES  128*1024   // 128 kB
     2583
     2584   int i, j, n, bits, n_bytes, n_words, n_dwords;
     2585   unsigned int buffer[MAX_N_BYTES/4], ret[MAX_N_BYTES/4];
     2586   time_t now;
     2587
     2588   if (fBoardType == 6 && fTransport == TR_VME) {
     2589      bits = 32;
     2590      n_bytes = 128*1024; // test full 128 kB
     2591      n_words = n_bytes/2;
     2592      n_dwords = n_words/2;
     2593   }  else {
     2594      bits = 24;
     2595      n_words = 9*1024;
     2596      n_bytes = n_words * 2;
     2597      n_dwords = n_words/2;
     2598   }
     2599
     2600   if (flag & 1) {
     2601      /* integrety test */
     2602      printf("Buffer size: %d (%1.1lfk)\n", n_words * 2, n_words * 2 / 1024.0);
     2603      if (flag & 1) {
     2604         for (i = 0; i < n_dwords; i++) {
     2605            if (bits == 24)
     2606               buffer[i] = (rand() | rand() << 16) & 0x00FFFFFF;   // random 24-bit values
     2607            else
     2608               buffer[i] = (rand() | rand() << 16);                // random 32-bit values
     2609         }
     2610
     2611         Reinit();
     2612         Write(T_RAM, 0, buffer, n_bytes);
     2613         memset(ret, 0, n_bytes);
     2614         Read(T_RAM, ret, 0, n_bytes);
     2615         Reinit();
     2616
     2617         for (i = n = 0; i < n_dwords; i++) {
     2618            if (buffer[i] != ret[i]) {
     2619               n++;
     2620            }
     2621            if (i < 10)
     2622               printf("written: %08X   read: %08X\n", buffer[i], ret[i]);
     2623         }
     2624
     2625         printf("RAM test: %d errors\n", n);
     2626      }
     2627   }
     2628
     2629   /* speed test */
     2630   if (flag & 2) {
     2631      /* read continously to determine speed */
     2632      time(&now);
     2633      while (now == time(NULL));
     2634      time(&now);
     2635      i = n = 0;
     2636      do {
     2637         memset(ret, 0, n_bytes);
     2638
     2639         for (j = 0; j < 10; j++) {
     2640            Read(T_RAM, ret, 0, n_bytes);
     2641            i += n_bytes;
     2642         }
     2643
     2644         if (flag & 1) {
     2645            for (j = 0; j < n_dwords; j++)
     2646               if (buffer[j] != ret[j])
     2647                  n++;
     2648         }
     2649
     2650         if (now != time(NULL)) {
     2651            if (flag & 1)
     2652               printf("%d read/sec, %1.2lf MB/sec, %d errors\n", static_cast < int >(i / n_bytes),
     2653                      i / 1024.0 / 1024.0, n);
     2654            else
     2655               printf("%d read/sec, %1.2lf MB/sec\n", static_cast < int >(i / n_bytes),
     2656                      i / 1024.0 / 1024.0);
     2657            time(&now);
     2658            i = 0;
     2659         }
     2660
     2661         if (drs_kbhit())
     2662            break;
     2663
     2664      } while (1);
     2665
     2666      while (drs_kbhit())
     2667         getch();
     2668   }
     2669
     2670   return 0;
     2671}
     2672
     2673/*------------------------------------------------------------------*/
     2674
     2675int DRSBoard::ChipTest()
     2676{
     2677   int i, j, t;
     2678   double freq, old_freq, min, max, mean, rms;
     2679   float  waveform[1024];
     2680
     2681   Init();
     2682   SetChannelConfig(0, 8, 8);
     2683   SetDominoMode(1);
     2684   SetReadoutMode(1);
     2685   SetDominoActive(1);
     2686   SetTranspMode(0);
     2687   EnableTrigger(0, 0);
     2688   EnableTcal(1, 0);
     2689   SelectClockSource(0);
     2690   EnableAcal(1, 0);
     2691
     2692   /* test 1 GHz */
     2693   SetFrequency(1, true);
     2694   StartDomino();
     2695   Sleep(100);
     2696   if (!(GetStatusReg() & BIT_PLL_LOCKED0)) {
     2697      puts("PLL did not lock at 1 GHz");
     2698      return 0;
     2699   }
     2700
     2701   /* test up to 6 GHz */
     2702   for (freq = 5 ; freq < 6 ; freq += 0.1) {
     2703      SetFrequency(freq, false);
     2704      Sleep(10);
     2705      if (!(GetStatusReg() & BIT_PLL_LOCKED0)) {
     2706         printf("Max. frequency is %1.1lf GHz\n", old_freq);
     2707         break;
     2708      }
     2709      ReadFrequency(0, &old_freq);
     2710   }
     2711
     2712   /* read and check at 0 calibration voltage */
     2713   SetFrequency(5, true);
     2714   Sleep(10);
     2715   SoftTrigger();
     2716   while (IsBusy());
     2717   TransferWaves(0, 8);
     2718
     2719   for (i=0 ; i<8 ; i++) {
     2720      t = GetStopCell(0);
     2721      GetWave(0, i, waveform, false, t, false);
     2722      for (j=0 ; j<1024; j++)
     2723         if (waveform[j] < -100 || waveform[j] > 100) {
     2724            if (j<5) {
     2725               /* skip this cells */
     2726            } else {
     2727               printf("Cell error on channel %d, cell %d: %1.1lf mV instead 0 mV\n", i, j, waveform[j]);
     2728               return 0;
     2729            }
     2730         }
     2731   }
     2732
     2733   /* read and check at +0.5V calibration voltage */
     2734   EnableAcal(1, 0.5);
     2735   StartDomino();
     2736   SoftTrigger();
     2737   while (IsBusy());
     2738   TransferWaves(0, 8);
     2739
     2740   for (i=0 ; i<8 ; i++) {
     2741      t = GetStopCell(0);
     2742      GetWave(0, i, waveform, false, t, false);
     2743      for (j=0 ; j<1024; j++)
     2744         if (waveform[j] < 350) {
     2745            if (j<5) {
     2746               /* skip this cell */
     2747            } else {
     2748               printf("Cell error on channel %d, cell %d: %1.1lf mV instead 400 mV\n", i, j, waveform[j]);
     2749               return 0;
     2750            }
     2751         }
     2752   }
     2753
     2754   /* read and check at -0.5V calibration voltage */
     2755   EnableAcal(1, -0.5);
     2756   StartDomino();
     2757   Sleep(10);
     2758   SoftTrigger();
     2759   while (IsBusy());
     2760   TransferWaves(0, 8);
     2761
     2762   for (i=0 ; i<8 ; i++) {
     2763      t = GetStopCell(0);
     2764      GetWave(0, i, waveform, false, t, false);
     2765      for (j=0 ; j<1024; j++)
     2766         if (waveform[j] > -350) {
     2767            if (j<5) {
     2768               /* skip this cell */
     2769            } else {
     2770               printf("Cell error on channel %d, cell %d: %1.1lf mV instead -400mV\n", i, j, waveform[j]);
     2771               return 0;
     2772            }
     2773         }
     2774   }
     2775
     2776   /* check clock channel */
     2777   GetWave(0, 8, waveform, false, 0);
     2778   min = max = mean = rms = 0;
     2779   for (j=0 ; j<1024 ; j++) {
     2780      if (waveform[j] > max)
     2781         max = waveform[j];
     2782      if (waveform[j] < min)
     2783         min = waveform[j];
     2784      mean += waveform[j];
     2785   }
     2786   mean /= 1024.0;
     2787   for (j=0 ; j<1024 ; j++)
     2788      rms += (waveform[j] - mean) * (waveform[j] - mean);
     2789   rms = sqrt(rms/1024);
     2790
     2791   if (max - min < 400) {
     2792      printf("Error on clock channel amplitude: %1.1lf mV\n", max-min);
     2793      return 0;
     2794   }
     2795
     2796   if (rms < 100 || rms > 300) {
     2797      printf("Error on clock channel RMS: %1.1lf mV\n", rms);
     2798      return 0;
     2799   }
     2800
     2801   return 1;
     2802}
     2803
     2804/*------------------------------------------------------------------*/
     2805
     2806void DRSBoard::SetVoltageOffset(double offset1, double offset2)
     2807{
     2808   if (fDRSType == 3) {
     2809      SetDAC(fDAC_ROFS_1, 0.95 - offset1);
     2810      SetDAC(fDAC_ROFS_2, 0.95 - offset2);
     2811   } else if (fDRSType == 2)
     2812      SetDAC(fDAC_COFS, 0.9 - offset1);
     2813
     2814   // let DAC settle
     2815   Sleep(100);
     2816}
     2817
     2818/*------------------------------------------------------------------*/
     2819
     2820int DRSBoard::SetInputRange(double center)
     2821{
     2822   if (fBoardType == 5 || fBoardType == 6) {
     2823      // DRS4 USB Evaluation Board 1.1 + Mezzanine Board
     2824
     2825      // only allow -0.5...0.5 to 0...1.0
     2826      if (center < 0 || center > 0.5)
     2827         return 0;
     2828
     2829      // remember range
     2830      fRange = center;
     2831
     2832      // correct for sampling cell charge injection
     2833      center *= 1.125;
     2834
     2835      // set readout offset
     2836      fROFS = 1.6 - center;
     2837      SetDAC(fDAC_ROFS_1, fROFS);
     2838   }
     2839
     2840   return 1;
     2841}
     2842
     2843/*------------------------------------------------------------------*/
     2844
     2845int DRSBoard::SetExternalClockFrequency(double frequencyMHz)
     2846{
     2847   // Set the frequency of the external clock
     2848   fExternalClockFrequency = frequencyMHz;
     2849   return 0;
     2850}
     2851
     2852/*------------------------------------------------------------------*/
     2853
     2854double DRSBoard::GetExternalClockFrequency()
     2855{
     2856   // Return the frequency of the external clock
     2857   return fExternalClockFrequency;
     2858}
     2859
     2860/*------------------------------------------------------------------*/
     2861
     2862int DRSBoard::TransferWaves(int numberOfChannels)
     2863{
     2864   return TransferWaves(fWaveforms, numberOfChannels);
     2865}
     2866
     2867/*------------------------------------------------------------------*/
     2868
     2869int DRSBoard::TransferWaves(unsigned char *p, int numberOfChannels)
     2870{
     2871   return TransferWaves(p, 0, numberOfChannels - 1);
     2872}
     2873
     2874/*------------------------------------------------------------------*/
     2875
     2876int DRSBoard::TransferWaves(int firstChannel, int lastChannel)
     2877{
     2878   int offset;
     2879
     2880   if (fTransport == TR_USB)
     2881      offset = firstChannel * sizeof(short int) * kNumberOfBins;
     2882   else
     2883      offset = 0;               //in VME and USB2, always start from zero
     2884
     2885   return TransferWaves(fWaveforms + offset, firstChannel, lastChannel);
     2886}
     2887
     2888/*------------------------------------------------------------------*/
     2889
     2890int DRSBoard::TransferWaves(unsigned char *p, int firstChannel, int lastChannel)
     2891{
     2892   // Transfer all waveforms at once from VME or USB to location
     2893   int n, offset, n_requested;
     2894
     2895   if (lastChannel >= fNumberOfChips * fNumberOfChannels)
     2896      lastChannel = fNumberOfChips * fNumberOfChannels - 1;
     2897   if (lastChannel < 0) {
     2898      printf("Error: Invalid channel index %d\n", lastChannel);
     2899      return 0;
     2900   }
     2901
     2902   if (firstChannel < 0 || firstChannel > fNumberOfChips * fNumberOfChannels) {
     2903      printf("Error: Invalid channel index %d\n", firstChannel);
     2904      return 0;
     2905   }
     2906
     2907   if (fTransport == TR_VME) {
     2908      /* in VME, always transfer all waveforms, since channels sit 'next' to each other */
     2909      firstChannel = 0;
     2910      lastChannel = fNumberOfChips * fNumberOfChannels - 1;
     2911      if (fReadoutChannelConfig == 4)
     2912         lastChannel = fNumberOfChips * 5 - 1; // special mode to read only even channels + clock
     2913   }
     2914
     2915   else if (fTransport == TR_USB2) {
     2916      /* USB2 FPGA contains 9 (Eval) or 10 (Mezz) channels */
     2917      firstChannel = 0;
     2918      if (fBoardType == 5)
     2919         lastChannel = 8;
     2920      else if (fBoardType == 6)
     2921         lastChannel = 9;
     2922   }
     2923
     2924   else if (fTransport == TR_USB) {
     2925      /* USB1 FPGA contains only 16 channels */
     2926      if (lastChannel > 15)
     2927         lastChannel = 15;
     2928   }
     2929
     2930   n_requested = (lastChannel - firstChannel + 1) * sizeof(short int) * kNumberOfBins;
     2931   offset = firstChannel * sizeof(short int) * kNumberOfBins;
     2932
     2933   n = Read(T_RAM, p, offset, n_requested);
     2934   if (n != n_requested) {
     2935      printf("Error: only %d bytes out of %d read\n", n, n_requested);
     2936      return n;
     2937   }
     2938
     2939   // read trigger cells
     2940   if (fDRSType == 4) {
     2941      if (fBoardType == 5)
     2942         Read(T_STATUS, fStopCell, REG_STOP_CELL0, 2);
     2943      else {
     2944         Read(T_STATUS, fStopCell,   REG_STOP_CELL0, 2);
     2945         Read(T_STATUS, fStopCell+1, REG_STOP_CELL1, 2);
     2946         Read(T_STATUS, fStopCell+2, REG_STOP_CELL2, 2);
     2947         Read(T_STATUS, fStopCell+3, REG_STOP_CELL3, 2);
     2948      }
     2949   }
    16952950 
    1696   if (firstChannel < 0 || firstChannel > kNumberOfChips*kNumberOfChannels) {
    1697     printf("Error: Invalid channel index %d\n", firstChannel);
    1698     return 0;
    1699   }
    1700  
    1701   firstChannel = 0;
    1702   lastChannel = kNumberOfChips*kNumberOfChannels -1;
    1703  
    1704  
    1705   n_requested = (lastChannel - firstChannel + 1) * sizeof(short int) * kNumberOfBins;
    1706   offset = firstChannel * sizeof(short int) * kNumberOfBins;
    1707  
    1708   n = Read(T_RAM, p, offset, n_requested);
    1709    
    1710   // Fixme (SCC 28082008): this check is now obsolete!!!!
    1711   if (n != n_requested) {
    1712     printf("Error: only %d bytes read\n", n);
    1713     return  n;
    1714   }
    1715  
    1716   // Remember which waveforms have been transferred
    1717   for (i = firstChannel; i <= lastChannel; i++)
    1718     fWaveTransferred[i] = true;
    1719    
    1720   //fNumberOfTransferredWaves = numberOfChannels;
    1721   return n;
     2951   return n;
    17222952}
    17232953
     
    17262956int DRSBoard::DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform)
    17272957{
    1728  
    1729   return DecodeWave(fWaveforms , chipIndex, channel, waveform);
    1730 }
    1731 
    1732 /*------------------------------------------------------------------*/
    1733 
    1734 int DRSBoard::DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, unsigned short *waveform)
    1735 {
    1736 
    1737   // Get waveform
    1738   int i, offset, ind;
    1739  
    1740   // Check valid parameters
    1741   if (channel > 9 || chipIndex > 1)
    1742     return kWrongChannelOrChip;
    1743  
    1744   // Re-map channel
    1745   if (fBoardVersion == 1) {
    1746     if (channel < 8)
    1747       channel = 7 - channel;
    1748     else
    1749       channel = 16 - channel;
    1750   } else {
    1751     channel = channel;
    1752   }
    1753  
    1754   offset = (kNumberOfBins * 4) * channel;
    1755 
    1756   if (DEBUG)
    1757     printf("offset = %d (0X%X)\n",offset,offset);
    1758 
    1759   for (i = 0; i < kNumberOfBins; i++) {
    1760 
    1761     ind = i * 4 + offset;
    1762 
    1763     if (chipIndex == 0)
    1764       // Lower 12 bit
    1765       waveform[i] = ((waveforms[ind + 1] & 0x0f) << 8) | waveforms[ind];
    1766     else
    1767       // Upper 12 bit
    1768       waveform[i] = (waveforms[ind + 2] << 4) | (waveforms[ind + 1] >> 4);
    1769   }
    1770  
    1771   return kSuccess;
     2958   return DecodeWave(fWaveforms, chipIndex, channel, waveform);
     2959}
     2960
     2961/*------------------------------------------------------------------*/
     2962
     2963int DRSBoard::DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
     2964                         unsigned short *waveform)
     2965{
     2966   // Get waveform
     2967   int i, offset=0, ind;
     2968
     2969   /* check valid parameters */
     2970   assert((int)channel < fNumberOfChannels);
     2971   assert((int)chipIndex < fNumberOfChips);
     2972
     2973   /* remap channel */
     2974   if (fBoardType == 1) {
     2975      if (channel < 8)
     2976         channel = 7 - channel;
     2977      else
     2978         channel = 16 - channel;
     2979   } else if (fBoardType == 6) {
     2980      if (fReadoutChannelConfig == 7) {
     2981         if (channel < 8)
     2982            channel = 7-channel;
     2983      } else if (fReadoutChannelConfig == 4) {
     2984         if (channel == 8)
     2985            channel = 4;
     2986         else
     2987            channel = 3 - channel/2;
     2988      } else {
     2989         channel = channel / 2;
     2990         if (channel != 4)
     2991           channel = 3-channel;
     2992      }
     2993   } else
     2994      channel = channel;
     2995
     2996   // Read channel
     2997   if (fTransport == TR_USB) {
     2998      offset = kNumberOfBins * 2 * (chipIndex * 16 + channel);
     2999      for (i = 0; i < kNumberOfBins; i++) {
     3000         // 12-bit data
     3001         waveform[i] = ((waveforms[i * 2 + 1 + offset] & 0x0f) << 8) + waveforms[i * 2 + offset];
     3002      }
     3003   } else if (fTransport == TR_USB2) {
     3004
     3005      if (fBoardType == 5)
     3006         // see dpram_map_eval1.xls
     3007         offset = kNumberOfBins * 2 * (chipIndex * 16 + channel);
     3008      else if (fBoardType == 6) {
     3009         // see dpram_map_mezz1.xls mode 0-3
     3010         offset = (kNumberOfBins * 4) * (channel % 9) + 2 * (chipIndex/2);
     3011      }
     3012      for (i = 0; i < kNumberOfBins; i++) {
     3013         // 16-bit data
     3014         if (fBoardType == 5)
     3015            waveform[i] = ((waveforms[i * 2 + 1 + offset] & 0xff) << 8) + waveforms[i * 2 + offset];
     3016         else if (fBoardType == 6)
     3017            waveform[i] = ((waveforms[i * 4 + 1 + offset] & 0xff) << 8) + waveforms[i * 4 + offset];
     3018      }
     3019   } else if (fTransport == TR_VME) {
     3020
     3021      if (fBoardType == 6) {
     3022         if (fReadoutChannelConfig == 7)       // see dpram_map_mezz1.xls mode 7
     3023            offset = (kNumberOfBins * 4) * (channel % 9 + 9*(chipIndex % 2)) + 2 * (chipIndex/2);
     3024         else if (fReadoutChannelConfig == 4)  // see dpram_map_mezz1.xls mode 4
     3025            offset = (kNumberOfBins * 4) * (channel % 5 + 5*(chipIndex % 2)) + 2 * (chipIndex/2);
     3026         for (i = 0; i < kNumberOfBins; i++)
     3027            waveform[i] = ((waveforms[i * 4 + 1 + offset] & 0xff) << 8) + waveforms[i * 4 + offset];
     3028      } else {
     3029         offset = (kNumberOfBins * 4) * channel;
     3030         for (i = 0; i < kNumberOfBins; i++) {
     3031            ind = i * 4 + offset;
     3032            if (chipIndex == 0)
     3033               // lower 12 bit
     3034               waveform[i] = ((waveforms[ind + 1] & 0x0f) << 8) | waveforms[ind];
     3035            else
     3036               // upper 12 bit
     3037               waveform[i] = (waveforms[ind + 2] << 4) | (waveforms[ind + 1] >> 4);
     3038         }
     3039      }
     3040   } else {
     3041      printf("Error: invalid transport %d\n", fTransport);
     3042      return kInvalidTransport;
     3043   }
     3044   return kSuccess;
     3045}
     3046
     3047/*------------------------------------------------------------------*/
     3048
     3049int DRSBoard::GetWave(unsigned int chipIndex, unsigned char channel, float *waveform)
     3050{
     3051   return GetWave(chipIndex, channel, waveform, true, fStopCell[chipIndex], false, 0, true);
    17723052}
    17733053
     
    17753055
    17763056int DRSBoard::GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib,
    1777                       int triggerCell, bool adjustToClock, float threshold)
    1778 {
    1779 
    1780   int ret;
    1781  
    1782   ret = GetWave(fWaveforms,chipIndex,channel,waveform,responseCalib,triggerCell,adjustToClock,threshold);
    1783 
    1784   if (kRotateWave) RotateWave((int)GetTriggerCell(chipIndex),waveform); 
    1785 
    1786   return ret;
    1787 }
    1788 
    1789 /*------------------------------------------------------------------*/
    1790 
    1791 int DRSBoard::GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib,
    1792                       int triggerCell, bool adjustToClock, float threshold)
    1793 {
    1794   int ret,i;
    1795   short waveS[kNumberOfBins];
    1796 
    1797   ret = GetWave(fWaveforms,chipIndex,channel,waveS,responseCalib,triggerCell,adjustToClock,threshold);
    1798 
    1799   if (responseCalib)
    1800     for (i = 0; i < kNumberOfBins; i++)
    1801       waveform[i] = static_cast<float>(waveS[i] * GetPrecision());
    1802   else {
    1803     for (i = 0; i < kNumberOfBins; i++) {
    1804       if (fBoardVersion==4)
    1805         waveform[i] = static_cast<float>(waveS[i] / 4.095); // 12-bit corresponding to 1V
    1806       else
    1807         waveform[i] = static_cast<float>(waveS[i]);
    1808     }
    1809   }
    1810 
    1811   if (kRotateWave)
    1812     //RotateWave((int)GetTriggerCell(waveform,chipIndex),waveform); 
    1813     RotateWave((int)GetTriggerCell(chipIndex),waveform); 
    1814 
    1815   return ret;
    1816 }
    1817 
    1818 /*------------------------------------------------------------------*/
    1819 
    1820 void DRSBoard::RotateWave(int triggerCell, float *waveform)
    1821 {
    1822   int i;
    1823   float buffer[kNumberOfBins];
    1824 
    1825   memcpy((float*)buffer,(float*)waveform,sizeof(buffer));
    1826 
    1827   for (i=0;i<kNumberOfBins;i++)
    1828     waveform[i] = buffer[(i + triggerCell)%kNumberOfBins];
    1829 }
    1830 
    1831 /*------------------------------------------------------------------*/
    1832 
    1833 void DRSBoard::RotateWave(int triggerCell, short *waveform)
    1834 {
    1835   int i;
    1836   short buffer[kNumberOfBins];
    1837 
    1838   memcpy((short*)buffer,(short*)waveform,sizeof(buffer));
    1839 
    1840   for (i=0;i<kNumberOfBins;i++)
    1841     waveform[i] = buffer[(i + triggerCell)%kNumberOfBins];
    1842 }
    1843 
    1844 /*------------------------------------------------------------------*/
    1845 
    1846 
    1847 int DRSBoard::GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib,
    1848                       int triggerCell, bool adjustToClock, float threshold)
    1849 {
    1850   int ret,i;
    1851   short waveS[kNumberOfBins];
    1852 
    1853   ret = GetWave(waveforms,chipIndex,channel,waveS,responseCalib,triggerCell,adjustToClock,threshold);
    1854 
    1855   if (responseCalib)
    1856     for (i = 0; i < kNumberOfBins; i++)
    1857       waveform[i] = static_cast<float>(waveS[i] * GetPrecision());
    1858   else {
    1859     for (i = 0; i < kNumberOfBins; i++) {
    1860       if (fBoardVersion == 4)
    1861         waveform[i] = static_cast<float>(waveS[i] / 4.095); // 12-bit corresponding to 1V
    1862       else
    1863         waveform[i] = static_cast<float>(waveS[i]);
    1864     }
    1865   }
    1866   return ret;
    1867 }
    1868 
    1869 /*------------------------------------------------------------------*/
    1870 
    1871 
    1872 int DRSBoard::GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib,
    1873                       int triggerCell, bool adjustToClock, float threshold)
    1874 {
    1875   if (!fWaveTransferred[chipIndex*kNumberOfChannels+channel])
    1876     return kWaveNotAvailable;
    1877   unsigned short adcWaveform[kNumberOfBins];
    1878   int ret = DecodeWave(waveforms, chipIndex, channel, adcWaveform);
    1879   if (ret!=kSuccess)
    1880     return ret;
    1881  
    1882   return CalibrateWaveform(chipIndex, channel, adcWaveform, waveform, responseCalib,
    1883                            triggerCell, adjustToClock, threshold);
    1884 }
    1885 
    1886 /*------------------------------------------------------------------*/
    1887 
    1888 int DRSBoard::GetADCWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform)
    1889 {
    1890   return DecodeWave(chipIndex, channel, waveform);
    1891 }
    1892 
    1893 /*------------------------------------------------------------------*/
    1894 
    1895 int DRSBoard::GetADCWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel, unsigned short *waveform)
    1896 {
    1897   return DecodeWave(waveforms, chipIndex, channel, waveform);
     3057                      int triggerCell, bool adjustToClock, float threshold, bool offsetCalib)
     3058{
     3059   return GetWave(fWaveforms, chipIndex, channel, waveform, responseCalib, triggerCell, adjustToClock,
     3060                  threshold, offsetCalib);
     3061}
     3062
     3063/*------------------------------------------------------------------*/
     3064
     3065int DRSBoard::GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib,
     3066                      int triggerCell, bool adjustToClock, float threshold, bool offsetCalib)
     3067{
     3068   int ret, i;
     3069   short waveS[kNumberOfBins];
     3070   ret =
     3071       GetWave(fWaveforms, chipIndex, channel, waveS, responseCalib, triggerCell, adjustToClock, threshold,
     3072               offsetCalib);
     3073   if (responseCalib)
     3074      for (i = 0; i < kNumberOfBins; i++)
     3075         waveform[i] = static_cast < float >(static_cast <short> (waveS[i]) * GetPrecision());
     3076   else {
     3077      for (i = 0; i < kNumberOfBins; i++) {
     3078         if (fBoardType == 4 || fBoardType == 5 || fBoardType == 6) {
     3079            waveform[i] = static_cast < float >(waveS[i] * GetPrecision());
     3080         } else
     3081            waveform[i] = static_cast < float >(waveS[i]);
     3082      }
     3083   }
     3084   return ret;
     3085}
     3086
     3087/*------------------------------------------------------------------*/
     3088
     3089int DRSBoard::GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
     3090                      float *waveform, bool responseCalib, int triggerCell, bool adjustToClock,
     3091                      float threshold, bool offsetCalib)
     3092{
     3093   int ret, i;
     3094   short waveS[kNumberOfBins];
     3095   ret =
     3096       GetWave(waveforms, chipIndex, channel, waveS, responseCalib, triggerCell, adjustToClock, threshold,
     3097               offsetCalib);
     3098
     3099   if (fBoardType == 4) {
     3100      for (i = 0; i < kNumberOfBins; i++)
     3101         waveform[i] = static_cast < float >(waveS[i] / 65.535); // 16-bit corresponding to 1V
     3102   } else {
     3103      if (responseCalib) {
     3104         for (i = 0; i < kNumberOfBins; i++)
     3105            waveform[i] = static_cast < float >(waveS[i] * GetPrecision());
     3106      } else {
     3107         for (i = 0; i < kNumberOfBins; i++) {
     3108            waveform[i] = static_cast < float >(waveS[i]);
     3109         }
     3110      }
     3111   }
     3112
     3113   return ret;
     3114}
     3115
     3116/*------------------------------------------------------------------*/
     3117
     3118int DRSBoard::GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
     3119                      short *waveform, bool responseCalib, int triggerCell, bool adjustToClock,
     3120                      float threshold, bool offsetCalib)
     3121{
     3122   unsigned short adcWaveform[kNumberOfBins];
     3123   int ret = DecodeWave(waveforms, chipIndex, channel, adcWaveform);
     3124   if (ret != kSuccess)
     3125      return ret;
     3126
     3127   return CalibrateWaveform(chipIndex, channel, adcWaveform, waveform, responseCalib,
     3128                            triggerCell, adjustToClock, threshold, offsetCalib);
     3129}
     3130
     3131/*------------------------------------------------------------------*/
     3132
     3133int DRSBoard::GetRawWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform,
     3134                         bool adjustToClock)
     3135{
     3136   return GetRawWave(fWaveforms, chipIndex, channel, waveform, adjustToClock);
     3137}
     3138
     3139/*------------------------------------------------------------------*/
     3140
     3141int DRSBoard::GetRawWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
     3142                         unsigned short *waveform, bool adjustToClock)
     3143{
     3144   int i, status, tc;
     3145   unsigned short wf[kNumberOfBins];
     3146
     3147   status = DecodeWave(waveforms, chipIndex, channel, wf);
     3148
     3149   if (adjustToClock) {
     3150      tc = GetTriggerCell(chipIndex);
     3151      for (i = 0 ; i < kNumberOfBins; i++)
     3152         waveform[(i + tc) % kNumberOfBins] = wf[i];
     3153   } else {
     3154      for (i = 0 ; i < kNumberOfBins; i++)
     3155         waveform[i] = wf[i];
     3156   }
     3157
     3158   return status;
    18983159}
    18993160
     
    19023163int DRSBoard::CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform,
    19033164                                short *waveform, bool responseCalib,
    1904                                 int triggerCell, bool // adjustToClock
    1905                                 , float threshold)
    1906 {
    1907   int j;
    1908  
    1909   // Calibrate waveform
    1910   if (responseCalib) {
    1911     if (!fResponseCalibration->Calibrate(chipIndex, channel % 10, adcWaveform, waveform, triggerCell, threshold))
    1912       return kZeroSuppression; // Return immediately if below threshold
    1913   } else {
    1914     for (j = 0; j < kNumberOfBins; j++) {
    1915       waveform[j] = adcWaveform[j];
    1916     }
    1917   }
    1918   // Fix bad cells for single turn mode
    1919   if (fDominoMode == 0 && triggerCell==-1) {
    1920     waveform[0] = 2 * waveform[1] - waveform[2];
    1921     short m1 = (waveform[kNumberOfBins - 5] + waveform[kNumberOfBins - 6]) / 2;
    1922     short m2 = (waveform[kNumberOfBins - 6] + waveform[kNumberOfBins - 7]) / 2;
    1923     waveform[kNumberOfBins - 4] = m1 - 1 * (m2 - m1);
    1924     waveform[kNumberOfBins - 3] = m1 - 2 * (m2 - m1);
    1925     waveform[kNumberOfBins - 2] = m1 - 3 * (m2 - m1);
    1926     waveform[kNumberOfBins - 1] = m1 - 4 * (m2 - m1);
    1927   }
    1928   return kSuccess;
     3165                                int triggerCell, bool adjustToClock, float threshold, bool offsetCalib)
     3166{
     3167   int j;
     3168   double value;
     3169   short left, right;
     3170
     3171   // calibrate waveform
     3172   if (responseCalib) {
     3173      if (GetDRSType() == 4) {
     3174         // if Mezz though USB2 -> select correct calibration channel
     3175         if (fBoardType == 6 && (fReadoutChannelConfig == 0 || fReadoutChannelConfig == 2) &&
     3176             channel != 8)
     3177            channel++;
     3178
     3179         // Channel readout mode #4 -> select correct calibration channel
     3180         if (fBoardType == 6 && fReadoutChannelConfig == 4 && channel % 2 == 0 && channel != 8)
     3181            channel++;
     3182
     3183         for (j = 0 ; j < kNumberOfBins; j++) {
     3184            if (fCellCalibrationValid) {
     3185               value = adcWaveform[j] - fCellOffset[channel+chipIndex*9][(j + triggerCell) % kNumberOfBins];
     3186               value = value / fCellGain[channel+chipIndex*9][(j + triggerCell) % kNumberOfBins];
     3187               if (offsetCalib && channel != 8)
     3188                  value = value - fCellOffset2[channel+chipIndex*9][j] + 32768;
     3189            } else {
     3190               value = adcWaveform[j];
     3191            }
     3192            /* convert to units of 0.1 mV */
     3193            value = value / 65536.0 * 1000 * 10;
     3194
     3195            /* apply clipping */
     3196            if (channel != 8) {
     3197               if (adcWaveform[j] >= 0xFFF0 || value > (fRange * 1000 + 500) * 10)
     3198                  value = (fRange * 1000 + 500) * 10;
     3199               if (adcWaveform[j] <  0x0010 || value < (fRange * 1000 - 500) * 10)
     3200                  value = (fRange * 1000 - 500) * 10;
     3201            }
     3202
     3203            if (adjustToClock)         
     3204               waveform[(j + triggerCell) % kNumberOfBins] = (short) (value + 0.5);
     3205            else
     3206               waveform[j] = (short) (value + 0.5);
     3207         }
     3208
     3209         // check for stuck pixels and replace by average of neighbors
     3210         if (fCellCalibrationValid) {
     3211            for (j = 0 ; j < kNumberOfBins; j++) {
     3212               if (adjustToClock) {
     3213                  if (fCellOffset[channel+chipIndex*9][j] == 0) {
     3214                     left = waveform[(j-1+kNumberOfBins) % kNumberOfBins];
     3215                     right = waveform[(j+1) % kNumberOfBins];
     3216                     waveform[j] = (short) ((left+right)/2);
     3217                  }
     3218               } else {
     3219                  if (fCellOffset[channel+chipIndex*9][(j + triggerCell) % kNumberOfBins] == 0) {
     3220                     left = waveform[(j-1+kNumberOfBins) % kNumberOfBins];
     3221                     right = waveform[(j+1) % kNumberOfBins];
     3222                     waveform[j] = (short) ((left+right)/2);
     3223                  }
     3224               }
     3225            }
     3226         }
     3227
     3228      } else {
     3229         if (!fResponseCalibration->
     3230             Calibrate(chipIndex, channel % 10, adcWaveform, waveform, triggerCell, threshold, offsetCalib))
     3231            return kZeroSuppression;       // return immediately if below threshold
     3232      }
     3233   } else {
     3234      if (GetDRSType() == 4) {
     3235         // if Mezz though USB2 -> select correct calibration channel
     3236         if (fBoardType == 6 && (fReadoutChannelConfig == 0 || fReadoutChannelConfig == 2) &&
     3237             channel != 8)
     3238            channel++;
     3239         for (j = 0 ; j < kNumberOfBins; j++) {
     3240            value = adcWaveform[j];
     3241
     3242            /* convert to units of 0.1 mV */
     3243            value = (value - 32768) / 65536.0 * 1000 * 10;
     3244
     3245            /* correct for range */
     3246            value += fRange * 1000 * 10;
     3247
     3248            if (adjustToClock)         
     3249               waveform[(j + triggerCell) % kNumberOfBins] = (short) (value + 0.5);
     3250            else
     3251               waveform[j] = (short) (value + 0.5);
     3252         }
     3253      } else {
     3254         for (j = 0; j < kNumberOfBins; j++) {
     3255            if (adjustToClock) {
     3256               // rotate waveform such that waveform[0] corresponds to bin #0 on the chip
     3257               waveform[j] = adcWaveform[(kNumberOfBins-triggerCell+j) % kNumberOfBins];
     3258            } else {
     3259               waveform[j] = adcWaveform[j];
     3260            }
     3261         }
     3262      }
     3263   }
     3264
     3265   // fix bad cells for single turn mode
     3266   if (GetDRSType() == 2) {
     3267      if (fDominoMode == 0 && triggerCell == -1) {
     3268         waveform[0] = 2 * waveform[1] - waveform[2];
     3269         short m1 = (waveform[kNumberOfBins - 5] + waveform[kNumberOfBins - 6]) / 2;
     3270         short m2 = (waveform[kNumberOfBins - 6] + waveform[kNumberOfBins - 7]) / 2;
     3271         waveform[kNumberOfBins - 4] = m1 - 1 * (m2 - m1);
     3272         waveform[kNumberOfBins - 3] = m1 - 2 * (m2 - m1);
     3273         waveform[kNumberOfBins - 2] = m1 - 3 * (m2 - m1);
     3274         waveform[kNumberOfBins - 1] = m1 - 4 * (m2 - m1);
     3275      }
     3276   }
     3277
     3278   return kSuccess;
    19293279}
    19303280
     
    19333283int DRSBoard::GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period)
    19343284{
    1935   int j;
    1936   if (*time >= measurement[numberOfMeasurements - 1]) {
    1937     *time -= measurement[numberOfMeasurements - 1];
    1938     return 1;
    1939   }
    1940   if (*time < measurement[0]) {
    1941     *time = *time - measurement[0] - (numberOfMeasurements - 1) * period / 2;
    1942     return 1;
    1943   }
    1944   for (j = 0; j < numberOfMeasurements - 1; j++) {
    1945     if (*time > measurement[j] && *time <= measurement[j + 1]) {
    1946       *time =
    1947         (period / 2) / (measurement[j + 1] - measurement[j]) * (*time - measurement[j + 1]) -
    1948         (numberOfMeasurements - 2 - j) * period / 2;
     3285   int j;
     3286   if (*time >= measurement[numberOfMeasurements - 1]) {
     3287      *time -= measurement[numberOfMeasurements - 1];
    19493288      return 1;
    1950     }
    1951   }
    1952   return 0;
     3289   }
     3290   if (*time < measurement[0]) {
     3291      *time = *time - measurement[0] - (numberOfMeasurements - 1) * period / 2;
     3292      return 1;
     3293   }
     3294   for (j = 0; j < numberOfMeasurements - 1; j++) {
     3295      if (*time > measurement[j] && *time <= measurement[j + 1]) {
     3296         *time =
     3297             (period / 2) / (measurement[j + 1] - measurement[j]) * (*time - measurement[j + 1]) -
     3298             (numberOfMeasurements - 2 - j) * period / 2;
     3299         return 1;
     3300      }
     3301   }
     3302   return 0;
    19533303}
    19543304
     
    19573307int DRSBoard::GetTriggerCell(unsigned int chipIndex)
    19583308{
    1959 
    1960   return GetTriggerCell(fWaveforms,chipIndex);
    1961 }
    1962 
    1963 /*------------------------------------------------------------------*/
    1964 
    1965 int DRSBoard::GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex)
    1966 {
    1967  
    1968   int j, triggerCell;
    1969   bool calib = 0;
    1970   unsigned short baseLevel = 1000;
    1971   unsigned short triggerChannel[1024];
    1972   if (!fWaveTransferred[chipIndex*kNumberOfChannels+8])
    1973     return -1;
    1974  
    1975   GetADCWave(waveforms,chipIndex, 8, triggerChannel);
    1976   //calib = fResponseCalibration->SubtractADCOffset(chipIndex, 8, triggerChannel, triggerChannel,baseLevel); // Changed 24/10/2008, SCC
    1977 
    1978 
    1979   triggerCell = -1;
    1980   for (j = 0; j < kNumberOfBins; j++) {
    1981     if (calib) {
    1982       if (triggerChannel[j] <= baseLevel+200
    1983           && triggerChannel[(j + 1) % kNumberOfBins] > baseLevel+200) {
    1984         triggerCell = j;
    1985         break;
    1986       }
    1987     } else {
    1988       if (triggerChannel[j] >= 2000
    1989           && triggerChannel[(j + 1) % kNumberOfBins] < 2000) {
    1990         triggerCell = j;
    1991         break;
    1992       }
    1993     }
    1994   }
    1995   if (triggerCell == -1) {
    1996     return kInvalidTriggerSignal;
    1997   }
    1998   fTriggerCell = triggerCell;
    1999   return triggerCell;
    2000 }
    2001 
    2002 /*------------------------------------------------------------------*/
    2003 
    2004 int DRSBoard::GetTriggerCell(float *waveform)
    2005 {
    2006   int j, triggerCell;
    2007    
    2008   triggerCell = -1;
    2009 
    2010   for (j = 0; j < kNumberOfBins; j++)
    2011     if ((waveform[(j + 1) % kNumberOfBins]-waveform[j % kNumberOfBins]) > 400.)
    2012       triggerCell = j;
    2013  
    2014    
    2015   if (triggerCell == -1) {
    2016     return kInvalidTriggerSignal;
    2017   }
    2018   fTriggerCell = triggerCell;
    2019   return triggerCell;
    2020 
     3309   if (fDRSType == 4)
     3310      return GetStopCell(chipIndex);
     3311
     3312   return GetTriggerCell(fWaveforms, chipIndex);
     3313}
     3314
     3315/*------------------------------------------------------------------*/
     3316
     3317int DRSBoard::GetTriggerCell(unsigned char *waveforms, unsigned int chipIndex)
     3318{
     3319   int j, triggerCell;
     3320   bool calib;
     3321   unsigned short baseLevel = 1000;
     3322   unsigned short triggerChannel[1024];
     3323
     3324   if (fDRSType == 4)
     3325      return GetStopCell(chipIndex);
     3326
     3327   GetRawWave(waveforms, chipIndex, 8, triggerChannel);
     3328   calib = fResponseCalibration->SubtractADCOffset(chipIndex, 8, triggerChannel, triggerChannel, baseLevel);
     3329
     3330   triggerCell = -1;
     3331   for (j = 0; j < kNumberOfBins; j++) {
     3332      if (calib) {
     3333         if (triggerChannel[j] <= baseLevel + 200
     3334             && triggerChannel[(j + 1) % kNumberOfBins] > baseLevel + 200) {
     3335            triggerCell = j;
     3336            break;
     3337         }
     3338      } else {
     3339         if (fDRSType == 3) {
     3340            if (triggerChannel[j] <= 2000 && triggerChannel[(j + 1) % kNumberOfBins] > 2000) {
     3341               triggerCell = j;
     3342               break;
     3343            }
     3344         } else {
     3345            if (triggerChannel[j] >= 2000 && triggerChannel[(j + 1) % kNumberOfBins] < 2000) {
     3346               triggerCell = j;
     3347               break;
     3348            }
     3349         }
     3350      }
     3351   }
     3352   if (triggerCell == -1) {
     3353      return kInvalidTriggerSignal;
     3354   }
     3355   fStopCell[0] = triggerCell;
     3356   return triggerCell;
     3357}
     3358
     3359/*------------------------------------------------------------------*/
     3360
     3361int DRSBoard::GetStopCell(unsigned int chipIndex)
     3362{
     3363   return fStopCell[chipIndex];
    20213364}
    20223365
     
    20253368void DRSBoard::TestDAC(int channel)
    20263369{
    2027   // Test DAC
    2028   int status;
    2029  
    2030   do {
    2031     status = SetDAC(channel, 0);
    2032     Sleep(1000);
    2033     status = SetDAC(channel, 0.5);
    2034     Sleep(1000);
    2035     status = SetDAC(channel, 1);
    2036     Sleep(1000);
    2037     status = SetDAC(channel, 1.5);
    2038     Sleep(1000);
    2039     status = SetDAC(channel, 2);
    2040     Sleep(1000);
    2041     status = SetDAC(channel, 2.5);
    2042     Sleep(1000);
    2043   } while (status);
     3370   // Test DAC
     3371   int status;
     3372
     3373   do {
     3374      status = SetDAC(channel, 0);
     3375      Sleep(1000);
     3376      status = SetDAC(channel, 0.5);
     3377      Sleep(1000);
     3378      status = SetDAC(channel, 1);
     3379      Sleep(1000);
     3380      status = SetDAC(channel, 1.5);
     3381      Sleep(1000);
     3382      status = SetDAC(channel, 2);
     3383      Sleep(1000);
     3384      status = SetDAC(channel, 2.5);
     3385      Sleep(1000);
     3386   } while (status);
    20443387}
    20453388
     
    20483391void DRSBoard::MeasureSpeed()
    20493392{
    2050   // Measure domino sampling speed
    2051   FILE *f;
    2052   double vdr, vds, freq;
    2053  
    2054   f = fopen("speed.txt", "wt");
    2055   fprintf(f, "\t");
    2056   printf("\t");
    2057   for (vdr = 0.5; vdr <= 2.501; vdr += 0.05) {
    2058     fprintf(f, "%1.2lf\t", vdr);
    2059     printf("%1.2lf\t", vdr);
    2060   }
    2061   fprintf(f, "\n");
    2062   printf("\n");
    2063  
    2064   for (vds = 0.5; vds <= 2.501; vds += 0.05) {
    2065     fprintf(f, "%1.2lf\t", vds);
    2066     printf("%1.2lf\t", vds);
    2067    
    2068     SetDAC(fDAC_DSA, vds);
    2069     StartDomino();
    2070     Sleep(1000);
    2071     ReadFrequency(0, &freq);
    2072    
    2073     fprintf(f, "%1.3lf\t", freq);
    2074     printf("%1.3lf\t", freq);
    2075    
    2076     fprintf(f, "\n");
    2077     printf("\n");
    2078     fflush(f);
    2079   }
     3393   // Measure domino sampling speed
     3394   FILE *f;
     3395   double vdr, vds, freq;
     3396
     3397   f = fopen("speed.txt", "wt");
     3398   fprintf(f, "\t");
     3399   printf("\t");
     3400   for (vdr = 0.5; vdr <= 2.501; vdr += 0.05) {
     3401      fprintf(f, "%1.2lf\t", vdr);
     3402      printf("%1.2lf\t", vdr);
     3403   }
     3404   fprintf(f, "\n");
     3405   printf("\n");
     3406
     3407   for (vds = 0.5; vds <= 2.501; vds += 0.05) {
     3408      fprintf(f, "%1.2lf\t", vds);
     3409      printf("%1.2lf\t", vds);
     3410
     3411      SetDAC(fDAC_DSA, vds);
     3412      StartDomino();
     3413      Sleep(1000);
     3414      ReadFrequency(0, &freq);
     3415
     3416      fprintf(f, "%1.3lf\t", freq);
     3417      printf("%1.3lf\t", freq);
     3418
     3419      fprintf(f, "\n");
     3420      printf("\n");
     3421      fflush(f);
     3422   }
    20803423}
    20813424
     
    20843427void DRSBoard::InteractSpeed()
    20853428{
    2086   int status, i;
    2087   double freq, vds;
    2088  
    2089   do {
    2090     printf("DS: ");
    2091     scanf("%lf", &vds);
    2092     if (vds == 0)
    2093       break;
    2094    
    2095     SetDAC(fDAC_DSA, vds);
    2096     SetDAC(fDAC_DSB, vds);
    2097    
    2098     StartDomino();
    2099     for (i = 0; i < 4; i++) {
     3429   int status, i;
     3430   double freq, vds;
     3431
     3432   do {
     3433      printf("DS: ");
     3434      scanf("%lf", &vds);
     3435      if (vds == 0)
     3436         break;
     3437
     3438      SetDAC(fDAC_DSA, vds);
     3439      SetDAC(fDAC_DSB, vds);
     3440
     3441      StartDomino();
     3442      for (i = 0; i < 4; i++) {
     3443         Sleep(1000);
     3444
     3445         status = ReadFrequency(0, &freq);
     3446         if (!status)
     3447            break;
     3448         printf("%1.6lf GHz\n", freq);
     3449      }
     3450
     3451      /* turn BOARD_LED off */
     3452      SetLED(0);
     3453
     3454   } while (1);
     3455}
     3456
     3457/*------------------------------------------------------------------*/
     3458
     3459void DRSBoard::MonitorFrequency()
     3460{
     3461   // Monitor domino sampling frequency
     3462   int status;
     3463   unsigned int data;
     3464   double freq, dac;
     3465   FILE *f;
     3466   time_t now;
     3467   char str[256];
     3468
     3469   f = fopen("DRSBoard.log", "w");
     3470
     3471   do {
    21003472      Sleep(1000);
    2101      
     3473
    21023474      status = ReadFrequency(0, &freq);
    21033475      if (!status)
    2104         break;
    2105       printf("%1.6lf GHz\n", freq);
    2106     }
    2107    
    2108     // Turn CMC_LED off
    2109     SetLED(0);
    2110    
    2111   } while (1);
    2112 }
    2113 
    2114 /*------------------------------------------------------------------*/
    2115 
    2116 void DRSBoard::MonitorFrequency()
    2117 {
    2118   // Monitor domino sampling frequency
    2119   int status;
    2120   unsigned int data;
    2121   double freq, dac;
    2122   FILE *f;
    2123   time_t now;
    2124   char str[256];
    2125  
    2126   f = fopen("DRSBoard.log", "w");
    2127  
    2128   do {
    2129     Sleep(1000);
    2130    
    2131     status = ReadFrequency(0, &freq);
    2132     if (!status)
    2133       break;
    2134    
    2135     data = 0;
    2136     if (fBoardVersion == 1)
    2137       Read(T_STATUS, &data, REG_RDAC3, 2);
    2138     else if (fBoardVersion == 2 || fBoardVersion == 3)
    2139       Read(T_STATUS, &data, REG_RDAC1, 2);
    2140    
    2141     dac = data / 65536.0 * 2.5;
    2142     printf("%1.6lf GHz, %1.4lf V\n", freq, dac);
    2143     time(&now);
    2144     strcpy(str, ctime(&now) + 11);
    2145     str[8] = 0;
    2146    
    2147     fprintf(f, "%s %1.6lf GHz, %1.4lf V\n", str, freq, dac);
    2148     fflush(f);
    2149    
    2150   } while (!drs_kbhit());
    2151  
    2152   fclose(f);
     3476         break;
     3477
     3478      data = 0;
     3479      if (fBoardType == 1)
     3480         Read(T_STATUS, &data, REG_RDAC3, 2);
     3481      else if (fBoardType == 2 || fBoardType == 3)
     3482         Read(T_STATUS, &data, REG_RDAC1, 2);
     3483
     3484      dac = data / 65536.0 * 2.5;
     3485      printf("%1.6lf GHz, %1.4lf V\n", freq, dac);
     3486      time(&now);
     3487      strcpy(str, ctime(&now) + 11);
     3488      str[8] = 0;
     3489
     3490      fprintf(f, "%s %1.6lf GHz, %1.4lf V\n", str, freq, dac);
     3491      fflush(f);
     3492
     3493   } while (!drs_kbhit());
     3494
     3495   fclose(f);
     3496}
     3497
     3498/*------------------------------------------------------------------*/
     3499
     3500int DRSBoard::TestShift(int n)
     3501{
     3502   // Test shift register
     3503   unsigned char buffer[3];
     3504
     3505   memset(buffer, 0, sizeof(buffer));
     3506
     3507#if 0
     3508   buffer[0] = CMD_TESTSHIFT;
     3509   buffer[1] = n;
     3510
     3511   status = msend_usb(buffer, 2);
     3512   if (status != 2)
     3513      return status;
     3514
     3515   status = mrecv_usb(buffer, sizeof(buffer));
     3516   if (status != 1)
     3517      return status;
     3518#endif
     3519
     3520   if (buffer[0] == 1)
     3521      printf("Shift register %c works correctly\n", 'A' + n);
     3522   else if (buffer[0] == 2)
     3523      printf("SROUT%c does hot go high after reset\n", 'A' + n);
     3524   else if (buffer[0] == 3)
     3525      printf("SROUT%c does hot go low after 1024 clocks\n", 'A' + n);
     3526
     3527   return 1;
    21533528}
    21543529
     
    21573532unsigned int DRSBoard::GetCtrlReg()
    21583533{
    2159   unsigned int status;
    2160  
    2161   Read(T_CTRL, &status, REG_CTRL, 4);
    2162   return status;
     3534   unsigned int status;
     3535
     3536   Read(T_CTRL, &status, REG_CTRL, 4);
     3537   return status;
     3538}
     3539
     3540/*------------------------------------------------------------------*/
     3541
     3542unsigned short DRSBoard::GetConfigReg()
     3543{
     3544   unsigned short status;
     3545
     3546   Read(T_CTRL, &status, REG_CONFIG, 2);
     3547   return status;
    21633548}
    21643549
     
    21673552unsigned int DRSBoard::GetStatusReg()
    21683553{
    2169   unsigned int status;
    2170  
    2171   Read(T_STATUS, &status, REG_STATUS, 4);
    2172   return status;
    2173 }
    2174 
    2175 /*------------------------------------------------------------------*/
    2176 
    2177 int DRSBoard::EnableTcal(int flag)
    2178 {
    2179   // Enable clock channel
    2180   if (flag)
    2181     fCtrlBits |= BIT_TCAL_EN;
    2182   else
    2183     fCtrlBits &= ~BIT_TCAL_EN;
    2184  
    2185   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2186  
    2187   return 1;
     3554   unsigned int status;
     3555
     3556   Read(T_STATUS, &status, REG_STATUS, 4);
     3557   return status;
     3558}
     3559
     3560/*------------------------------------------------------------------*/
     3561
     3562int DRSBoard::EnableTcal(int freq, int level, int phase)
     3563{
     3564   fTcalFreq = freq;
     3565   fTcalLevel = level;
     3566   fTcalPhase = phase;
     3567
     3568   if (fBoardType == 6) {
     3569      ConfigureLMK(fFrequency, false, freq, phase);
     3570   } else {
     3571      // Enable clock channel
     3572      if (freq)
     3573         fCtrlBits |= BIT_TCAL_EN;
     3574      else
     3575         fCtrlBits &= ~BIT_TCAL_EN;
     3576
     3577      // Set output level, needed for gain calibration
     3578      if (fDRSType == 4) {
     3579         if (level)
     3580            fCtrlBits |= BIT_NEG_TRIGGER;
     3581         else
     3582            fCtrlBits &= ~BIT_NEG_TRIGGER;
     3583      }
     3584
     3585      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3586   }
     3587
     3588   return 1;
     3589}
     3590
     3591/*------------------------------------------------------------------*/
     3592
     3593int DRSBoard::SelectClockSource(int source)
     3594{
     3595   fTcalSource = source;
     3596
     3597   // Select clock source:
     3598   // EVAL1: synchronous (0) or asynchronous (1) (2nd quartz)
     3599   if (source)
     3600      fCtrlBits |= BIT_TCAL_SOURCE;
     3601   else
     3602      fCtrlBits &= ~BIT_TCAL_SOURCE;
     3603
     3604   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3605
     3606   return 1;
     3607}
     3608
     3609/*------------------------------------------------------------------*/
     3610
     3611int DRSBoard::SetRefclk(int source)
     3612{
     3613   // Select reference clock source to internal FPGA (0) or external P2 (1)
     3614   if (source)
     3615      fCtrlBits |= BIT_REFCLK_SOURCE;
     3616   else
     3617      fCtrlBits &= ~BIT_REFCLK_SOURCE;
     3618
     3619   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3620
     3621   return 1;
    21883622}
    21893623
     
    21923626int DRSBoard::EnableAcal(int mode, double voltage)
    21933627{
    2194   double t1, t2;
    2195  
    2196   if (mode == 0) {
    2197     // Turn calibration off
    2198     SetCalibTiming(0, 0);
    2199     fCtrlBits &= ~BIT_ACAL_EN;
    2200     Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2201   } else if (mode == 1) {
    2202     // Static calibration
    2203     SetCalibVoltage(voltage);
    2204     SetCalibTiming(0, 0);
    2205     fCtrlBits |= BIT_ACAL_EN;
    2206     Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2207   } else if (mode == 2) {
    2208     // First part calibration:
    2209     // stop domino wave after 1.2 revolutions,
    2210     // turn on calibration voltage after 0.1 revolutions
    2211    
    2212     // Ensure circulating domino wave
    2213     SetDominoMode(1);
    2214    
    2215     // Set calibration voltage but do not turn it on now
    2216     SetCalibVoltage(voltage);
    2217     fCtrlBits &= ~BIT_ACAL_EN;
    2218     Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2219    
    2220     // Calculate duration of DENABLE signal as 1.2 revolutions
    2221     t1 = 1 / fFrequency * 1024 * 1.2; // ns
    2222     t1 = static_cast<int>((t1 - 30) / 30 + 1);  // 30 ns offset, 30 ns units, rounded up
    2223     t2 = 1 / fFrequency * 1024 * 0.1; // ns
    2224     t2 = static_cast<int>((t2 - 30) / 30 + 1);  // 30 ns offset, 30 ns units, rounded up
    2225     SetCalibTiming(static_cast<int>(t1), static_cast<int>(t2));
    2226    
    2227   } else if (mode == 3) {
    2228     // Second part calibration:
    2229     // stop domino wave after 1.05 revolutions
    2230    
    2231     // Ensure circulating domino wave
    2232     SetDominoMode(1);
    2233    
    2234     // Turn on and let settle calibration voltage
    2235     SetCalibVoltage(voltage);
    2236     fCtrlBits |= BIT_ACAL_EN;
    2237     Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2238    
    2239     // Calculate duration of DENABLE signal as 1.1 revolutions
    2240     t1 = 1 / fFrequency * 1024 * 1.05;        // ns
    2241     t1 = static_cast<int>((t1 - 30) / 30 + 1);  // 30 ns offset, 30 ns units, rounded up
    2242     SetCalibTiming(static_cast<int>(t1), 0);
    2243   }
    2244  
    2245   return 1;
     3628   double t1, t2;
     3629
     3630   fAcalMode = mode;
     3631   fAcalVolt = voltage;
     3632
     3633   if (mode == 0) {
     3634      /* turn calibration off */
     3635      SetCalibTiming(0, 0);
     3636      if (fBoardType == 5 || fBoardType == 6) {
     3637         /* turn voltages off (50 Ohm analog switch!) */
     3638         SetDAC(fDAC_CALP, 0);
     3639         SetDAC(fDAC_CALN, 0);
     3640      }
     3641      fCtrlBits &= ~BIT_ACAL_EN;
     3642      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3643   } else if (mode == 1) {
     3644      /* static calibration */
     3645      SetCalibVoltage(voltage);
     3646      SetCalibTiming(0, 0);
     3647      fCtrlBits |= BIT_ACAL_EN;
     3648      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3649   } else if (mode == 2) {
     3650      /* first part calibration:
     3651         stop domino wave after 1.2 revolutions
     3652         turn on calibration voltage after 0.1 revolutions */
     3653
     3654      /* ensure circulating domino wave */
     3655      SetDominoMode(1);
     3656
     3657      /* set calibration voltage but do not turn it on now */
     3658      SetCalibVoltage(voltage);
     3659      fCtrlBits &= ~BIT_ACAL_EN;
     3660      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3661
     3662      /* calculate duration of DENABLE signal as 1.2 revolutions */
     3663      t1 = 1 / fFrequency * 1024 * 1.2; // ns
     3664      t1 = static_cast < int >((t1 - 30) / 30 + 1);     // 30 ns offset, 30 ns units, rounded up
     3665      t2 = 1 / fFrequency * 1024 * 0.1; // ns
     3666      t2 = static_cast < int >((t2 - 30) / 30 + 1);     // 30 ns offset, 30 ns units, rounded up
     3667      SetCalibTiming(static_cast < int >(t1), static_cast < int >(t2));
     3668
     3669   } else if (mode == 3) {
     3670      /* second part calibration:
     3671         stop domino wave after 1.05 revolutions */
     3672
     3673      /* ensure circulating domino wave */
     3674      SetDominoMode(1);
     3675
     3676      /* turn on and let settle calibration voltage */
     3677      SetCalibVoltage(voltage);
     3678      fCtrlBits |= BIT_ACAL_EN;
     3679      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3680
     3681      /* calculate duration of DENABLE signal as 1.1 revolutions */
     3682      t1 = 1 / fFrequency * 1024 * 1.05;        // ns
     3683      t1 = static_cast < int >((t1 - 30) / 30 + 1);     // 30 ns offset, 30 ns units, rounded up
     3684      SetCalibTiming(static_cast < int >(t1), 0);
     3685   }
     3686
     3687   return 1;
    22463688}
    22473689
     
    22503692int DRSBoard::SetCalibTiming(int t_enable, int t_cal)
    22513693{
    2252   unsigned short d;
    2253  
    2254   if (fChipVersion == 2) {
    2255     d = t_cal | (t_enable << 8);
    2256     Write(T_CTRL, REG_CALIB_TIMING, &d, 2);
    2257   }
    2258  
    2259   if (fChipVersion == 3) {
    2260     d = t_cal;
    2261     Write(T_CTRL, REG_CALIB_TIMING, &d, 2);
    2262   }
    2263  
    2264   return 1;
     3694   unsigned short d;
     3695
     3696   if (fDRSType == 2) {
     3697      d = t_cal | (t_enable << 8);
     3698      Write(T_CTRL, REG_CALIB_TIMING, &d, 2);
     3699   }
     3700
     3701   if (fDRSType == 3) {
     3702      d = t_cal;
     3703      Write(T_CTRL, REG_CALIB_TIMING, &d, 2);
     3704   }
     3705
     3706   return 1;
    22653707}
    22663708
     
    22693711int DRSBoard::SetCalibVoltage(double value)
    22703712{
    2271   // Set Calibration Voltage
    2272   SetDAC(fDAC_ACALIB, value);
    2273   return 1;
     3713   // Set Calibration Voltage
     3714   if (fBoardType == 5 || fBoardType == 6) {
     3715      if (fBoardType == 5)
     3716         value = value * (1+fFrequency/65); // rough correction factor for input current
     3717      SetDAC(fDAC_CALP, fCommonMode + value / 2);
     3718      SetDAC(fDAC_CALN, fCommonMode - value / 2);
     3719   } else
     3720      SetDAC(fDAC_ACALIB, value);
     3721   return 1;
     3722}
     3723
     3724/*------------------------------------------------------------------*/
     3725
     3726int DRSBoard::StartClearCycle()
     3727{
     3728   /* clear cycle is necessary for DRS4 to reduce noise */
     3729
     3730   fbkAcalVolt  = fAcalVolt;
     3731   fbkAcalMode  = fAcalMode;
     3732   fbkTcalFreq  = fTcalFreq;
     3733   fbkTcalLevel = fTcalLevel;
     3734
     3735   /* switch all inputs to zero */
     3736   EnableAcal(1, 0);
     3737
     3738   /* start, stop and readout of zero */
     3739   StartDomino();
     3740   SoftTrigger();
     3741
     3742   return 1;
     3743}
     3744
     3745/*------------------------------------------------------------------*/
     3746
     3747int DRSBoard::FinishClearCycle()
     3748{
     3749   while (IsBusy());
     3750
     3751   /* restore old values */
     3752   EnableAcal(fbkAcalMode, fbkAcalVolt);
     3753
     3754   return 1;
    22743755}
    22753756
     
    22783759double DRSBoard::GetTemperature()
    22793760{
    2280   // Read Out Temperature Sensor
    2281   unsigned char buffer[2];
    2282   unsigned short d;
    2283   double temperature;
    2284  
    2285   Read(T_STATUS, buffer, REG_TEMPERATURE, 2);
    2286  
    2287   d = (static_cast<unsigned int>(buffer[1]) << 8) + buffer[0];
    2288   temperature = ((d >> 3) & 0x0FFF) * 0.0625;
    2289  
    2290   return temperature;
     3761   // Read Out Temperature Sensor
     3762   unsigned char buffer[2];
     3763   unsigned short d;
     3764   double temperature;
     3765
     3766   Read(T_STATUS, buffer, REG_TEMPERATURE, 2);
     3767
     3768   d = (static_cast < unsigned int >(buffer[1]) << 8) +buffer[0];
     3769   temperature = ((d >> 3) & 0x0FFF) * 0.0625;
     3770
     3771   return temperature;
    22913772}
    22923773
     
    22953776int DRSBoard::GetTriggerBus()
    22963777{
    2297   unsigned short status;
    2298  
    2299   Read(T_STATUS, &status, REG_TRIGGER_BUS, 2);
    2300   return static_cast<int>(status);
    2301 }
    2302 
    2303 /*------------------------------------------------------------------*/
    2304 
    2305 int DRSBoard::FlashEEPROM(unsigned short serial_cmc)
    2306 {
    2307   unsigned short dac;
    2308  
    2309   // Read current DAC register
    2310   Read(T_CTRL, &dac, REG_DAC0, 2);
    2311  
    2312   // Put serial in DAC register
    2313   Write(T_CTRL, REG_DAC0, &serial_cmc, 2);
    2314  
    2315   // Execute flash
    2316   fCtrlBits |= BIT_FLASH_TRIG;
    2317   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
    2318   fCtrlBits &= ~BIT_FLASH_TRIG;
    2319  
    2320   // Wait 6 ms per word
    2321   Sleep(20);
    2322  
    2323   // Write back old DAC registers
    2324   Write(T_CTRL, REG_DAC0, &dac, 2);
    2325  
    2326   // Read back serial number
    2327   ReadSerialNumber();
    2328  
    2329   return 1;
    2330 }
    2331 
    2332 /*------------------------------------------------------------------*/
    2333 
    2334 int DRSBoard::GetTime(unsigned int chipIndex, int frequencyMHz, float *time,int triggerCell)
    2335 {
    2336   int i,irot;
    2337   DRSBoard::TimeData * init;
    2338   DRSBoard::TimeData::FrequencyData * freq;
    2339  
    2340   init = GetTimeCalibration(chipIndex);
    2341  
    2342   if (init == NULL) {
    2343     for (i = 0; i < kNumberOfBins; i++)
    2344       time[i] = static_cast<float>(i / fFrequency);
    2345     return 1;
    2346   }
    2347   freq = NULL;
    2348   for (i = 0; i < init->fNumberOfFrequencies; i++) {
    2349     if (init->fFrequency[i]->fFrequency == frequencyMHz) {
    2350       freq = init->fFrequency[i];
    2351       break;
    2352     }
    2353   }
    2354   if (freq == NULL) {
    2355     for (i = 0; i < kNumberOfBins; i++)
    2356       time[i] = static_cast<float>(i / fFrequency);
    2357     return 1;
    2358   }
    2359   for (i = 0; i < kNumberOfBins; i++) {
    2360     irot = i;
    2361     if (triggerCell>-1)
    2362       irot = (triggerCell + i) % kNumberOfBins;
    2363     if (triggerCell + i < kNumberOfBins)
    2364       time[i] = static_cast<float>((freq->fBin[irot] - freq->fBin[triggerCell]) / fFrequency);
    2365     else
    2366       time[i] = static_cast<float>((freq->fBin[irot] - freq->fBin[triggerCell] + freq->fBin[kNumberOfBins - 1] -
    2367                                     2 * freq->fBin[0] + freq->fBin[1]) / fFrequency);
    2368   }
    2369   return 1;
     3778   unsigned short status;
     3779
     3780   Read(T_STATUS, &status, REG_TRIGGER_BUS, 2);
     3781   return static_cast < int >(status);
     3782}
     3783
     3784/*------------------------------------------------------------------*/
     3785
     3786int DRSBoard::SetBoardSerialNumber(unsigned short serialNumber)
     3787{
     3788   unsigned char buf[32768];
     3789
     3790   unsigned short dac;
     3791
     3792   if (fDRSType < 4) {
     3793      // read current DAC register
     3794      Read(T_CTRL, &dac, REG_DAC0, 2);
     3795
     3796      // put serial in DAC register
     3797      Write(T_CTRL, REG_DAC0, &serialNumber, 2);
     3798
     3799      // execute flash
     3800      fCtrlBits |= BIT_EEPROM_WRITE_TRIG;
     3801      Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3802      fCtrlBits &= ~BIT_EEPROM_WRITE_TRIG;
     3803
     3804      // wait 6ms per word
     3805      Sleep(20);
     3806
     3807      // write back old DAC registers
     3808      Write(T_CTRL, REG_DAC0, &dac, 2);
     3809
     3810      // read back serial number
     3811      ReadSerialNumber();
     3812
     3813   } else if (fDRSType == 4) {
     3814      /* merge serial number into eeprom page #0 */
     3815      ReadEEPROM(0, buf, sizeof(buf));
     3816      buf[0] = serialNumber & 0xFF;
     3817      buf[1] = serialNumber >> 8;
     3818      WriteEEPROM(0, buf, sizeof(buf));
     3819
     3820      /* erase DPRAM */
     3821      memset(buf, 0, sizeof(buf));
     3822      Write(T_RAM, 0, buf, sizeof(buf));
     3823
     3824      /* read back EEPROM */
     3825      ReadEEPROM(0, buf, sizeof(buf));
     3826
     3827      /* check if correctly set */
     3828      if (((buf[1] << 8) | buf[0]) != serialNumber)
     3829         return 0;
     3830
     3831      fBoardSerialNumber = serialNumber;
     3832   }
     3833
     3834   return 1;
     3835}
     3836
     3837/*------------------------------------------------------------------*/
     3838
     3839int DRSBoard::ReadEEPROM(unsigned short page, void *buffer, int size)
     3840{
     3841   int i;
     3842   unsigned long status;
     3843   // write eeprom page number
     3844   if (fBoardType == 5)
     3845      Write(T_CTRL, REG_EEPROM_PAGE_EVAL, &page, 2);
     3846   else if (fBoardType == 6)
     3847      Write(T_CTRL, REG_EEPROM_PAGE_MEZZ, &page, 2);
     3848   else return -1;
     3849       
     3850   // execute eeprom read
     3851   fCtrlBits |= BIT_EEPROM_READ_TRIG;
     3852   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3853   fCtrlBits &= ~BIT_EEPROM_READ_TRIG;
     3854
     3855   // poll on serial_busy flag
     3856   for (i=0 ; i<100 ; i++) {
     3857      Read(T_STATUS, &status, REG_STATUS, 4);
     3858      if ((status & BIT_SERIAL_BUSY) == 0) break;
     3859      Sleep(10);
     3860   }
     3861
     3862   return Read(T_RAM, buffer, 0, size);
     3863}
     3864
     3865/*------------------------------------------------------------------*/
     3866
     3867int DRSBoard::WriteEEPROM(unsigned short page, void *buffer, int size)
     3868{
     3869   int i;
     3870   unsigned long status;
     3871
     3872   // write eeprom page number
     3873   if (fBoardType == 5)
     3874      Write(T_CTRL, REG_EEPROM_PAGE_EVAL, &page, 2);
     3875   else if (fBoardType == 6)
     3876      Write(T_CTRL, REG_EEPROM_PAGE_MEZZ, &page, 2);
     3877   else
     3878      return -1;
     3879
     3880   // write eeprom page to RAM
     3881   Write(T_RAM, 0, buffer, size);
     3882
     3883   // execute eeprom write
     3884   fCtrlBits |= BIT_EEPROM_WRITE_TRIG;
     3885   Write(T_CTRL, REG_CTRL, &fCtrlBits, 4);
     3886   fCtrlBits &= ~BIT_EEPROM_WRITE_TRIG;
     3887
     3888   // poll on serail_busy flag
     3889   for (i=0 ; i<500 ; i++) {
     3890      Read(T_STATUS, &status, REG_STATUS, 4);
     3891      if ((status & BIT_SERIAL_BUSY) == 0)
     3892         break;
     3893      Sleep(10);
     3894   }
     3895
     3896   return 1;
     3897}
     3898
     3899/*------------------------------------------------------------------*/
     3900
     3901int DRSBoard::GetTime(unsigned int chipIndex, float *time, bool tcalibrated, bool rotated)
     3902{
     3903   int i;
     3904
     3905   /* for DRS2, please use function below */
     3906   if (fDRSType < 4)
     3907      return GetTime(chipIndex, fFrequency, time, tcalibrated, rotated);
     3908
     3909   if (!fTimingCalibrationValid || !tcalibrated || fabs(fTimingCalibratedFrequency - fFrequency)>0.01) {
     3910      double t0 = fStopCell[chipIndex] / fFrequency;
     3911      for (i = 0; i < kNumberOfBins; i++) {
     3912         if (rotated)
     3913            time[i] = static_cast < float >(((i+fStopCell[chipIndex]) % kNumberOfBins) / fFrequency - t0);
     3914         else
     3915            time[i] = static_cast < float >(i / fFrequency);
     3916         if (time[i] < 0)
     3917            time[i] += static_cast < float > (kNumberOfBins / fFrequency);
     3918      }
     3919      return 1;
     3920   }
     3921
     3922   double t0 = fCellT[chipIndex][fStopCell[chipIndex]];
     3923
     3924   for (i=0 ; i<kNumberOfBins ; i++) {
     3925      if (rotated)
     3926         time[i] = static_cast < float > (fCellT[chipIndex][(i+fStopCell[chipIndex]) % kNumberOfBins] - t0);
     3927      else
     3928         time[i] = static_cast < float > (fCellT[chipIndex][i]);
     3929      if (time[i] < 0)
     3930         time[i] += static_cast < float > (kNumberOfBins / fFrequency);
     3931   }
     3932   return 1;
     3933}
     3934
     3935/*------------------------------------------------------------------*/
     3936
     3937int DRSBoard::GetTime(unsigned int chipIndex, double freqGHz, float *time, bool tcalibrated, bool rotated)
     3938{
     3939   /* for DRS4, use function above */
     3940   if (fDRSType == 4)
     3941      return GetTime(chipIndex, time, tcalibrated, rotated);
     3942
     3943   int i, irot;
     3944   DRSBoard::TimeData * init;
     3945   DRSBoard::TimeData::FrequencyData * freq;
     3946   int frequencyMHz = (int)(freqGHz*1000);
     3947
     3948   init = GetTimeCalibration(chipIndex);
     3949
     3950   if (init == NULL) {
     3951      for (i = 0; i < kNumberOfBins; i++)
     3952         time[i] = static_cast < float >(i / fFrequency);
     3953      return 1;
     3954   }
     3955   freq = NULL;
     3956   for (i = 0; i < init->fNumberOfFrequencies; i++) {
     3957      if (init->fFrequency[i]->fFrequency == frequencyMHz) {
     3958         freq = init->fFrequency[i];
     3959         break;
     3960      }
     3961   }
     3962   if (freq == NULL) {
     3963      for (i = 0; i < kNumberOfBins; i++)
     3964         time[i] = static_cast < float >(i / fFrequency);
     3965      return 1;
     3966   }
     3967   for (i = 0; i < kNumberOfBins; i++) {
     3968      irot = (fStopCell[chipIndex] + i) % kNumberOfBins;
     3969      if (fStopCell[chipIndex] + i < kNumberOfBins)
     3970         time[i] = static_cast < float >((freq->fBin[irot] - freq->fBin[fStopCell[chipIndex]]) / fFrequency);
     3971      else
     3972      time[i] =
     3973          static_cast <
     3974          float
     3975          >((freq->fBin[irot] - freq->fBin[fStopCell[chipIndex]] + freq->fBin[kNumberOfBins - 1] - 2 * freq->fBin[0] +
     3976             freq->fBin[1]) / fFrequency);
     3977   }
     3978   return 1;
    23703979}
    23713980
     
    23743983bool DRSBoard::InitTimeCalibration(unsigned int chipIndex)
    23753984{
    2376   return GetTimeCalibration(chipIndex, true) != NULL;
    2377 }
    2378 
    2379 /*------------------------------------------------------------------*/
    2380 
    2381 DRSBoard::TimeData *DRSBoard::GetTimeCalibration(unsigned int chipIndex, bool reinit)
    2382 {
    2383   int i, l, index;
    2384   char *cstop;
    2385   char fileName[500];
    2386   char error[240];
    2387   PMXML_NODE node, rootNode, mainNode;
    2388  
    2389   index = fNumberOfTimeData;
    2390   for (i = 0; i < fNumberOfTimeData; i++) {
    2391     if (fTimeData[i]->fChip == static_cast < int >(chipIndex)) {
    2392       if (!reinit)
    2393         return fTimeData[i];
    2394       else {
    2395         index = i;
    2396         break;
    2397       }
    2398     }
    2399   }
    2400  
    2401   fTimeData[index] = new DRSBoard::TimeData();
    2402   DRSBoard::TimeData * init = fTimeData[index];
    2403  
    2404   init->fChip = chipIndex;
    2405  
    2406   for (i = 0; i < init->kMaxNumberOfFrequencies; i++) {
    2407     if (i <= 499 || (i >= 501 && i <= 999) || (i >= 1001 && i <= 1499) || (i >= 1501 && i <= 1999) || (i >= 2001 && i <= 2499) || i >= 2501)
    2408       continue;
    2409     sprintf(fileName, "%s/board%d/TimeCalib_board%d_chip%d_%dMHz.xml", fCalibDirectory, fCMCSerialNumber,
    2410             fCMCSerialNumber, chipIndex, i);
    2411     rootNode = mxml_parse_file(fileName, error, sizeof(error));
    2412     if (rootNode == NULL)
    2413       continue;
    2414    
    2415     init->fFrequency[init->fNumberOfFrequencies] = new DRSBoard::TimeData::FrequencyData();
    2416     init->fFrequency[init->fNumberOfFrequencies]->fFrequency = i;
    2417    
    2418     mainNode = mxml_find_node(rootNode, "/DRSTimeCalibration");
    2419    
    2420     for (l = 0; l < kNumberOfBins; l++) {
    2421       node = mxml_subnode(mainNode, l + 2);
    2422       init->fFrequency[init->fNumberOfFrequencies]->fBin[l] = strtod(mxml_get_value(node), &cstop);
    2423     }
    2424     mxml_free_tree(rootNode);
    2425     init->fNumberOfFrequencies++;
    2426   }
    2427   if (init->fNumberOfFrequencies == 0) {
    2428     printf("Board %d --> Could not find time calibration file\n", GetCMCSerialNumber());
    2429   }
    2430  
    2431   if (index == fNumberOfTimeData)
    2432     fNumberOfTimeData++;
    2433  
    2434   return fTimeData[index];
     3985   return GetTimeCalibration(chipIndex, true) != NULL;
     3986}
     3987
     3988/*------------------------------------------------------------------*/
     3989
     3990DRSBoard::TimeData * DRSBoard::GetTimeCalibration(unsigned int chipIndex, bool reinit)
     3991{
     3992   int i, l, index;
     3993   char *cstop;
     3994   char fileName[500];
     3995   char error[240];
     3996   PMXML_NODE node, rootNode, mainNode;
     3997
     3998   index = fNumberOfTimeData;
     3999   for (i = 0; i < fNumberOfTimeData; i++) {
     4000      if (fTimeData[i]->fChip == static_cast < int >(chipIndex)) {
     4001         if (!reinit)
     4002            return fTimeData[i];
     4003         else {
     4004            index = i;
     4005            break;
     4006         }
     4007      }
     4008   }
     4009
     4010   fTimeData[index] = new DRSBoard::TimeData();
     4011   DRSBoard::TimeData * init = fTimeData[index];
     4012
     4013   init->fChip = chipIndex;
     4014
     4015   for (i = 0; i < init->kMaxNumberOfFrequencies; i++) {
     4016      if (i <= 499 || (i >= 501 && i <= 999) || (i >= 1001 && i <= 1499) || (i >= 1501 && i <= 1999) ||
     4017          (i >= 2001 && i <= 2499) || i >= 2501)
     4018         continue;
     4019      sprintf(fileName, "%s/board%d/TimeCalib_board%d_chip%d_%dMHz.xml", fCalibDirectory, fBoardSerialNumber,
     4020              fBoardSerialNumber, chipIndex, i);
     4021      rootNode = mxml_parse_file(fileName, error, sizeof(error));
     4022      if (rootNode == NULL)
     4023         continue;
     4024
     4025      init->fFrequency[init->fNumberOfFrequencies] = new DRSBoard::TimeData::FrequencyData();
     4026      init->fFrequency[init->fNumberOfFrequencies]->fFrequency = i;
     4027
     4028      mainNode = mxml_find_node(rootNode, "/DRSTimeCalibration");
     4029
     4030      for (l = 0; l < kNumberOfBins; l++) {
     4031         node = mxml_subnode(mainNode, l + 2);
     4032         init->fFrequency[init->fNumberOfFrequencies]->fBin[l] = strtod(mxml_get_value(node), &cstop);
     4033      }
     4034      mxml_free_tree(rootNode);
     4035      init->fNumberOfFrequencies++;
     4036   }
     4037   if (init->fNumberOfFrequencies == 0) {
     4038      printf("Board %d --> Could not find time calibration file\n", GetBoardSerialNumber());
     4039   }
     4040
     4041   if (index == fNumberOfTimeData)
     4042      fNumberOfTimeData++;
     4043
     4044   return fTimeData[index];
    24354045}
    24364046
     
    24394049void DRSBoard::SetCalibrationDirectory(const char *calibrationDirectoryPath)
    24404050{
    2441   strncpy(fCalibDirectory, calibrationDirectoryPath, strlen(calibrationDirectoryPath));
    2442   fCalibDirectory[strlen(calibrationDirectoryPath)] = 0;
     4051   strncpy(fCalibDirectory, calibrationDirectoryPath, strlen(calibrationDirectoryPath));
     4052   fCalibDirectory[strlen(calibrationDirectoryPath)] = 0;
    24434053};
    24444054
     
    24474057void DRSBoard::GetCalibrationDirectory(char *calibrationDirectoryPath)
    24484058{
    2449   strncpy(calibrationDirectoryPath, fCalibDirectory, strlen(fCalibDirectory));
    2450   calibrationDirectoryPath[strlen(fCalibDirectory)] = 0;
     4059   strncpy(calibrationDirectoryPath, fCalibDirectory, strlen(fCalibDirectory));
     4060   calibrationDirectoryPath[strlen(fCalibDirectory)] = 0;
    24514061};
    24524062
     
    24554065void DRSBoard::LinearRegression(double *x, double *y, int n, double *a, double *b)
    24564066{
    2457   int i;
    2458   double sx, sxx, sy, sxy;
    2459  
    2460   sx = sxx = sy = sxy = 0;
    2461   for (i = 0; i < n; i++) {
    2462     sx  += x[i];
    2463     sxx += x[i] * x[i];
    2464     sy  += y[i];
    2465     sxy += x[i] * y[i];
    2466   }
    2467  
    2468   *a = (n * sxy - sx*sy) / (n * sxx - sx * sx);
    2469   *b = (sy - *a * sx) / n;
     4067   int i;
     4068   double sx, sxx, sy, sxy;
     4069
     4070   sx = sxx = sy = sxy = 0;
     4071   for (i = 0; i < n; i++) {
     4072      sx += x[i];
     4073      sxx += x[i] * x[i];
     4074      sy += y[i];
     4075      sxy += x[i] * y[i];
     4076   }
     4077
     4078   *a = (n * sxy - sx * sy) / (n * sxx - sx * sx);
     4079   *b = (sy - *a * sx) / n;
     4080}
     4081
     4082/*------------------------------------------------------------------*/
     4083
     4084void DRSBoard::ReadSingleWaveform(int nChip, int nChan,
     4085                                  unsigned short wf[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins],
     4086                                  bool rotated)
     4087{
     4088   int i, j, k, tc;
     4089
     4090   StartDomino();
     4091   SoftTrigger();
     4092   while (IsBusy());
     4093   TransferWaves();
     4094
     4095   for (i=0 ; i<nChip ; i++) {
     4096      tc = GetTriggerCell(i);
     4097
     4098      for (j=0 ; j<nChan ; j++) {
     4099         GetRawWave(i, j, wf[i][j], rotated);
     4100         if (!rotated) {
     4101            for (k=0 ; k<kNumberOfBins ; k++) {
     4102               /* do primary offset calibration */
     4103               wf[i][j][k] = wf[i][j][k] - fCellOffset[j+i*9][(k + tc) % kNumberOfBins] + 32768;
     4104            }
     4105         }
     4106      }
     4107   }
     4108}
     4109     
     4110#define WFH_SIZE 100
     4111
     4112static unsigned short wfh[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins][WFH_SIZE];
     4113static float weight[] = {
     4114   0.1f,
     4115   0.2f,
     4116   0.4f,
     4117   0.6f,
     4118   0.8f,
     4119   1.0f,
     4120   1.0f,
     4121   1.0f,
     4122   0.8f,
     4123   0.6f,
     4124   0.4f,
     4125   0.2f,
     4126   0.1f,
     4127};
     4128static unsigned short swf[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins];
     4129static unsigned short htmp[WFH_SIZE];
     4130static float          center[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins];
     4131static int            icenter[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins];
     4132
     4133int DRSBoard::AverageWaveforms(DRSCallback *pcb, int nChip, int nChan,
     4134                               int prog1, int prog2, unsigned short *awf, int n, bool rotated)
     4135{
     4136   int i, j, k, l, prog, old_prog = 0;
     4137   float cm;
     4138
     4139   if (pcb != NULL)
     4140      pcb->Progress(prog1);
     4141
     4142   memset(center, 0, sizeof(center));
     4143
     4144   for (i=0 ; i<n; i++) {
     4145      ReadSingleWaveform(nChip, nChan, swf, rotated);
     4146
     4147      for (j=0 ; j<nChip ; j++) {
     4148         for (k=0 ; k<nChan ; k++) {
     4149            if (i > 5) {
     4150               /* calculate and subtract common mode */
     4151               for (l=0,cm=0 ; l<kNumberOfBins ; l++)
     4152                  cm += swf[j][k][l] - 32768;
     4153               cm /= kNumberOfBins;
     4154               for (l=0 ; l<kNumberOfBins ; l++)
     4155                  center[j][k][l] += swf[j][k][l]- cm;
     4156            }
     4157         }
     4158      }
     4159
     4160      prog = (int)(((double)i/n)*(prog2-prog1)+prog1);
     4161      if (prog > old_prog) {
     4162         old_prog = prog;
     4163         if (pcb != NULL)
     4164            pcb->Progress(prog);
     4165      }
     4166   }
     4167
     4168   for (i=0 ; i<nChip ; i++)
     4169      for (j=0 ; j<nChan ; j++)
     4170         for (k=0 ; k<kNumberOfBins ; k++)
     4171            awf[(i*nChan+j)*kNumberOfBins+k] = (unsigned short)(center[i][j][k]/(n-6) + 0.5);
     4172   
     4173   return 1;
     4174}
     4175
     4176int DRSBoard::RobustAverageWaveforms(DRSCallback *pcb, int nChip, int nChan,
     4177                               int prog1, int prog2, unsigned short *awf, int n, bool rotated)
     4178{
     4179   int i, j, k, l, prog, old_prog = 0;
     4180   int nw, bin, max, imax;
     4181   float mean, norm;
     4182
     4183   if (pcb != NULL)
     4184      pcb->Progress(prog1);
     4185
     4186   memset(wfh, 0, sizeof(wfh));
     4187   memset(center, 0, sizeof(center));
     4188
     4189   /* obtain center of histograms */
     4190   for (i=0 ; i<10 ; i++) {
     4191      ReadSingleWaveform(nChip, nChan, swf, rotated);
     4192      for (j=0 ; j<nChip ; j++)
     4193         for (k=0 ; k<nChan ; k++)
     4194            for (l=0 ; l<kNumberOfBins ; l++) {
     4195               center[j][k][l] += swf[j][k][l]/10.0f;
     4196            }
     4197
     4198      /* update progress bar */
     4199      prog = (int)(((double)i/(n+10))*(prog2-prog1)+prog1);
     4200      if (prog > old_prog) {
     4201         old_prog = prog;
     4202         if (pcb != NULL)
     4203            pcb->Progress(prog);
     4204      }
     4205   }
     4206   for (j=0 ; j<nChip ; j++)
     4207      for (k=0 ; k<nChan ; k++)
     4208         for (l=0 ; l<kNumberOfBins ; l++)
     4209            icenter[j][k][l] = (int)(center[j][k][l]/16+0.5)*16;
     4210
     4211   /* fill histograms */
     4212   for (i=0 ; i<n ; i++) {
     4213      ReadSingleWaveform(nChip, nChan, swf, rotated);
     4214      for (j=0 ; j<nChip ; j++)
     4215         for (k=0 ; k<nChan ; k++)
     4216            for (l=0 ; l<kNumberOfBins ; l++) {
     4217               bin = (swf[j][k][l]-icenter[j][k][l])/16+WFH_SIZE/2;
     4218               if (bin < 0)
     4219                  bin = 0;
     4220               if (bin > WFH_SIZE-1)
     4221                  bin = WFH_SIZE-1;
     4222               wfh[j][k][l][bin]++;
     4223            }
     4224
     4225      /* update progress bar */
     4226      prog = (int)(((double)(i+10)/(n+10))*(prog2-prog1)+prog1);
     4227      if (prog > old_prog) {
     4228         old_prog = prog;
     4229         if (pcb != NULL)
     4230            pcb->Progress(prog);
     4231      }
     4232   }
     4233
     4234   /*
     4235   FILE *fh = fopen("calib.csv", "wt");
     4236   for (i=40 ; i<60 ; i++) {
     4237      for (j=0 ; j<WFH_SIZE ; j++)
     4238         fprintf(fh, "%d;", wfh[0][0][i][j]);
     4239      fprintf(fh, "\n");
     4240   }
     4241   fclose(fh);
     4242   */
     4243
     4244   /* shift histograms to center */
     4245   for (i=0 ; i<nChip ; i++) {
     4246      for (j=0 ; j<nChan ; j++) {
     4247         for (k=0 ; k<kNumberOfBins ; k++) {
     4248            max = imax = 0;
     4249            for (l=0 ; l<WFH_SIZE ; l++) {
     4250               if (wfh[i][j][k][l] > max) {
     4251                  max = wfh[i][j][k][l];
     4252                  imax = l;
     4253               }
     4254            }
     4255            for (l=0 ; l<WFH_SIZE ; l++) {
     4256               bin = l+imax-WFH_SIZE/2;
     4257               if (bin < 0 || bin > WFH_SIZE-1)
     4258                  htmp[l] = 0;
     4259               else
     4260                  htmp[l] = wfh[i][j][k][bin];
     4261            }
     4262            for (l=0 ; l<WFH_SIZE ; l++)
     4263               wfh[i][j][k][l] = htmp[l];
     4264            icenter[i][j][k] += (imax-WFH_SIZE/2)*16;
     4265         }
     4266      }
     4267   }
     4268
     4269   /* do a weighted average */
     4270   nw = sizeof(weight)/sizeof(float);
     4271   for (i=0 ; i<nChip ; i++) {
     4272      for (j=0 ; j<nChan ; j++) {
     4273         for (k=0 ; k<kNumberOfBins ; k++) {
     4274            mean = norm = 0;
     4275            for (l=0 ; l<nw ; l++) {
     4276               mean += wfh[i][j][k][WFH_SIZE/2 + l-nw/2] * weight[l] * (icenter[i][j][k] + (l-nw/2)*16);
     4277               norm += wfh[i][j][k][WFH_SIZE/2 + l-nw/2] * weight[l];
     4278            }
     4279            if (norm == 0)
     4280               awf[(i*nChan+j)*kNumberOfBins+k] = 0;
     4281            else
     4282               awf[(i*nChan+j)*kNumberOfBins+k] = (unsigned short) (mean/norm+0.5);
     4283         }
     4284      }
     4285   }
     4286
     4287   /*
     4288   FILE *fh = fopen("calib.csv", "wt");
     4289   for (i=40 ; i<60 ; i++) {
     4290      fprintf(fh, "%d;", icenter[0][0][0] + (i - WFH_SIZE/2)*16);
     4291      fprintf(fh, "%d;", wfh[0][0][0][i]);
     4292      if (i == 50)
     4293         fprintf(fh, "%d;", awf[0]);
     4294      fprintf(fh, "\n");
     4295   }
     4296   fclose(fh);
     4297   */
     4298
     4299   if (pcb != NULL)
     4300      pcb->Progress(prog2);
     4301
     4302   return 1;
     4303}
     4304
     4305/*------------------------------------------------------------------*/
     4306
     4307int idx[4][10] = {
     4308   {  0,  2,  4,  6,  8, 18, 20, 22, 24, 26 },
     4309   {  1,  3,  5,  7, 39, 19, 21, 23, 25, 39 },
     4310   {  9, 11, 13, 15, 17, 27, 29, 31, 33, 35 },
     4311   { 10, 12, 14, 16, 39, 28, 30, 32, 34, 39 },
     4312};
     4313
     4314#define F1(x) ((int) (84.0/24 * (x)))
     4315#define F2(x) ((int) (92.0/8 * (x)))
     4316
     4317static unsigned short wft[kNumberOfChipsMax*kNumberOfChannelsMax*kNumberOfChipsMax][1024],
     4318                      wf1[kNumberOfChipsMax*kNumberOfChannelsMax*kNumberOfChipsMax][1024],
     4319                      wf2[kNumberOfChipsMax*kNumberOfChannelsMax*kNumberOfChipsMax][1024],
     4320                      wf3[kNumberOfChipsMax*kNumberOfChannelsMax*kNumberOfChipsMax][1024];
     4321
     4322int DRSBoard::CalibrateVolt(DRSCallback *pcb)
     4323{
     4324int    i, j, nChan, timingChan=0, chip, config, p, clkon, refclk, trg1, trg2, n_stuck;
     4325double f, r;
     4326unsigned short buf[kNumberOfBins*kNumberOfCalibChannelsV4*2];
     4327   
     4328   f       = fFrequency;
     4329   r       = fRange;
     4330   clkon   = (GetCtrlReg() & BIT_TCAL_EN) > 0;
     4331   refclk  = (GetCtrlReg() & BIT_REFCLK_SOURCE) > 0;
     4332   trg1    = fTriggerEnable1;
     4333   trg2    = fTriggerEnable2;
     4334
     4335   Init();
     4336   fFrequency = f;
     4337   SetRefclk(refclk);
     4338   SetFrequency(fFrequency, true);
     4339   SetDominoMode(1);
     4340   SetDominoActive(1);
     4341   SetReadoutMode(1);
     4342   SetInputRange(r);
     4343   if (fBoardType == 5)
     4344      SelectClockSource(0);
     4345   else if (fBoardType == 6)
     4346      SetRefclk(refclk);
     4347   EnableTrigger(0, 0);
     4348
     4349   StartDomino();
     4350
     4351   nChan = 0;
     4352
     4353   if (fBoardType == 5) {
     4354      nChan = 9;
     4355      timingChan = 8;
     4356
     4357      /* measure offset */
     4358      EnableAcal(0, 0); // no inputs signal is allowed during calibration!
     4359      EnableTcal(0, 0);
     4360      Sleep(100);
     4361      RobustAverageWaveforms(pcb, 1, nChan, 0, 33, wf1[0], 500, true);
     4362
     4363      /* measure gain at upper range */
     4364      EnableAcal(1, fRange+0.4);
     4365      EnableTcal(0, 1);
     4366      Sleep(100);
     4367      RobustAverageWaveforms(pcb, 1, nChan, 33, 66, wf2[0], 500, true);
     4368
     4369   } else if (fBoardType == 6) {
     4370      if (fTransport == TR_USB2) {
     4371         nChan = 36;
     4372         timingChan = 8;
     4373         memset(wf1, 0, sizeof(wf1));
     4374         memset(wf2, 0, sizeof(wf2));
     4375         memset(wf3, 0, sizeof(wf3));
     4376         for (config=p=0 ; config<4 ; config++) {
     4377            SetChannelConfig(config, 8, 8);
     4378
     4379            /* measure offset */
     4380            EnableAcal(1, 0);
     4381            EnableTcal(0, 0);
     4382            Sleep(100);
     4383            RobustAverageWaveforms(pcb, 0, 10, F1(p), F1(p+1), wft[0], 500, true); p++;
     4384            for (i=0 ; i<5 ; i++)
     4385               memcpy(wf1[idx[config][i]], wft[i*2], sizeof(float)*kNumberOfBins);
     4386            RobustAverageWaveforms(pcb, 2, 10, F1(p), F1(p+1), wft[0], 500, true); p++;
     4387            for (i=0 ; i<5 ; i++)
     4388               memcpy(wf1[idx[config][i+5]], wft[i*2], sizeof(float)*kNumberOfBins);
     4389
     4390            /* measure gain at +400 mV */
     4391            EnableAcal(1, 0.4);
     4392            EnableTcal(0, 0);
     4393            Sleep(100);
     4394            RobustAverageWaveforms(pcb, 0, 8, F1(p), F1(p+1), wft[0], 500, true); p++;
     4395            for (i=0 ; i<4 ; i++)
     4396               memcpy(wf2[idx[config][i]], wft[i*2], sizeof(float)*kNumberOfBins);
     4397            RobustAverageWaveforms(pcb, 2, 8, F1(p), F1(p+1), wft[0], 500, true); p++;
     4398            for (i=0 ; i<4 ; i++)
     4399               memcpy(wf2[idx[config][i+5]], wft[i*2], sizeof(float)*kNumberOfBins);
     4400
     4401            /* measure gain at -400 mV */
     4402            EnableAcal(1, -0.4);
     4403            EnableTcal(0, 1);
     4404            Sleep(100);
     4405            RobustAverageWaveforms(pcb, 0, 8, F1(p), F1(p+1), wft[0], 500, true); p++;
     4406            for (i=0 ; i<4 ; i++)
     4407               memcpy(wf3[idx[config][i]], wft[i], sizeof(float)*kNumberOfBins);
     4408            RobustAverageWaveforms(pcb, 2, 8, F1(p), F1(p+1), wft[0], 500, true); p++;
     4409            for (i=0 ; i<4 ; i++)
     4410               memcpy(wf3[idx[config][i+5]], wft[i], sizeof(float)*kNumberOfBins);
     4411         }
     4412      } else {
     4413         nChan = 36;
     4414         timingChan = 8;
     4415
     4416         /* measure offset */
     4417         EnableAcal(0, 0); // no inputs signal is allowed during calibration!
     4418         EnableTcal(0, 0);
     4419         Sleep(100);
     4420         RobustAverageWaveforms(pcb, 4, 9, 0, 25, wf1[0], 500, true);
     4421
     4422         /* measure gain at upper range */
     4423         EnableAcal(1, fRange+0.4);
     4424         EnableTcal(0, 0);
     4425         Sleep(100);
     4426         RobustAverageWaveforms(pcb, 4, 9, 25, 50, wf2[0], 500, true);
     4427      }
     4428   }
     4429
     4430   /* convert offsets and gains to 16-bit values */
     4431   memset(fCellOffset, 0, sizeof(fCellOffset));
     4432   n_stuck = 0;
     4433   for (i=0 ; i<nChan ; i++) {
     4434      for (j=0 ; j<kNumberOfBins; j++) {
     4435         if (i % 9 == timingChan) {
     4436            /* calculate offset and gain for timing channel */
     4437            if (fBoardType == 5) {
     4438               /* we have a +325mV and a -325mV value */
     4439               fCellOffset[i][j] = (unsigned short) ((wf1[i][j]+wf2[i][j])/2+0.5);
     4440               fCellGain[i][j]   = (wf2[i][j] - wf1[i][j])/65536.0*1000 / 650.0;
     4441            } else {
     4442               /* only have offset */
     4443               fCellOffset[i][j] = wf1[i][j];
     4444               fCellGain[i][j]   = 1;
     4445            }
     4446         } else {
     4447            /* calculate offset and gain for data channel */
     4448            fCellOffset[i][j] = wf1[i][j];
     4449            if (fCellOffset[i][j] < 100) {
     4450               // mark stuck pixel
     4451               n_stuck ++;
     4452               fCellOffset[i][j] = 0;
     4453               fCellGain[i][j] = 1;
     4454            } else
     4455               fCellGain[i][j] = (wf2[i][j] - fCellOffset[i][j])/65536.0*1000 / ((0.4+fRange)*1000);
     4456         }
     4457
     4458         /* check gain */
     4459         if (fCellGain[i][j] < 0.5 || fCellGain[i][j] > 1.1) {
     4460            printf("Gain of %6.3lf for channel %2d, cell %4d out of range 0.5 ... 1.1\n",
     4461               fCellGain[i][j], i, j);
     4462            fCellGain[i][j] = 1;
     4463         }
     4464      }
     4465   }
     4466
     4467   /*
     4468   FILE *fh = fopen("calib.txt", "wt");
     4469   for (i=0 ; i<nChan ; i++) {
     4470      fprintf(fh, "CH%02d:", i);
     4471      for (j=0 ; j<20 ; j++)
     4472         fprintf(fh, " %5d", fCellOffset[i][j]-32768);
     4473      fprintf(fh, "\n");
     4474   }
     4475   fclose(fh);
     4476   */
     4477
     4478   /* perform secondary calibration */
     4479   if (fBoardType == 5) {
     4480      nChan = 9;
     4481      timingChan = 8;
     4482
     4483      /* measure offset */
     4484      EnableAcal(0, 0); // no inputs signal is allowed during calibration!
     4485      EnableTcal(0, 0);
     4486      Sleep(100);
     4487      AverageWaveforms(pcb, 1, 9, 66, 100, wf1[0], 500, false);
     4488   } else if (fBoardType == 6 && fTransport == TR_VME) {
     4489      nChan = 36;
     4490      timingChan = 8;
     4491
     4492      /* measure offset */
     4493      EnableAcal(0, 0); // no inputs signal is allowed during calibration!
     4494      EnableTcal(0, 0);
     4495      Sleep(100);
     4496      AverageWaveforms(pcb, 4, 9, 50, 75, wf1[0], 500, false);
     4497   }
     4498
     4499   /* convert offset to 16-bit values */
     4500   memset(fCellOffset2, 0, sizeof(fCellOffset2));
     4501   for (i=0 ; i<nChan ; i++)
     4502      for (j=0 ; j<kNumberOfBins; j++)
     4503         if (i % 9 != timingChan)
     4504            fCellOffset2[i][j] = wf1[i][j];
     4505
     4506   /*
     4507   FILE *fh = fopen("calib.txt", "wt");
     4508   for (i=0 ; i<nChan ; i++) {
     4509      for (j=0 ; j<kNumberOfBins; j++)
     4510         fprintf(fh, "%5d: %5d %5d\n", j, fCellOffset2[0][j]-32768, fCellOffset2[1][j]-32768);
     4511      fprintf(fh, "\n");
     4512   }
     4513   fclose(fh);
     4514   */
     4515
     4516   if (fBoardType == 5) {
     4517      /* write calibration CH0-CH7 to EEPROM page 1 */
     4518      for (i=0 ; i<8 ; i++)
     4519         for (j=0 ; j<1024; j++) {
     4520            buf[(i*1024+j)*2]   = fCellOffset[i][j];
     4521            buf[(i*1024+j)*2+1] = (unsigned short) ((fCellGain[i][j] - 0.7) / 0.4 * 65535);
     4522         }
     4523      WriteEEPROM(1, buf, 1024*32);
     4524
     4525      /* write calibration CH8 and secondary calibration to EEPROM page 2 */
     4526      ReadEEPROM(2, buf, 1024*5*4);
     4527      for (j=0 ; j<1024; j++) {
     4528         buf[j*2]   = fCellOffset[8][j];
     4529         buf[j*2+1] = (unsigned short) ((fCellGain[8][j] - 0.7) / 0.4 * 65535);
     4530      }
     4531      for (i=0 ; i<4 ; i++)
     4532         for (j=0 ; j<1024; j++) {
     4533            buf[2*1024+((i*2)*1024+j)*2]   = fCellOffset2[i*2][j];
     4534            buf[2*1024+((i*2)*1024+j)*2+1] = fCellOffset2[i*2+1][j];
     4535         }
     4536      WriteEEPROM(2, buf, 1024*5*4);
     4537
     4538      /* write calibration method and range */
     4539      ReadEEPROM(0, buf, 2048); // 0-0x0FFF
     4540      buf[2] = VCALIB_METHOD | ((signed char)(fRange * 100)) << 8;
     4541      WriteEEPROM(0, buf, 2048);
     4542      fCellCalibratedRange = fRange;
     4543
     4544   } else if (fBoardType == 6) {
     4545      for (chip=0 ; chip<4 ; chip++) {
     4546         /* write calibration of A0 to A7 to EEPROM page 1
     4547                                 B0 to B7 to EEPROM page 2 and so on */
     4548         for (i=0 ; i<8 ; i++)
     4549            for (j=0 ; j<1024; j++) {
     4550               buf[(i*1024+j)*2]   = fCellOffset[i+chip*9][j];
     4551               buf[(i*1024+j)*2+1] = (unsigned short) ((fCellGain[i+chip*9][j] - 0.7) / 0.4 * 65535);
     4552            }
     4553         WriteEEPROM(1+chip, buf, 1024*32);
     4554         if (pcb != NULL)
     4555            pcb->Progress(75+chip*4);
     4556       }
     4557
     4558      /* write calibration A/B/C/D/CLK to EEPROM page 5 */
     4559      ReadEEPROM(5, buf, 1024*4*4);
     4560      for (chip=0 ; chip<4 ; chip++) {
     4561         for (j=0 ; j<1024; j++) {
     4562            buf[j*2+chip*0x0800]   = fCellOffset[8+chip*9][j];
     4563            buf[j*2+1+chip*0x0800] = (unsigned short) ((fCellGain[8+chip*9][j] - 0.7) / 0.4 * 65535);
     4564         }
     4565      }
     4566      WriteEEPROM(5, buf, 1024*4*4);
     4567      if (pcb != NULL)
     4568         pcb->Progress(90);
     4569
     4570      /* write secondary calibration to EEPROM page 7 and 8 */
     4571      for (i=0 ; i<8 ; i++) {
     4572         for (j=0 ; j<1024; j++) {
     4573            buf[i*0x800 + j*2]   = fCellOffset2[i][j];
     4574            buf[i*0x800 + j*2+1] = fCellOffset2[i+9][j];
     4575         }
     4576      }
     4577      WriteEEPROM(7, buf, 1024*32);
     4578      if (pcb != NULL)
     4579         pcb->Progress(94);
     4580
     4581      for (i=0 ; i<8 ; i++) {
     4582         for (j=0 ; j<1024; j++) {
     4583            buf[i*0x800 + j*2]   = fCellOffset2[i+18][j];
     4584            buf[i*0x800 + j*2+1] = fCellOffset2[i+27][j];
     4585         }
     4586      }
     4587      WriteEEPROM(8, buf, 1024*32);
     4588      if (pcb != NULL)
     4589         pcb->Progress(98);
     4590
     4591      /* write calibration method and range */
     4592      ReadEEPROM(0, buf, 2048); // 0-0x0FFF
     4593      buf[2] = VCALIB_METHOD | ((signed char)(fRange * 100)) << 8;
     4594      WriteEEPROM(0, buf, 2048);
     4595      fCellCalibratedRange = fRange;
     4596      if (pcb != NULL)
     4597         pcb->Progress(100);
     4598   }
     4599
     4600   if (n_stuck)
     4601      printf("\nFound %d stuck pixels on this board\n", n_stuck);
     4602
     4603   fCellCalibrationValid = true;
     4604
     4605   /* remove calibration voltage */
     4606   EnableAcal(0, 0);
     4607   EnableTcal(0, 0);
     4608   EnableTrigger(trg1, trg2);
     4609
     4610   return 1;
     4611}
     4612
     4613/*------------------------------------------------------------------*/
     4614
     4615int DRSBoard::AnalyzeWF(int nIter, float wf[kNumberOfBins], int tCell, double cellT[kNumberOfBins])
     4616{
     4617int    i, i1, i2, j, k, nzx, zeroXing[1000], edge, n_correct;
     4618double damping, zeroLevel, ta, tb, dt, corr, inv_corr;
     4619
     4620   /* calculate zero level */
     4621   for (i=0,zeroLevel=0 ; i<1024 ; i++)
     4622      zeroLevel += wf[i];
     4623   zeroLevel /= 1024;
     4624
     4625   /* correct for zero common mode */
     4626   for (i=0 ; i<1024 ; i++)
     4627      wf[i] -= (float)zeroLevel;
     4628
     4629   /* estimate damping factor */
     4630   damping = fFrequency / nIter * 40;
     4631
     4632   for (edge = 0 ; edge < 2 ; edge ++) {
     4633
     4634      /* find edge zero crossing with wrap-around */
     4635      for (i=tCell+3,nzx=0 ; i<tCell+1023 && nzx < (int)(sizeof(zeroXing)/sizeof(int)) ; i++) {
     4636         if (edge == 0) {
     4637            if (wf[(i+1) % 1024] < 0 && wf[i % 1024] > 0) // falling edge
     4638               zeroXing[nzx++] = i;
     4639         } else {
     4640            if (wf[(i+1) % 1024] > 0 && wf[i % 1024] < 0) // rising edge
     4641               zeroXing[nzx++] = i;
     4642         }
     4643      }
     4644
     4645      if (nzx < 20)
     4646         return 0;
     4647
     4648      for (i=n_correct=0 ; i<nzx-1 ; i++) {
     4649         i1 = zeroXing[i] % 1024;
     4650         if (i1 == 1023)
     4651            continue;
     4652         ta = cellT[i1] + (cellT[i1+1] - cellT[i1])*(1/(1-wf[(i1+1) % 1024]/wf[i1]));
     4653         i2 = zeroXing[i+1] % 1024;
     4654         if (i2 == 1023)
     4655            continue;
     4656         tb = cellT[i2] + (cellT[i2+1] - cellT[i2])*(1/(1-wf[(i2+1) % 1024]/wf[i2]));
     4657
     4658//      for (i=n_correct=0 ; i<nzx-1 ; i++) {
     4659 //        i1 = zeroXing[i] % 1024;
     4660 //        ta = cellT[i1] + (cellT[i1+1] - cellT[i1])*(1/(1-wf[(i1+1)%1024]/wf[i1]));
     4661//         i2 = zeroXing[i+1] % 1024;
     4662//         tb = cellT[i2] + (cellT[i2+1] - cellT[i2])*(1/(1-wf[(i2+1)%1024]/wf[i2]));
     4663
     4664         /* wrap-around ? */
     4665         if (tb - ta < 0)
     4666            tb += 1/fFrequency*1024;
     4667
     4668         /* calculate correction to nominal period in ns */
     4669         corr = 1/fTCALFrequency*1000 - (tb - ta);
     4670
     4671         /* skip very large corrections (noise?) */
     4672         if (fabs(corr/(1/fTCALFrequency*1000)) > 0.5)
     4673            continue;
     4674
     4675         /* remeber number of valid corrections */
     4676         n_correct++;
     4677
     4678         /* apply damping factor */
     4679         corr *= damping;
     4680
     4681         /* calculate inverse correction */
     4682         inv_corr = -corr;
     4683
     4684         /* apply from (i1+1)+1 to i2 inclusive */
     4685         i1 = zeroXing[i]+2;
     4686         i2 = zeroXing[i+1];
     4687
     4688         /* distribute correciton equally into bins inside the region ... */
     4689         corr = corr / (i2-i1+1);
     4690
     4691         /* ... and inverse correction into the outside bins */
     4692         inv_corr = inv_corr / (1024 - (i2-i1+1));
     4693
     4694         i1 = i1 % 1024;
     4695         i2 = i2 % 1024;
     4696
     4697         double oldT[kNumberOfBins];
     4698         memcpy(oldT, cellT, sizeof(double)*1024);
     4699         for (j=0,ta=0 ; j<1024 ; j++) {
     4700            if (j < 1023)
     4701               dt = cellT[j+1] - cellT[j];
     4702            else
     4703               dt = 1/fFrequency*1024 - cellT[j];
     4704            if ((i2 > i1 && (j >= i1 && j<= i2)) ||
     4705                (i2 < i1 && (j >= i1 || j<= i2)) )
     4706               dt += corr;
     4707            else
     4708               dt += inv_corr;
     4709
     4710            cellT[j] = ta;               
     4711            ta += dt;
     4712         }
     4713
     4714         /* check and correct for too narrow bin widths */
     4715         for (j=0 ; j<1023 ; j++) {
     4716            dt = cellT[j+1] - cellT[j];
     4717            if (dt < 1/fFrequency*0.1) {
     4718               /* if width is smaller than 10% of nominal width, "undo" 5x that correction,
     4719                  otherwise next iteration would cause this problem again */
     4720               corr = 5*(1/fFrequency*0.1-dt);
     4721               inv_corr = -corr;
     4722
     4723               /* distribute inverse correction equally into the outside bins */
     4724               inv_corr = inv_corr / 1022;
     4725
     4726               for (k=0,ta=0 ; k<1024 ; k++) {
     4727                  if (k < 1023)
     4728                     dt = cellT[k+1] - cellT[k];
     4729                  else
     4730                     dt = 1/fFrequency*1024 - cellT[k];
     4731                  if (k == j)
     4732                     dt += corr;
     4733                  else
     4734                     dt += inv_corr;
     4735
     4736                  cellT[k] = ta;
     4737                  ta += dt;
     4738               }
     4739            }
     4740         }
     4741      }
     4742
     4743      if (n_correct < nzx/3)
     4744         return 0;
     4745   }
     4746
     4747   return 1;
     4748}
     4749
     4750/*------------------------------------------------------------------*/
     4751
     4752
     4753int DRSBoard::CalibrateTiming(DRSCallback *pcb)
     4754{
     4755int    index, status, tCell, i, c, chip, mode, nIter, clkon, phase, refclk, trg1, trg2;
     4756double f, range, t1[4], t2[4];
     4757unsigned short buf[1024*4];
     4758float  wf[1024];
     4759   
     4760   nIter   = 1000;
     4761   f       = fFrequency;
     4762   range   = fRange;
     4763   clkon   = (GetCtrlReg() & BIT_TCAL_EN) > 0;
     4764   refclk  = (GetCtrlReg() & BIT_REFCLK_SOURCE) > 0;
     4765   trg1    = fTriggerEnable1;
     4766   trg2    = fTriggerEnable2;
     4767
     4768   Init();
     4769   fFrequency = f;
     4770   SetRefclk(refclk);
     4771   SetFrequency(fFrequency, true);
     4772   if (fBoardType == 5)
     4773      fTCALFrequency = 240; // 240 MHz, for MEZZ this is set by ConfigureLMK
     4774   SetDominoMode(1);
     4775   SetDominoActive(1);
     4776   SetReadoutMode(1);
     4777   EnableTrigger(0, 0);
     4778   EnableTcal(1, 0, 0);
     4779   if (fBoardType == 5)
     4780      SelectClockSource(1); // 2nd quartz
     4781   StartDomino();
     4782
     4783   /* initialize time array */
     4784   for (i=0 ; i<1024 ; i++)
     4785      for (chip=0 ; chip<4 ; chip++)
     4786         fCellT[chip][i] = (float)1/fFrequency*i; // [ns]
     4787
     4788   for (index = 0 ; index < nIter ; index++) {
     4789      if (index % 10 == 0)
     4790         pcb->Progress(100*index/nIter);
     4791
     4792      if (fTransport == TR_VME) {
     4793         SoftTrigger();
     4794         while (IsBusy());
     4795
     4796         /* select random phase */
     4797         phase = (rand() % 30) - 15;
     4798         if (phase == 0)
     4799            phase = 15;
     4800         EnableTcal(1, 0, phase);
     4801
     4802         StartDomino();
     4803         TransferWaves();
     4804
     4805         for (chip=0 ; chip<4 ; chip++) {
     4806            tCell = GetStopCell(chip);
     4807            GetWave(chip, 8, wf, true, tCell, true);
     4808            status = AnalyzeWF(nIter, wf, tCell, fCellT[chip]);
     4809
     4810            if (!status)
     4811               return 0;
     4812         }
     4813      } else {
     4814         if (fBoardType == 5) { // DRS4 Evaluation board: 1 Chip
     4815            SoftTrigger();
     4816            while (IsBusy());
     4817
     4818            StartDomino();
     4819            TransferWaves();
     4820
     4821            tCell = GetStopCell(0);
     4822            GetWave(0, 8, wf, true, tCell, true);
     4823            status = AnalyzeWF(nIter, wf, tCell, fCellT[0]);
     4824
     4825            if (!status)
     4826               return 0;
     4827
     4828         } else {               // DRS4 Mezzanine board: 4 Chips
     4829            for (mode=0 ; mode<2 ; mode++) {
     4830               SetChannelConfig(mode*2, 8, 8);
     4831               SoftTrigger();
     4832               while (IsBusy());
     4833
     4834               /* select random phase */
     4835               phase = (rand() % 30) - 15;
     4836               if (phase == 0)
     4837                  phase = 15;
     4838               EnableTcal(1, 0, phase);
     4839
     4840               StartDomino();
     4841               TransferWaves();
     4842
     4843               for (chip=0 ; chip<4 ; chip+=2) {
     4844                  tCell = GetStopCell(chip+mode);
     4845                  GetWave(chip+mode, 8, wf, true, tCell, true);
     4846                  status = AnalyzeWF(nIter, wf, tCell, fCellT[chip+mode]);
     4847
     4848                  if (!status)
     4849                     return 0;
     4850               }
     4851            }
     4852         }
     4853      }
     4854   }
     4855
     4856   pcb->Progress(100);
     4857
     4858   // use following lines to save calibration into an ASCII file
     4859#if 1
     4860   FILE *fh;
     4861
     4862   fh = fopen("cellt.csv", "wt");
     4863   if (!fh)
     4864      printf("Cannot open file \"cellt.csv\"\n");
     4865   else {
     4866      fprintf(fh, "index;d_ch1;d_ch2;d_ch3;d_ch4\n");
     4867      for (i=0 ; i<1024 ; i++)
     4868         fprintf(fh, "%4d;%5.3lf;%5.3lf;%5.3lf;%5.3lf\n", i,
     4869                 fCellT[0][i]-i/fFrequency,
     4870                 fCellT[1][i]-i/fFrequency,
     4871                 fCellT[2][i]-i/fFrequency,
     4872                 fCellT[3][i]-i/fFrequency);
     4873      fclose(fh);
     4874   }
     4875#endif
     4876
     4877   if (fBoardType == 5) {
     4878      /* write timing calibration to EEPROM page 0 */
     4879      ReadEEPROM(0, buf, sizeof(buf));
     4880      for (i=0,t1[0]=0 ; i<1024; i++) {
     4881         t2[0] = fCellT[0][i] - t1[0];
     4882         t2[0] = (unsigned short) (t2[0] * 10000 + 0.5);
     4883         t1[0] += t2[0] / 10000.0;
     4884         buf[i*2+1] = (unsigned short) t2[0];
     4885      }
     4886
     4887      /* write calibration method and frequency */
     4888      buf[4] = TCALIB_METHOD;
     4889      buf[6] = (unsigned short) (fFrequency / 6.0 * 65535.0);
     4890      fTimingCalibratedFrequency = buf[6] / 65535.0 * 6.0;
     4891      WriteEEPROM(0, buf, sizeof(buf));
     4892   } else {
     4893      /* write timing calibration to EEPROM page 6 */
     4894      ReadEEPROM(6, buf, sizeof(buf));
     4895      for (c=0 ; c<4 ; c++)
     4896         t1[c] = 0;
     4897      for (i=0 ; i<1024; i++) {
     4898         for (c=0 ; c<4 ; c++) {
     4899            t2[c] = fCellT[c][i] - t1[c];
     4900            t2[c] = (unsigned short) (t2[c] * 10000 + 0.5);
     4901            t1[c] += t2[c] / 10000.0;
     4902         }
     4903         buf[i*2]         = (unsigned short) t2[0];
     4904         buf[i*2+1]       = (unsigned short) t2[1];
     4905         buf[i*2+0x800]   = (unsigned short) t2[2];
     4906         buf[i*2+0x800+1] = (unsigned short) t2[3];
     4907      }
     4908      WriteEEPROM(6, buf, sizeof(buf));
     4909
     4910      /* write calibration method and frequency */
     4911      ReadEEPROM(0, buf, 16);
     4912      buf[4] = TCALIB_METHOD;
     4913      buf[6] = (unsigned short) (fFrequency / 6.0 * 65535.0);
     4914      fTimingCalibratedFrequency = buf[6] / 65535.0 * 6.0;
     4915      WriteEEPROM(0, buf, 16);
     4916   }
     4917
     4918   fTimingCalibrationValid = true;
     4919
     4920   /* remove calibration voltage */
     4921   EnableAcal(0, 0);
     4922   EnableTcal(clkon, 0);
     4923   SetInputRange(range);
     4924   EnableTrigger(trg1, trg2);
     4925
     4926   return 1;
     4927}
     4928
     4929
     4930/*------------------------------------------------------------------*/
     4931
     4932
     4933void DRSBoard::RemoveSymmetricSpikes(short **wf, int nwf,
     4934                                     short diffThreshold, int spikeWidth,
     4935                                     short maxPeakToPeak, short spikeVoltage,
     4936                                     int nTimeRegionThreshold)
     4937{
     4938   // Remove a specific kind of spike on DRS4.
     4939   // This spike has some features,
     4940   //  - Common on all the channels on a chip
     4941   //  - Constant heigh and width
     4942   //  - Two spikes per channel
     4943   //  - Symmetric to cell #0.
     4944   //
     4945   // This is not general purpose spike-removing function.
     4946   //
     4947   // wf                   : Waveform data. cell#0 must be at bin0,
     4948   //                        and number of bins must be kNumberOfBins.
     4949   // nwf                  : Number of channels which "wf" holds.
     4950   // diffThreshold        : Amplitude threshold to find peak
     4951   // spikeWidth           : Width of spike
     4952   // maxPeakToPeak        : When peak-to-peak is larger than this, the channel
     4953   //                        is not used to find spikes.
     4954   // spikeVoltage         : Amplitude of spikes. When it is 0, it is calculated in this function
     4955   //                        from voltage difference from neighboring bins.
     4956   // nTimeRegionThreshold : Requirement of number of time regions having spike at common position.
     4957   //                        Total number of time regions is 2*"nwf".
     4958
     4959   if (!wf || !nwf || !diffThreshold || !spikeWidth) {
     4960      return;
     4961   }
     4962
     4963   int          ibin, jbin, kbin;
     4964   double       v;
     4965   int          nbin;
     4966   int          iwf;
     4967   short        maximum, minimum;
     4968   int          spikeCount[kNumberOfBins / 2];
     4969   int          spikeCountSum[kNumberOfBins / 2] = {0};
     4970   bool         largePulse[kNumberOfChannelsMax * 2] = {0};
     4971   const short  diffThreshold2 = diffThreshold + diffThreshold;
     4972
     4973   const short  maxShort = 0xFFFF>>1;
     4974   const short  minShort = -maxShort - 1;
     4975
     4976   // search spike
     4977   for (iwf = 0; iwf < nwf; iwf++) {
     4978      // first half
     4979      memset(spikeCount, 0, sizeof(spikeCount));
     4980      maximum = minShort;
     4981      minimum = maxShort;
     4982      for (ibin = 0; ibin < kNumberOfBins / 2; ibin++) {
     4983         jbin = ibin;
     4984         maximum = max(maximum, wf[iwf][jbin]);
     4985         minimum = min(minimum, wf[iwf][jbin]);
     4986         if (jbin - 1 >= 0 && jbin + spikeWidth < kNumberOfBins) {
     4987            v = 0;
     4988            nbin = 0;
     4989            for (kbin = 0; kbin < spikeWidth; kbin++) {
     4990               v += wf[iwf][jbin + kbin];
     4991               nbin++;
     4992            }
     4993            if ((nbin == 2 && v - (wf[iwf][jbin - 1] + wf[iwf][jbin + spikeWidth]) > diffThreshold2) ||
     4994                (nbin != 2 && nbin && v / nbin - (wf[iwf][jbin - 1] + wf[iwf][jbin + spikeWidth]) / 2 > diffThreshold)) {
     4995               spikeCount[ibin]++;
     4996            }
     4997         }
     4998      }
     4999      if (maximum != minShort && minimum != maxShort &&
     5000          (!maxPeakToPeak || maximum - minimum < maxPeakToPeak)) {
     5001         for (ibin = 0; ibin < kNumberOfBins / 2; ibin++) {
     5002            spikeCountSum[ibin] += spikeCount[ibin];
     5003         }
     5004         largePulse[iwf] = false;
     5005#if 0 /* this part can be enabled to skip checking other channels */
     5006         if (maximum != minShort && minimum != maxShort &&
     5007             maximum - minimum < diffThreshold) {
     5008            return;
     5009         }
     5010#endif
     5011      } else {
     5012         largePulse[iwf] = true;
     5013      }
     5014
     5015      // second half
     5016      memset(spikeCount, 0, sizeof(spikeCount));
     5017      maximum = minShort;
     5018      minimum = maxShort;
     5019      for (ibin = 0; ibin < kNumberOfBins / 2; ibin++) {
     5020         jbin = kNumberOfBins - 1 - ibin;
     5021         maximum = max(maximum, wf[iwf][jbin]);
     5022         minimum = min(minimum, wf[iwf][jbin]);
     5023         if (jbin + 1 < kNumberOfBins && jbin - spikeWidth >= 0) {
     5024            v = 0;
     5025            nbin = 0;
     5026            for (kbin = 0; kbin < spikeWidth; kbin++) {
     5027               v += wf[iwf][jbin - kbin];
     5028               nbin++;
     5029            }
     5030            if ((nbin == 2 && v - (wf[iwf][jbin + 1] + wf[iwf][jbin - spikeWidth]) > diffThreshold2) ||
     5031                (nbin != 2 && nbin && v / nbin - (wf[iwf][jbin + 1] + wf[iwf][jbin - spikeWidth]) / 2 > diffThreshold)) {
     5032               spikeCount[ibin]++;
     5033            }
     5034         }
     5035      }
     5036      if (maximum != minShort && minimum != maxShort &&
     5037          maximum - minimum < maxPeakToPeak) {
     5038         for (ibin = 0; ibin < kNumberOfBins / 2; ibin++) {
     5039            spikeCountSum[ibin] += spikeCount[ibin];
     5040         }
     5041         largePulse[iwf + nwf] = false;
     5042#if 0 /* this part can be enabled to skip checking other channels */
     5043         if (maximum != minShort && minimum != maxShort &&
     5044             maximum - minimum < diffThreshold) {
     5045            return;
     5046         }
     5047#endif
     5048      } else {
     5049         largePulse[iwf + nwf] = true;
     5050      }
     5051   }
     5052
     5053   // Find common spike
     5054   int commonSpikeBin = -1;
     5055   int commonSpikeMax = -1;
     5056   for (ibin = 0; ibin < kNumberOfBins / 2; ibin++) {
     5057      if (commonSpikeMax < spikeCountSum[ibin]) {
     5058         commonSpikeMax = spikeCountSum[ibin];
     5059         commonSpikeBin = ibin;
     5060      }
     5061   }
     5062
     5063   if (spikeCountSum[commonSpikeBin] >= nTimeRegionThreshold) {
     5064      if (spikeVoltage == 0) {
     5065         // Estimate spike amplitude
     5066         double  baseline      = 0;
     5067         int    nBaseline      = 0;
     5068         double  peakAmplitude = 0;
     5069         int    nPeakAmplitude = 0;
     5070         for (iwf = 0; iwf < nwf; iwf++) {
     5071            // first half
     5072            if (!largePulse[iwf]) {
     5073               // baseline
     5074               if ((jbin = commonSpikeBin - 1) >= 0 && jbin < kNumberOfBins) {
     5075                  baseline += wf[iwf][jbin];
     5076                  nBaseline++;
     5077               }
     5078               if ((jbin = commonSpikeBin + spikeWidth + 1) >= 0 && jbin < kNumberOfBins) {
     5079                  baseline += wf[iwf][jbin];
     5080                  nBaseline++;
     5081               }
     5082               // spike
     5083               for (ibin = 0; ibin < spikeWidth; ibin++) {
     5084                  if ((jbin = commonSpikeBin + ibin) >= 0 && jbin < kNumberOfBins) {
     5085                     peakAmplitude += wf[iwf][jbin];
     5086                     nPeakAmplitude++;
     5087                  }
     5088               }
     5089            }
     5090
     5091            // second half
     5092            if (!largePulse[iwf + nwf]) {
     5093               // baseline
     5094               if ((jbin = kNumberOfBins - 1 - commonSpikeBin + 1) >= 0 && jbin < kNumberOfBins) {
     5095                  baseline += wf[iwf][jbin];
     5096                  nBaseline++;
     5097               }
     5098               if ((jbin = kNumberOfBins - 1 - commonSpikeBin - spikeWidth - 1) >= 0 && jbin < kNumberOfBins) {
     5099                  baseline += wf[iwf][jbin];
     5100                  nBaseline++;
     5101               }
     5102               // spike
     5103               for (ibin = 0; ibin < spikeWidth; ibin++) {
     5104                  if ((jbin = kNumberOfBins - 1 - commonSpikeBin - ibin) >= 0 && jbin < kNumberOfBins) {
     5105                     peakAmplitude += wf[iwf][jbin];
     5106                     nPeakAmplitude++;
     5107                  }
     5108               }
     5109            }
     5110         }
     5111         if (nBaseline && nPeakAmplitude) {
     5112            baseline /= nBaseline;
     5113            peakAmplitude /= nPeakAmplitude;
     5114            spikeVoltage = static_cast<short>(peakAmplitude - baseline);
     5115         } else {
     5116            spikeVoltage = 0;
     5117         }
     5118      }
     5119
     5120      // Remove spike
     5121      if (spikeVoltage > 0) {
     5122         for (iwf = 0; iwf < nwf; iwf++) {
     5123            for (ibin = 0; ibin < spikeWidth; ibin++) {
     5124               if ((jbin = commonSpikeBin + ibin) >= 0 && jbin < kNumberOfBins) {
     5125                  wf[iwf][jbin] -= spikeVoltage;
     5126               }
     5127               if ((jbin = kNumberOfBins - 1 - commonSpikeBin - ibin) >= 0 && jbin < kNumberOfBins) {
     5128                  wf[iwf][jbin] -= spikeVoltage;
     5129               }
     5130            }
     5131         }
     5132      }
     5133   }
    24705134}
    24715135
     
    24785142                                                   int showStatistics)
    24795143{
    2480   DeleteFields();
    2481   InitFields(numberOfPointsLowVolt, numberOfPoints, numberOfMode2Bins, numberOfSamples, numberOfGridPoints,
    2482              numberOfXConstPoints, numberOfXConstGridPoints, triggerFrequency, showStatistics);
     5144   DeleteFields();
     5145   InitFields(numberOfPointsLowVolt, numberOfPoints, numberOfMode2Bins, numberOfSamples, numberOfGridPoints,
     5146              numberOfXConstPoints, numberOfXConstGridPoints, triggerFrequency, showStatistics);
    24835147}
    24845148
     
    24875151void ResponseCalibration::ResetCalibration()
    24885152{
    2489   int i;
    2490   for (i = 0; i < kNumberOfChips; i++)
    2491     fCalibrationData[i]->fRead = false;
    2492   fCurrentPoint = 0;
    2493   fCurrentLowVoltPoint = 0;
    2494   fCurrentSample = 0;
    2495   fCurrentFitChannel = 0;
    2496   fCurrentFitBin = 0;
    2497   fRecorded = false;
    2498   fFitted = false;
    2499   fOffset = false;
     5153   int i;
     5154   for (i = 0; i < kNumberOfChipsMax; i++)
     5155      fCalibrationData[i]->fRead = false;
     5156   fCurrentPoint = 0;
     5157   fCurrentLowVoltPoint = 0;
     5158   fCurrentSample = 0;
     5159   fCurrentFitChannel = 0;
     5160   fCurrentFitBin = 0;
     5161   fRecorded = false;
     5162   fFitted = false;
     5163   fOffset = false;
    25005164};
    25015165
     
    25045168bool ResponseCalibration::WriteCalibration(unsigned int chipIndex)
    25055169{
    2506   if (!fOffset)
    2507     return false;
    2508   if (fBoard->GetChipVersion() == 3)
    2509     return WriteCalibrationV4(chipIndex);
    2510   else
    2511     return WriteCalibrationV3(chipIndex);
     5170   if (!fOffset)
     5171      return false;
     5172   if (fBoard->GetDRSType() == 3)
     5173      return WriteCalibrationV4(chipIndex);
     5174   else
     5175      return WriteCalibrationV3(chipIndex);
    25125176}
    25135177
     
    25165180bool ResponseCalibration::WriteCalibrationV3(unsigned int chipIndex)
    25175181{
    2518   if (!fOffset)
    2519     return false;
    2520  
    2521   int ii, j, k;
    2522   char str[1000];
    2523   char strt[1000];
    2524   short tempShort;
    2525   CalibrationData *data = fCalibrationData[chipIndex];
    2526   CalibrationData::CalibrationDataChannel * chn;
    2527  
    2528   // Open File
    2529   fBoard->GetCalibrationDirectory(strt);
    2530   sprintf(str, "%s/board%d", strt, fBoard->GetCMCSerialNumber());
    2531   if (MakeDir(str) == -1) {
    2532     printf("Error: Cannot create directory \"%s\"\n", str);
    2533     return false;
    2534   }
    2535   sprintf(str, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", strt, fBoard->GetCMCSerialNumber(),
    2536           fBoard->GetCMCSerialNumber(), chipIndex, static_cast<int>(fBoard->GetFrequency() * 1000));
    2537   fCalibFile = fopen(str, "wb");
    2538   if (fCalibFile == NULL) {
    2539     printf("Error: Cannot write to file \"%s\"\n", str);
    2540     return false;
    2541   }
    2542   // Write File
    2543   fwrite(&data->fNumberOfGridPoints, 1, 1, fCalibFile);
    2544   tempShort = static_cast<short>(data->fStartTemperature) * 10;
    2545   fwrite(&tempShort, 2, 1, fCalibFile);
    2546   tempShort = static_cast<short>(data->fEndTemperature) * 10;
    2547   fwrite(&tempShort, 2, 1, fCalibFile);
    2548   fwrite(&data->fMin, 4, 1, fCalibFile);
    2549   fwrite(&data->fMax, 4, 1, fCalibFile);
    2550   fwrite(&data->fNumberOfLimitGroups, 1, 1, fCalibFile);
    2551  
    2552   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    2553     chn = data->fChannel[ii];
    2554     for (j = 0; j < kNumberOfBins; j++) {
    2555       fwrite(&chn->fLimitGroup[j], 1, 1, fCalibFile);
    2556       fwrite(&chn->fLookUpOffset[j], 2, 1, fCalibFile);
    2557       fwrite(&chn->fNumberOfLookUpPoints[j], 1, 1, fCalibFile);
    2558       for (k = 0; k < chn->fNumberOfLookUpPoints[j]; k++) {
    2559         fwrite(&chn->fLookUp[j][k], 1, 1, fCalibFile);
    2560       }
    2561       for (k = 0; k < data->fNumberOfGridPoints; k++) {
    2562         fwrite(&chn->fData[j][k], 2, 1, fCalibFile);
    2563       }
    2564       fwrite(&chn->fOffsetADC[j], 2, 1, fCalibFile);
    2565       fwrite(&chn->fOffset[j], 2, 1, fCalibFile);
    2566     }
    2567   }
    2568   fclose(fCalibFile);
    2569  
    2570   printf("Calibration successfully written to\n\"%s\"\n", str);
    2571   return true;
     5182   if (!fOffset)
     5183      return false;
     5184
     5185   int ii, j, k;
     5186   char str[1000];
     5187   char strt[1000];
     5188   short tempShort;
     5189   CalibrationData *data = fCalibrationData[chipIndex];
     5190   CalibrationData::CalibrationDataChannel * chn;
     5191
     5192   // Open File
     5193   fBoard->GetCalibrationDirectory(strt);
     5194   sprintf(str, "%s/board%d", strt, fBoard->GetBoardSerialNumber());
     5195   if (MakeDir(str) == -1) {
     5196      printf("Error: Cannot create directory \"%s\"\n", str);
     5197      return false;
     5198   }
     5199   sprintf(str, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", strt, fBoard->GetBoardSerialNumber(),
     5200           fBoard->GetBoardSerialNumber(), chipIndex, static_cast < int >(fBoard->GetFrequency() * 1000));
     5201   fCalibFile = fopen(str, "wb");
     5202   if (fCalibFile == NULL) {
     5203      printf("Error: Cannot write to file \"%s\"\n", str);
     5204      return false;
     5205   }
     5206   // Write File
     5207   fwrite(&data->fNumberOfGridPoints, 1, 1, fCalibFile);
     5208   tempShort = static_cast < short >(data->fStartTemperature) * 10;
     5209   fwrite(&tempShort, 2, 1, fCalibFile);
     5210   tempShort = static_cast < short >(data->fEndTemperature) * 10;
     5211   fwrite(&tempShort, 2, 1, fCalibFile);
     5212   fwrite(&data->fMin, 4, 1, fCalibFile);
     5213   fwrite(&data->fMax, 4, 1, fCalibFile);
     5214   fwrite(&data->fNumberOfLimitGroups, 1, 1, fCalibFile);
     5215
     5216   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5217      chn = data->fChannel[ii];
     5218      for (j = 0; j < kNumberOfBins; j++) {
     5219         fwrite(&chn->fLimitGroup[j], 1, 1, fCalibFile);
     5220         fwrite(&chn->fLookUpOffset[j], 2, 1, fCalibFile);
     5221         fwrite(&chn->fNumberOfLookUpPoints[j], 1, 1, fCalibFile);
     5222         for (k = 0; k < chn->fNumberOfLookUpPoints[j]; k++) {
     5223            fwrite(&chn->fLookUp[j][k], 1, 1, fCalibFile);
     5224         }
     5225         for (k = 0; k < data->fNumberOfGridPoints; k++) {
     5226            fwrite(&chn->fData[j][k], 2, 1, fCalibFile);
     5227         }
     5228         fwrite(&chn->fOffsetADC[j], 2, 1, fCalibFile);
     5229         fwrite(&chn->fOffset[j], 2, 1, fCalibFile);
     5230      }
     5231   }
     5232   fclose(fCalibFile);
     5233
     5234   printf("Calibration successfully written to\n\"%s\"\n", str);
     5235   return true;
    25725236}
    25735237
     
    25765240bool ResponseCalibration::WriteCalibrationV4(unsigned int chipIndex)
    25775241{
    2578   if (!fOffset)
    2579     return false;
    2580  
    2581   int ii, j;
    2582   char str[1000];
    2583   char strt[1000];
    2584   CalibrationData *data = fCalibrationData[chipIndex];
    2585   CalibrationData::CalibrationDataChannel * chn;
    2586  
    2587   // Open File
    2588   fBoard->GetCalibrationDirectory(strt);
    2589   sprintf(str, "%s/board%d", strt, fBoard->GetCMCSerialNumber());
    2590   if (MakeDir(str) == -1) {
    2591     printf("Error: Cannot create directory \"%s\"\n", str);
    2592     return false;
    2593   }
    2594   sprintf(str, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", strt, fBoard->GetCMCSerialNumber(),
    2595           fBoard->GetCMCSerialNumber(), chipIndex, static_cast<int>(fBoard->GetFrequency() * 1000));
    2596   fCalibFile = fopen(str, "wb");
    2597   if (fCalibFile == NULL) {
    2598     printf("Error: Cannot write to file \"%s\"\n", str);
    2599     return false;
    2600   }
    2601  
    2602   // Write File
    2603   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    2604     chn = data->fChannel[ii];
    2605     for (j = 0; j < kNumberOfBins; j++) {
    2606       fwrite(&chn->fOffset[j], 2, 1, fCalibFile);
    2607       fwrite(&chn->fGain[j], 2, 1, fCalibFile);
    2608     }
    2609   }
    2610   fclose(fCalibFile);
    2611  
    2612   printf("Calibration successfully written to\n\"%s\"\n", str);
    2613   return true;
     5242   if (!fOffset)
     5243      return false;
     5244
     5245   int ii, j;
     5246   char str[1000];
     5247   char strt[1000];
     5248   CalibrationData *data = fCalibrationData[chipIndex];
     5249   CalibrationData::CalibrationDataChannel * chn;
     5250
     5251   // Open File
     5252   fBoard->GetCalibrationDirectory(strt);
     5253   sprintf(str, "%s/board%d", strt, fBoard->GetBoardSerialNumber());
     5254   if (MakeDir(str) == -1) {
     5255      printf("Error: Cannot create directory \"%s\"\n", str);
     5256      return false;
     5257   }
     5258   sprintf(str, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", strt, fBoard->GetBoardSerialNumber(),
     5259           fBoard->GetBoardSerialNumber(), chipIndex, static_cast < int >(fBoard->GetFrequency() * 1000));
     5260   fCalibFile = fopen(str, "wb");
     5261   if (fCalibFile == NULL) {
     5262      printf("Error: Cannot write to file \"%s\"\n", str);
     5263      return false;
     5264   }
     5265   // Write File
     5266   for (ii = 0; ii < kNumberOfCalibChannelsV4; ii++) {
     5267      chn = data->fChannel[ii];
     5268      for (j = 0; j < kNumberOfBins; j++) {
     5269         fwrite(&chn->fOffset[j], 2, 1, fCalibFile);
     5270         fwrite(&chn->fGain[j], 2, 1, fCalibFile);
     5271      }
     5272   }
     5273   fclose(fCalibFile);
     5274
     5275   printf("Calibration successfully written to\n\"%s\"\n", str);
     5276   return true;
    26145277}
    26155278
     
    26185281void ResponseCalibration::CalibrationTrigger(int mode, double voltage)
    26195282{
    2620   fBoard->Reinit();
    2621   fBoard->EnableAcal(mode, voltage);
    2622   fBoard->StartDomino();
    2623   fBoard->SoftTrigger();
    2624   while (fBoard->IsBusy()) {
    2625   }
     5283   fBoard->Reinit();
     5284   fBoard->EnableAcal(mode, voltage);
     5285   fBoard->StartDomino();
     5286   fBoard->SoftTrigger();
     5287   while (fBoard->IsBusy()) {
     5288   }
    26265289}
    26275290
     
    26305293void ResponseCalibration::CalibrationStart(double voltage)
    26315294{
    2632   fBoard->SetDominoMode(1);
    2633   fBoard->EnableAcal(0, voltage);
    2634   fBoard->StartDomino();
    2635   fBoard->IsBusy();
    2636   fBoard->IsBusy();
    2637   fBoard->IsBusy();
     5295   fBoard->SetDominoMode(1);
     5296   fBoard->EnableAcal(0, voltage);
     5297   fBoard->StartDomino();
     5298   fBoard->IsBusy();
     5299   fBoard->IsBusy();
     5300   fBoard->IsBusy();
    26385301}
    26395302
     
    26425305bool ResponseCalibration::RecordCalibrationPoints(int chipNumber)
    26435306{
    2644   if (!fInitialized)
    2645     return true;
    2646   if (fBoard->GetChipVersion() == 3)
    2647     return RecordCalibrationPointsV4(chipNumber);
    2648   else
    2649     return RecordCalibrationPointsV3(chipNumber);
     5307   if (!fInitialized)
     5308      return true;
     5309   if (fBoard->GetDRSType() == 3)
     5310      return RecordCalibrationPointsV4(chipNumber);
     5311   else
     5312      return RecordCalibrationPointsV3(chipNumber);
    26505313}
    26515314
     
    26545317bool ResponseCalibration::RecordCalibrationPointsV3(int chipNumber)
    26555318{
    2656 
    2657   int j, k, ii;
    2658   int notdone, nsample;
    2659   double voltage;
    2660   float mean;
    2661   const double minVolt = 0.006;
    2662   const double xpos[50] =
    2663     { 0.010, 0.027, 0.052, 0.074, 0.096, 0.117, 0.136, 0.155, 0.173, 0.191, 0.208, 0.226, 0.243, 0.260,
     5319   int j, k, ii;
     5320   int notdone, nsample;
     5321   double voltage;
     5322   float mean;
     5323   const double minVolt = 0.006;
     5324   const double xpos[50] =
     5325       { 0.010, 0.027, 0.052, 0.074, 0.096, 0.117, 0.136, 0.155, 0.173, 0.191, 0.208, 0.226, 0.243, 0.260,
    26645326      0.277, 0.294, 0.310,
    26655327      0.325, 0.342, 0.358, 0.374, 0.390, 0.406, 0.422, 0.439, 0.457, 0.477, 0.497, 0.520, 0.546, 0.577, 0.611,
     
    26675329      0.772, 0.842, 0.916,
    26685330      0.995, 1.075, 1.157, 1.240, 1.323, 1.407, 1.490, 1.575, 1.659, 1.744, 1.829, 1.914, 2.000
    2669     };
    2670  
    2671   // Initialisations
    2672   if (fCurrentLowVoltPoint == 0) {
    2673     fBoard->SetDAC(fBoard->fDAC_CLKOFS, 0);
    2674     // Record Temperature
    2675     fCalibrationData[chipNumber]->fStartTemperature = static_cast<float>(fBoard->GetTemperature());
    2676   }
    2677   // Record current Voltage
    2678   if (fCurrentLowVoltPoint < fNumberOfPointsLowVolt)
    2679     voltage = (xpos[0] - minVolt) * fCurrentLowVoltPoint / static_cast<double>(fNumberOfPointsLowVolt) + minVolt;
    2680   else
    2681     voltage = xpos[fCurrentPoint];
    2682   fBoard->SetCalibVoltage(voltage);
    2683   fResponseY[fCurrentPoint + fCurrentLowVoltPoint] = static_cast<float>(voltage) * 1000;
    2684  
    2685   // Loop Over Number Of Samples For Statistics
    2686   for (j = 0; j < fNumberOfSamples; j++) {
    2687     // Read Out Second Part of the Waveform
    2688     CalibrationTrigger(3, voltage);
    2689     fBoard->TransferWaves();
    2690     for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    2691       fBoard->GetADCWave(chipNumber, ii, fWaveFormMode3[ii][j]);
    2692     }
    2693     // Read Out First Part of the Waveform
    2694     CalibrationStart(voltage);
    2695     CalibrationTrigger(2, voltage);
    2696     fBoard->TransferWaves();
    2697     for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    2698       fBoard->GetADCWave(chipNumber, ii, fWaveFormMode2[ii][j]);
    2699     }
    2700     CalibrationStart(voltage);
    2701   }
    2702   // Average Sample Points
    2703   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    2704     for (k = 0; k < kNumberOfBins; k++) {
    2705       fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] = 0;
    2706       for (j = 0; j < fNumberOfSamples; j++) {
    2707         fSampleUsed[j] = 1;
    2708         if (k < fNumberOfMode2Bins)
    2709           fSamples[j] = fWaveFormMode2[ii][j][k];
    2710         else
    2711           fSamples[j] = fWaveFormMode3[ii][j][k];
    2712         fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] += fSamples[j];
    2713       }
    2714       mean = fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] / fNumberOfSamples;
    2715       notdone = 1;
    2716       nsample = fNumberOfSamples;
    2717       while (notdone) {
    2718         notdone = 0;
    2719         for (j = 0; j < fNumberOfSamples; j++) {
    2720           if (fSampleUsed[j] && abs(static_cast<int>(fSamples[j] - mean)) > 3) {
    2721             notdone = 1;
    2722             fSampleUsed[j] = 0;
    2723             nsample--;
    2724             fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] -= fSamples[j];
    2725             mean = fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] / nsample;
    2726           }
    2727         }
    2728       }
    2729       fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] = mean;
    2730     }
    2731   }
    2732   if (fCurrentLowVoltPoint < fNumberOfPointsLowVolt)
    2733     fCurrentLowVoltPoint++;
    2734   else
    2735     fCurrentPoint++;
    2736  
    2737   if (fCurrentPoint == fNumberOfPoints) {
    2738     fCalibrationData[chipNumber]->fEndTemperature = static_cast<float>(fBoard->GetTemperature());
    2739     fRecorded = true;
    2740     fFitted = false;
    2741     fOffset = false;
    2742     fCalibrationData[chipNumber]->fRead = false;
    2743     fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
    2744     fBoard->SetCalibVoltage(0.0);
    2745     fBoard->EnableAcal(1, 0.0);
    2746     fBoard->SetDAC(fBoard->fDAC_CLKOFS, 0.0);
    2747     return true;
    2748   }
    2749  
    2750   return false;
     5331   };
     5332
     5333   // Initialisations
     5334   if (fCurrentLowVoltPoint == 0) {
     5335      fBoard->SetDAC(fBoard->fDAC_CLKOFS, 0);
     5336      // Record Temperature
     5337      fCalibrationData[chipNumber]->fStartTemperature = static_cast < float >(fBoard->GetTemperature());
     5338   }
     5339   // Record current Voltage
     5340   if (fCurrentLowVoltPoint < fNumberOfPointsLowVolt)
     5341      voltage =
     5342          (xpos[0] - minVolt) * fCurrentLowVoltPoint / static_cast <
     5343          double >(fNumberOfPointsLowVolt) + minVolt;
     5344   else
     5345   voltage = xpos[fCurrentPoint];
     5346   fBoard->SetCalibVoltage(voltage);
     5347   fResponseY[fCurrentPoint + fCurrentLowVoltPoint] = static_cast < float >(voltage) * 1000;
     5348
     5349   // Loop Over Number Of Samples For Statistics
     5350   for (j = 0; j < fNumberOfSamples; j++) {
     5351      // Read Out Second Part of the Waveform
     5352      CalibrationTrigger(3, voltage);
     5353      fBoard->TransferWaves();
     5354      for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5355         fBoard->GetRawWave(chipNumber, ii, fWaveFormMode3[ii][j]);
     5356      }
     5357      // Read Out First Part of the Waveform
     5358      CalibrationStart(voltage);
     5359      CalibrationTrigger(2, voltage);
     5360      fBoard->TransferWaves();
     5361      for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5362         fBoard->GetRawWave(chipNumber, ii, fWaveFormMode2[ii][j]);
     5363      }
     5364      CalibrationStart(voltage);
     5365   }
     5366   // Average Sample Points
     5367   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5368      for (k = 0; k < kNumberOfBins; k++) {
     5369         fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] = 0;
     5370         for (j = 0; j < fNumberOfSamples; j++) {
     5371            fSampleUsed[j] = 1;
     5372            if (k < fNumberOfMode2Bins)
     5373               fSamples[j] = fWaveFormMode2[ii][j][k];
     5374            else
     5375               fSamples[j] = fWaveFormMode3[ii][j][k];
     5376            fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] += fSamples[j];
     5377         }
     5378         mean = fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] / fNumberOfSamples;
     5379         notdone = 1;
     5380         nsample = fNumberOfSamples;
     5381         while (notdone) {
     5382            notdone = 0;
     5383            for (j = 0; j < fNumberOfSamples; j++) {
     5384               if (fSampleUsed[j] && abs(static_cast < int >(fSamples[j] - mean)) > 3) {
     5385                  notdone = 1;
     5386                  fSampleUsed[j] = 0;
     5387                  nsample--;
     5388                  fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] -= fSamples[j];
     5389                  mean = fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] / nsample;
     5390               }
     5391            }
     5392         }
     5393         fResponseX[ii][k][fCurrentPoint + fCurrentLowVoltPoint] = mean;
     5394      }
     5395   }
     5396   if (fCurrentLowVoltPoint < fNumberOfPointsLowVolt)
     5397      fCurrentLowVoltPoint++;
     5398   else
     5399      fCurrentPoint++;
     5400
     5401   if (fCurrentPoint == fNumberOfPoints) {
     5402      fCalibrationData[chipNumber]->fEndTemperature = static_cast < float >(fBoard->GetTemperature());
     5403      fRecorded = true;
     5404      fFitted = false;
     5405      fOffset = false;
     5406      fCalibrationData[chipNumber]->fRead = false;
     5407      fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
     5408      fBoard->SetCalibVoltage(0.0);
     5409      fBoard->EnableAcal(1, 0.0);
     5410      fBoard->SetDAC(fBoard->fDAC_CLKOFS, 0.0);
     5411      return true;
     5412   }
     5413
     5414   return false;
    27515415}
    27525416
     
    27555419bool ResponseCalibration::RecordCalibrationPointsV4(int chipNumber)
    27565420{
    2757   int i, j, k, n;
    2758   double voltage, s, s2, average, sigma;
    2759  
    2760   if (fCurrentPoint == 0) {
    2761     fBoard->SetDominoMode(1);
    2762     fBoard->EnableAcal(1,0);
    2763     fBoard->SoftTrigger();
    2764     while (fBoard->IsBusy());
    2765     fBoard->StartDomino();
    2766     fCalibrationData[chipNumber]->fStartTemperature = static_cast<float>(fBoard->GetTemperature());
    2767   }
    2768   voltage = 1.0 * fCurrentPoint / (static_cast<double>(fNumberOfPoints) - 1) + 0.1;
    2769   fBoard->SetCalibVoltage(voltage);
    2770   Sleep(10);
    2771   fBoard->SetCalibVoltage(voltage);
    2772   Sleep(10);
    2773  
    2774   // One dummy cycle for unknown reasons
    2775   fBoard->SoftTrigger();
    2776   while (fBoard->IsBusy());
    2777   fBoard->StartDomino();
    2778   //Sleep(50);
    2779   fBoard->TransferWaves();
    2780  
    2781   // Loop over number of samples for statistics
    2782   for (i = 0; i < fNumberOfSamples; i++) {
     5421   int i, j, k, n;
     5422   double voltage, s, s2, average, sigma;
     5423
     5424   if (fCurrentPoint == 0) {
     5425      fBoard->SetDominoMode(1);
     5426      fBoard->EnableAcal(1, 0);
     5427      fBoard->SoftTrigger();
     5428      while (fBoard->IsBusy());
     5429      fBoard->StartDomino();
     5430      fCalibrationData[chipNumber]->fStartTemperature = static_cast < float >(fBoard->GetTemperature());
     5431   }
     5432   voltage = 1.0 * fCurrentPoint / (static_cast < double >(fNumberOfPoints) - 1) +0.1;
     5433   fBoard->SetCalibVoltage(voltage);
     5434   Sleep(10);
     5435   fBoard->SetCalibVoltage(voltage);
     5436   Sleep(10);
     5437
     5438   // One dummy cycle for unknown reasons
     5439   fBoard->SoftTrigger();
     5440   while (fBoard->IsBusy());
     5441   fBoard->StartDomino();
     5442   Sleep(50);
     5443   fBoard->TransferWaves();
     5444
     5445   // Loop over number of samples for statistics
     5446   for (i = 0; i < fNumberOfSamples; i++) {
     5447      if (fBoard->Debug()) {
     5448         printf("%02d:%02d\r", fNumberOfPoints - fCurrentPoint, fNumberOfSamples - i);
     5449         fflush(stdout);
     5450      }
     5451
     5452
     5453      fBoard->SoftTrigger();
     5454      while (fBoard->IsBusy());
     5455      fBoard->StartDomino();
     5456      Sleep(50);
     5457      fBoard->TransferWaves();
     5458      for (j = 0; j < kNumberOfCalibChannelsV4; j++) {
     5459         fBoard->GetRawWave(chipNumber, j, fWaveFormMode3[j][i]);
     5460      }
     5461   }
     5462
     5463   // Calculate averages
     5464   for (i = 0; i < kNumberOfCalibChannelsV4; i++) {
     5465      for (k = 0; k < kNumberOfBins; k++) {
     5466         s = s2 = 0;
     5467
     5468         for (j = 0; j < fNumberOfSamples; j++) {
     5469            s += fWaveFormMode3[i][j][k];
     5470            s2 += fWaveFormMode3[i][j][k] * fWaveFormMode3[i][j][k];
     5471         }
     5472         n = fNumberOfSamples;
     5473         average = s / n;
     5474         sigma = sqrt((n * s2 - s * s) / (n * (n - 1)));
     5475
     5476         fResponseX[i][k][fCurrentPoint] = static_cast < float >(average);
     5477      }
     5478   }
     5479
    27835480#ifdef DEBUG_CALIB
    2784     printf("%d   \r", fNumberOfSamples-i);
     5481   for (j = 0; j < fNumberOfSamples; j++)
     5482      printf("%d ", fWaveFormMode3[1][j][10]);
     5483
     5484   s = s2 = 0;
     5485   for (j = 0; j < fNumberOfSamples; j++) {
     5486      s += fWaveFormMode3[i][j][k];
     5487      s2 += fWaveFormMode3[i][j][k] * fWaveFormMode3[i][j][k];
     5488   }
     5489   n = fNumberOfSamples;
     5490   average = s / n;
     5491   sigma = sqrt((n * s2 - s * s) / (n * (n - 1)));
     5492
     5493   printf("\n");
     5494   printf("%1.2lf V: %6.1lf (%1.4lf)\n", voltage,
     5495          fResponseX[1][10][fCurrentPoint], fResponseX[1][10][fCurrentPoint] / 4096.0);
    27855496#endif
    2786     fBoard->SoftTrigger();
    2787     while (fBoard->IsBusy());
    2788     fBoard->StartDomino();
    2789     //Sleep(50);
    2790     fBoard->TransferWaves();
    2791     for (j = 0; j < kNumberOfCalibChannels; j++) {
    2792       fBoard->GetADCWave(chipNumber, j, fWaveFormMode3[j][i]);
    2793     }
    2794   }
    2795  
    2796   for (i = 0; i < kNumberOfCalibChannels; i++) {
    2797     for (k = 0; k < kNumberOfBins; k++) {
    2798       s = s2 = 0;
    2799      
    2800       for (j=0 ; j<fNumberOfSamples ; j++) {
    2801         s += fWaveFormMode3[i][j][k];
    2802         s2 += fWaveFormMode3[i][j][k] * fWaveFormMode3[i][j][k];
    2803       }
    2804       n = fNumberOfSamples;
    2805       average = s / n;
    2806       sigma = sqrt( (n*s2 - s*s) / (n*(n - 1)) );
    2807      
    2808       fResponseX[i][k][fCurrentPoint] = static_cast<float>(average);
    2809     }
    2810   }
    2811  
    2812 #ifdef DEBUG_CALIB
    2813   for (j = 0; j < fNumberOfSamples; j++)
    2814     printf("%d ", fWaveFormMode3[1][j][10]);
    2815  
    2816   s = s2 = 0;
    2817   for (j = 0; j < fNumberOfSamples; j++) {
    2818     s += fWaveFormMode3[i][j][k];
    2819     s2 += fWaveFormMode3[i][j][k] * fWaveFormMode3[i][j][k];
    2820   }
    2821   n = fNumberOfSamples;
    2822   average = s / n;
    2823   sigma = sqrt( (n*s2 - s*s) / (n*(n - 1)) );
    2824  
    2825   printf("\n");
    2826   printf("%1.2lf V: %6.1lf (%1.4lf)\n", voltage,
    2827          fResponseX[1][10][fCurrentPoint],
    2828          fResponseX[1][10][fCurrentPoint]/4096.0);
     5497
     5498   fCurrentPoint++;
     5499   if (fCurrentPoint == fNumberOfPoints) {
     5500      fCalibrationData[chipNumber]->fEndTemperature = static_cast < float >(fBoard->GetTemperature());
     5501      fRecorded = true;
     5502      return true;
     5503   }
     5504
     5505   return false;
     5506}
     5507
     5508/*------------------------------------------------------------------*/
     5509
     5510bool ResponseCalibration::FitCalibrationPoints(int chipNumber)
     5511{
     5512   if (!fRecorded || fFitted)
     5513      return true;
     5514   if (fBoard->GetDRSType() == 3)
     5515      return FitCalibrationPointsV4(chipNumber);
     5516   else
     5517      return FitCalibrationPointsV3(chipNumber);
     5518}
     5519
     5520/*------------------------------------------------------------------*/
     5521
     5522bool ResponseCalibration::FitCalibrationPointsV3(int chipNumber)
     5523{
     5524   int i, j, k;
     5525   float x1, x2, y1, y2;
     5526   float uu;
     5527   float yc, yr;
     5528   float xminExt, xrangeExt;
     5529   float xmin, xrange;
     5530   float average, averageError, averageExt, averageErrorExt;
     5531   unsigned short i0, i1;
     5532
     5533   CalibrationData *data = fCalibrationData[chipNumber];
     5534   CalibrationData::CalibrationDataChannel * chn = data->fChannel[fCurrentFitChannel];
     5535
     5536   data->DeletePreCalculatedBSpline();
     5537
     5538   if (fCurrentFitBin == 0 && fCurrentFitChannel == 0) {
     5539      data->fNumberOfLimitGroups = 0;
     5540      data->fMin = 100000;
     5541      data->fMax = -100000;
     5542      for (i = 0; i < kNumberOfCalibChannelsV3; i++) {
     5543         for (j = 0; j < kNumberOfBins; j++) {
     5544            if (data->fMin > fResponseX[i][j][fNumberOfPointsLowVolt + fNumberOfPoints - 1])
     5545               data->fMin = fResponseX[i][j][fNumberOfPointsLowVolt + fNumberOfPoints - 1];
     5546            if (data->fMax < fResponseX[i][j][fNumberOfPointsLowVolt])
     5547               data->fMax = fResponseX[i][j][fNumberOfPointsLowVolt];
     5548         }
     5549      }
     5550   }
     5551   // Low Volt
     5552   i0 = static_cast < unsigned short >(fResponseX[fCurrentFitChannel][fCurrentFitBin][0]);
     5553   i1 = static_cast <
     5554       unsigned short >(fResponseX[fCurrentFitChannel][fCurrentFitBin][fNumberOfPointsLowVolt]) + 1;
     5555   chn->fLookUpOffset[fCurrentFitBin] = i0;
     5556   delete chn->fLookUp[fCurrentFitBin];
     5557   if (i0 - i1 + 1 < 2) {
     5558      chn->fNumberOfLookUpPoints[fCurrentFitBin] = 2;
     5559      chn->fLookUp[fCurrentFitBin] = new unsigned char[2];
     5560      chn->fLookUp[fCurrentFitBin][0] = 0;
     5561      chn->fLookUp[fCurrentFitBin][1] = 0;
     5562   } else {
     5563      chn->fNumberOfLookUpPoints[fCurrentFitBin] = i0 - i1 + 1;
     5564      chn->fLookUp[fCurrentFitBin] = new unsigned char[i0 - i1 + 1];
     5565      for (i = 0; i < i0 - i1 + 1; i++) {
     5566         for (j = 0; j < fNumberOfPointsLowVolt; j++) {
     5567            if (i0 - i >= fResponseX[fCurrentFitChannel][fCurrentFitBin][j + 1]) {
     5568               x1 = fResponseX[fCurrentFitChannel][fCurrentFitBin][j];
     5569               x2 = fResponseX[fCurrentFitChannel][fCurrentFitBin][j + 1];
     5570               y1 = fResponseY[j];
     5571               y2 = fResponseY[j + 1];
     5572               chn->fLookUp[fCurrentFitBin][i] =
     5573                   static_cast < unsigned char >(((y2 - y1) * (i0 - i - x1) / (x2 - x1) + y1) / fPrecision);
     5574               break;
     5575            }
     5576         }
     5577      }
     5578   }
     5579
     5580   // Copy Points
     5581   for (i = 0; i < fNumberOfPoints; i++) {
     5582      fPntX[0][i] = fResponseX[fCurrentFitChannel][fCurrentFitBin][fNumberOfPointsLowVolt + i];
     5583      fPntY[0][i] = fResponseY[fNumberOfPointsLowVolt + i];
     5584   }
     5585   // Fit BSpline
     5586   for (i = 0; i < fNumberOfPoints; i++) {
     5587      fUValues[0][i] = static_cast < float >(1 - i / (fNumberOfPoints - 1.));
     5588   }
     5589   if (!Approx(fPntX[0], fUValues[0], fNumberOfPoints, fNumberOfGridPoints, fResX[fCurrentFitBin]))
     5590      return true;
     5591   if (!Approx(fPntY[0], fUValues[0], fNumberOfPoints, fNumberOfGridPoints, fRes[fCurrentFitBin]))
     5592      return true;
     5593
     5594   // X constant fit
     5595   for (k = 0; k < fNumberOfXConstPoints - 2; k++) {
     5596      fPntX[1][k + 1] =
     5597          GetValue(fResX[fCurrentFitBin],
     5598                   static_cast < float >(1 - k / static_cast < float >(fNumberOfXConstPoints - 3)),
     5599                   fNumberOfGridPoints);
     5600      fPntY[1][k + 1] =
     5601          GetValue(fRes[fCurrentFitBin],
     5602                   static_cast < float >(1 - k / static_cast < float >(fNumberOfXConstPoints - 3)),
     5603                   fNumberOfGridPoints);
     5604   }
     5605   xmin = fPntX[1][fNumberOfXConstPoints - 2];
     5606   xrange = fPntX[1][1] - xmin;
     5607
     5608   for (i = 0; i < fNumberOfXConstPoints - 2; i++) {
     5609      fUValues[1][i + 1] = (fPntX[1][i + 1] - xmin) / xrange;
     5610   }
     5611
     5612   if (!Approx
     5613       (&fPntY[1][1], &fUValues[1][1], fNumberOfXConstPoints - 2, fNumberOfXConstGridPoints, chn->fTempData))
     5614      return true;
     5615
     5616   // error statistics
     5617   if (fShowStatistics) {
     5618      for (i = 0; i < fNumberOfPoints; i++) {
     5619         uu = (fPntX[0][i] - xmin) / xrange;
     5620         yc = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
     5621         yr = fPntY[0][i];
     5622         fStatisticsApprox[i][fCurrentFitBin + fCurrentFitChannel * kNumberOfBins] = yc - yr;
     5623      }
     5624   }
     5625   // Add min and max point
     5626   chn->fLimitGroup[fCurrentFitBin] = 0;
     5627   while (xmin - kBSplineXMinOffset > data->fMin + kBSplineXMinOffset * chn->fLimitGroup[fCurrentFitBin]) {
     5628      chn->fLimitGroup[fCurrentFitBin]++;
     5629   }
     5630   if (data->fNumberOfLimitGroups <= chn->fLimitGroup[fCurrentFitBin])
     5631      data->fNumberOfLimitGroups = chn->fLimitGroup[fCurrentFitBin] + 1;
     5632   xminExt = data->fMin + kBSplineXMinOffset * chn->fLimitGroup[fCurrentFitBin];
     5633   xrangeExt = data->fMax - xminExt;
     5634
     5635   fPntX[1][0] = data->fMax;
     5636   uu = (fPntX[1][0] - xmin) / xrange;
     5637   fPntY[1][0] = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
     5638
     5639   fPntX[1][fNumberOfXConstPoints - 1] = xminExt;
     5640   uu = (fPntX[1][fNumberOfXConstPoints - 1] - xmin) / xrange;
     5641   fPntY[1][fNumberOfXConstPoints - 1] = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
     5642
     5643   for (i = 0; i < fNumberOfXConstPoints; i++) {
     5644      fUValues[1][i] = (fPntX[1][i] - xminExt) / xrangeExt;
     5645   }
     5646
     5647   if (!Approx(fPntY[1], fUValues[1], fNumberOfXConstPoints, fNumberOfXConstGridPoints, chn->fTempData))
     5648      return true;
     5649
     5650   // error statistics
     5651   if (fShowStatistics) {
     5652      for (i = 0; i < fNumberOfPoints; i++) {
     5653         uu = (fPntX[0][i] - xminExt) / xrangeExt;
     5654         yc = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
     5655         yr = fPntY[0][i];
     5656         fStatisticsApproxExt[i][fCurrentFitBin + fCurrentFitChannel * kNumberOfBins] = yc - yr;
     5657      }
     5658   }
     5659   for (i = 0; i < fNumberOfXConstGridPoints; i++) {
     5660      chn->fData[fCurrentFitBin][i] = static_cast < short >(chn->fTempData[i] / fPrecision);
     5661   }
     5662
     5663   // write end of file
     5664   fCurrentFitBin++;
     5665   if (fCurrentFitBin == kNumberOfBins) {
     5666      fCurrentFitChannel++;
     5667      fCurrentFitBin = 0;
     5668   }
     5669   if (fCurrentFitChannel == kNumberOfCalibChannelsV3) {
     5670      if (fShowStatistics) {
     5671         for (i = 0; i < fNumberOfPoints; i++) {
     5672            average = 0;
     5673            averageError = 0;
     5674            averageExt = 0;
     5675            averageErrorExt = 0;
     5676            for (j = 0; j < kNumberOfCalibChannelsV3 * kNumberOfBins; j++) {
     5677               average += fStatisticsApprox[i][j];
     5678               averageError += fStatisticsApprox[i][j] * fStatisticsApprox[i][j];
     5679               averageExt += fStatisticsApproxExt[i][j];
     5680               averageErrorExt += fStatisticsApproxExt[i][j] * fStatisticsApproxExt[i][j];
     5681            }
     5682            average /= kNumberOfCalibChannelsV3 * kNumberOfBins;
     5683            averageError =
     5684                sqrt((averageError -
     5685                      average * average / kNumberOfCalibChannelsV3 * kNumberOfBins) /
     5686                     (kNumberOfCalibChannelsV3 * kNumberOfBins - 1));
     5687            averageExt /= kNumberOfCalibChannelsV3 * kNumberOfBins;
     5688            averageErrorExt =
     5689                sqrt((averageErrorExt -
     5690                      averageExt * averageExt / kNumberOfCalibChannelsV3 * kNumberOfBins) /
     5691                     (kNumberOfCalibChannelsV3 * kNumberOfBins - 1));
     5692            printf("Error at %3.1f V : % 2.3f +- % 2.3f ; % 2.3f +- % 2.3f\n", fPntY[0][i], average,
     5693                   averageError, averageExt, averageErrorExt);
     5694         }
     5695      }
     5696      fFitted = true;
     5697      fOffset = false;
     5698      fCalibrationData[chipNumber]->fRead = true;
     5699      fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
     5700      data->PreCalculateBSpline();
     5701      return true;
     5702   }
     5703   return false;
     5704}
     5705
     5706/*------------------------------------------------------------------*/
     5707
     5708bool ResponseCalibration::FitCalibrationPointsV4(int chipNumber)
     5709{
     5710   if (!fRecorded || fFitted)
     5711      return true;
     5712   int i;
     5713   double par[2];
     5714   static int error;
     5715
     5716   CalibrationData *data = fCalibrationData[chipNumber];
     5717   CalibrationData::CalibrationDataChannel * chn = data->fChannel[fCurrentFitChannel];
     5718
     5719   if (fCurrentFitBin == 0 && fCurrentFitChannel == 0) {
     5720      error = 0;
     5721      for (i = 0; i < fNumberOfPoints; i++)
     5722         fWWFit[i] = 1;
     5723   }
     5724
     5725   for (i = 0; i < fNumberOfPoints; i++) {
     5726      fXXFit[i] = 1.0 * i / (static_cast < double >(fNumberOfPoints) - 1) +0.1;
     5727      fYYFit[i] = fResponseX[fCurrentFitChannel][fCurrentFitBin][i];
     5728      if (fCurrentFitBin == 10 && fCurrentFitChannel == 1) {
     5729         fXXSave[i] = fXXFit[i];
     5730         fYYSave[i] = fYYFit[i];
     5731      }
     5732   }
     5733
     5734   // DRSBoard::LinearRegression(fXXFit, fYYFit, fNumberOfPoints, &par[1], &par[0]);
     5735   // exclude first two points (sometimes are on limit of FADC)
     5736   DRSBoard::LinearRegression(fXXFit + 2, fYYFit + 2, fNumberOfPoints - 2, &par[1], &par[0]);
     5737
     5738   chn->fOffset[fCurrentFitBin] = static_cast < unsigned short >(par[0] + 0.5);
     5739   chn->fGain[fCurrentFitBin] = static_cast < unsigned short >(par[1] + 0.5);
     5740
     5741   // Remember min/max of gain
     5742   if (fCurrentFitBin == 0 && fCurrentFitChannel == 0)
     5743      fGainMin = fGainMax = chn->fGain[0];
     5744   if (chn->fGain[fCurrentFitBin] < fGainMin)
     5745      fGainMin = chn->fGain[fCurrentFitBin];
     5746   if (chn->fGain[fCurrentFitBin] > fGainMax)
     5747      fGainMax = chn->fGain[fCurrentFitBin];
     5748
     5749   // abort if outside normal region
     5750   if (chn->fGain[fCurrentFitBin] / 4096.0 < 0.8 || chn->fGain[fCurrentFitBin] / 4096.0 > 1) {
     5751      error++;
     5752
     5753      if (error < 20)
     5754         printf("Gain=%1.3lf for bin %d on channel %d on chip %d outside valid region\n",
     5755                chn->fGain[fCurrentFitBin] / 4096.0, fCurrentFitBin, fCurrentFitChannel, chipNumber);
     5756   }
     5757
     5758   if (fCurrentFitChannel == 1 && fCurrentFitBin == 10) {
     5759      for (i = 0; i < fNumberOfPoints; i++) {
     5760         fXXSave[i] = fXXFit[i];
     5761         fYYSave[i] = (fYYFit[i] - chn->fOffset[10]) / chn->fGain[10] - fXXFit[i];
     5762      }
     5763   }
     5764
     5765   fCurrentFitBin++;
     5766   if (fCurrentFitBin == kNumberOfBins) {
     5767      fCurrentFitChannel++;
     5768      fCurrentFitBin = 0;
     5769   }
     5770   if (fCurrentFitChannel == kNumberOfCalibChannelsV4) {
     5771
     5772      if (fBoard->Debug()) {
     5773         printf("Gain min=%1.3lf max=%1.3lf\n", fGainMin / 4096.0, fGainMax / 4096.0);
     5774         fflush(stdout);
     5775      }
     5776      // allow up to three bad bins
     5777      if (error > 3) {
     5778         printf("Aborting calibration!\n");
     5779         return true;
     5780      }
     5781
     5782      fFitted = true;
     5783      fOffset = false;
     5784      fCalibrationData[chipNumber]->fRead = true;
     5785      fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
     5786      return true;
     5787   }
     5788
     5789   return false;
     5790}
     5791
     5792unsigned int millitime()
     5793{
     5794#ifdef _MSC_VER
     5795
     5796   return (int) GetTickCount();
     5797
     5798#else
     5799   struct timeval tv;
     5800
     5801   gettimeofday(&tv, NULL);
     5802
     5803   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
    28295804#endif
    2830  
    2831   fCurrentPoint++;
    2832   if (fCurrentPoint == fNumberOfPoints) {
    2833     fCalibrationData[chipNumber]->fEndTemperature = static_cast<float>(fBoard->GetTemperature());
    2834     fRecorded = true;
    2835     return true;
    2836   }
    2837  
    2838   return false;
    2839 }
    2840 
    2841 /*------------------------------------------------------------------*/
    2842 
    2843 bool ResponseCalibration::FitCalibrationPoints(int chipNumber)
    2844 {
    2845   if (!fRecorded || fFitted)
    2846     return true;
    2847   if (fBoard->GetChipVersion() == 3)
    2848     return FitCalibrationPointsV4(chipNumber);
    2849   else
    2850     return FitCalibrationPointsV3(chipNumber);
    2851 }
    2852 
    2853 /*------------------------------------------------------------------*/
    2854 
    2855 bool ResponseCalibration::FitCalibrationPointsV3(int chipNumber)
    2856 {
    2857   int i, j, k;
    2858   float x1, x2, y1, y2;
    2859   float uu;
    2860   float yc, yr;
    2861   float xminExt, xrangeExt;
    2862   float xmin, xrange;
    2863   float average, averageError, averageExt, averageErrorExt;
    2864   unsigned short i0, i1;
    2865  
    2866   CalibrationData *data = fCalibrationData[chipNumber];
    2867   CalibrationData::CalibrationDataChannel * chn = data->fChannel[fCurrentFitChannel];
    2868  
    2869   data->DeletePreCalculatedBSpline();
    2870  
    2871   if (fCurrentFitBin == 0 && fCurrentFitChannel == 0) {
    2872     data->fNumberOfLimitGroups = 0;
    2873     data->fMin = 100000;
    2874     data->fMax = -100000;
    2875     for (i = 0; i < kNumberOfCalibChannels; i++) {
    2876       for (j = 0; j < kNumberOfBins; j++) {
    2877         if (data->fMin > fResponseX[i][j][fNumberOfPointsLowVolt + fNumberOfPoints - 1])
    2878           data->fMin = fResponseX[i][j][fNumberOfPointsLowVolt + fNumberOfPoints - 1];
    2879         if (data->fMax < fResponseX[i][j][fNumberOfPointsLowVolt])
    2880           data->fMax = fResponseX[i][j][fNumberOfPointsLowVolt];
    2881       }
    2882     }
    2883   }
    2884 
    2885   // Low Volt
    2886   i0 = static_cast<unsigned short>(fResponseX[fCurrentFitChannel][fCurrentFitBin][0]);
    2887   i1 = static_cast<unsigned short>(fResponseX[fCurrentFitChannel][fCurrentFitBin][fNumberOfPointsLowVolt]) + 1;
    2888   chn->fLookUpOffset[fCurrentFitBin] = i0;
    2889   delete chn->fLookUp[fCurrentFitBin];
    2890   if (i0 - i1 + 1 < 2) {
    2891     chn->fNumberOfLookUpPoints[fCurrentFitBin] = 2;
    2892     chn->fLookUp[fCurrentFitBin] = new unsigned char[2];
    2893     chn->fLookUp[fCurrentFitBin][0] = 0;
    2894     chn->fLookUp[fCurrentFitBin][1] = 0;
    2895   } else {
    2896     chn->fNumberOfLookUpPoints[fCurrentFitBin] = i0 - i1 + 1;
    2897     chn->fLookUp[fCurrentFitBin] = new unsigned char[i0 - i1 + 1];
    2898     for (i = 0; i < i0 - i1 + 1; i++) {
    2899       for (j = 0; j < fNumberOfPointsLowVolt; j++) {
    2900         if (i0 - i >= fResponseX[fCurrentFitChannel][fCurrentFitBin][j + 1]) {
    2901           x1 = fResponseX[fCurrentFitChannel][fCurrentFitBin][j];
    2902           x2 = fResponseX[fCurrentFitChannel][fCurrentFitBin][j + 1];
    2903           y1 = fResponseY[j];
    2904           y2 = fResponseY[j + 1];
    2905           chn->fLookUp[fCurrentFitBin][i] = static_cast<unsigned char>(((y2 - y1) * (i0 - i - x1) / (x2 - x1) + y1)/fPrecision);
    2906           break;
    2907         }
    2908       }
    2909     }
    2910   }
    2911  
    2912 
    2913   // Copy Points
    2914   for (i = 0; i < fNumberOfPoints; i++) {
    2915     fPntX[0][i] = fResponseX[fCurrentFitChannel][fCurrentFitBin][fNumberOfPointsLowVolt + i];
    2916     fPntY[0][i] = fResponseY[fNumberOfPointsLowVolt + i];
    2917   }
    2918   // Fit BSpline
    2919   for (i = 0; i < fNumberOfPoints; i++) {
    2920     fUValues[0][i] = static_cast<float>(1 - i / (fNumberOfPoints - 1.));
    2921   }
    2922   if (!Approx(fPntX[0], fUValues[0], fNumberOfPoints, fNumberOfGridPoints, fResX[fCurrentFitBin]))
    2923     return true;
    2924   if (!Approx(fPntY[0], fUValues[0], fNumberOfPoints, fNumberOfGridPoints, fRes[fCurrentFitBin]))
    2925     return true;
    2926  
    2927 
    2928   // X constant fit
    2929   for (k = 0; k < fNumberOfXConstPoints - 2; k++) {
    2930     fPntX[1][k + 1] =
    2931       GetValue(fResX[fCurrentFitBin], static_cast<float>(1 - k / static_cast<float>(fNumberOfXConstPoints - 3)),
    2932                fNumberOfGridPoints);
    2933     fPntY[1][k + 1] =
    2934       GetValue(fRes[fCurrentFitBin], static_cast<float>(1 - k / static_cast<float>(fNumberOfXConstPoints - 3)),
    2935                fNumberOfGridPoints);
    2936   }
    2937   xmin = fPntX[1][fNumberOfXConstPoints - 2];
    2938   xrange = fPntX[1][1] - xmin;
    2939  
    2940   for (i = 0; i < fNumberOfXConstPoints - 2; i++) {
    2941     fUValues[1][i + 1] = (fPntX[1][i + 1] - xmin) / xrange;
    2942   }
    2943  
    2944   if (!Approx
    2945       (&fPntY[1][1], &fUValues[1][1], fNumberOfXConstPoints - 2, fNumberOfXConstGridPoints,
    2946        chn->fTempData))
    2947     return true;
    2948 
    2949  
    2950   // Error statistics
    2951   if (fShowStatistics) {
    2952     for (i = 0; i < fNumberOfPoints; i++) {
    2953       uu = (fPntX[0][i] - xmin) / xrange;
    2954       yc = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
    2955       yr = fPntY[0][i];
    2956       fStatisticsApprox[i][fCurrentFitBin + fCurrentFitChannel * kNumberOfBins] = yc - yr;
    2957     }
    2958   }
    2959   // Add min and max point
    2960   chn->fLimitGroup[fCurrentFitBin] = 0;
    2961   while (xmin - kBSplineXMinOffset > data->fMin + kBSplineXMinOffset * chn->fLimitGroup[fCurrentFitBin]) {
    2962     chn->fLimitGroup[fCurrentFitBin]++;
    2963   }
    2964   if (data->fNumberOfLimitGroups <= chn->fLimitGroup[fCurrentFitBin])
    2965     data->fNumberOfLimitGroups = chn->fLimitGroup[fCurrentFitBin] + 1;
    2966   xminExt = data->fMin + kBSplineXMinOffset * chn->fLimitGroup[fCurrentFitBin];
    2967   xrangeExt = data->fMax - xminExt;
    2968  
    2969   fPntX[1][0] = data->fMax;
    2970   uu = (fPntX[1][0] - xmin) / xrange;
    2971   fPntY[1][0] = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
    2972  
    2973   fPntX[1][fNumberOfXConstPoints - 1] = xminExt;
    2974   uu = (fPntX[1][fNumberOfXConstPoints - 1] - xmin) / xrange;
    2975   fPntY[1][fNumberOfXConstPoints - 1] = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
    2976  
    2977   for (i = 0; i < fNumberOfXConstPoints; i++) {
    2978     fUValues[1][i] = (fPntX[1][i] - xminExt) / xrangeExt;
    2979   }
    2980  
    2981   if (!Approx
    2982       (fPntY[1], fUValues[1], fNumberOfXConstPoints, fNumberOfXConstGridPoints, chn->fTempData))
    2983     return true;
    2984  
    2985   // Error statistics
    2986   if (fShowStatistics) {
    2987     for (i = 0; i < fNumberOfPoints; i++) {
    2988       uu = (fPntX[0][i] - xminExt) / xrangeExt;
    2989       yc = GetValue(chn->fTempData, uu, fNumberOfXConstGridPoints);
    2990       yr = fPntY[0][i];
    2991       fStatisticsApproxExt[i][fCurrentFitBin + fCurrentFitChannel * kNumberOfBins] = yc - yr;
    2992     }
    2993   }
    2994   for (i = 0; i < fNumberOfXConstGridPoints; i++) {
    2995     chn->fData[fCurrentFitBin][i] = static_cast<short>(chn->fTempData[i] / fPrecision);
    2996   }
    2997  
    2998 
    2999   // Write end of file
    3000   fCurrentFitBin++;
    3001   if (fCurrentFitBin == kNumberOfBins) {
    3002     fCurrentFitChannel++;
    3003     fCurrentFitBin = 0;
    3004   }
    3005   if (fCurrentFitChannel == kNumberOfCalibChannels) {
    3006     if (fShowStatistics) {
    3007       for (i = 0; i < fNumberOfPoints; i++) {
    3008         average = 0;
    3009         averageError = 0;
    3010         averageExt = 0;
    3011         averageErrorExt = 0;
    3012         for (j = 0; j < kNumberOfCalibChannels * kNumberOfBins; j++) {
    3013           average += fStatisticsApprox[i][j];
    3014           averageError += fStatisticsApprox[i][j] * fStatisticsApprox[i][j];
    3015           averageExt += fStatisticsApproxExt[i][j];
    3016           averageErrorExt += fStatisticsApproxExt[i][j] * fStatisticsApproxExt[i][j];
    3017         }
    3018         average /= kNumberOfCalibChannels * kNumberOfBins;
    3019         averageError =
    3020           sqrt((averageError -
    3021                 average * average / kNumberOfCalibChannels * kNumberOfBins) / (kNumberOfCalibChannels *
    3022                                                                                kNumberOfBins - 1));
    3023         averageExt /= kNumberOfCalibChannels * kNumberOfBins;
    3024         averageErrorExt =
    3025           sqrt((averageErrorExt -
    3026                 averageExt * averageExt / kNumberOfCalibChannels * kNumberOfBins) /
    3027                (kNumberOfCalibChannels * kNumberOfBins - 1));
    3028         printf("Error at %3.1f V : % 2.3f +- % 2.3f ; % 2.3f +- % 2.3f\n", fPntY[0][i], average,
    3029                averageError, averageExt, averageErrorExt);
    3030       }
    3031     }
    3032     fFitted = true;
    3033     fOffset = false;
    3034     fCalibrationData[chipNumber]->fRead = true;
    3035     fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
    3036     data->PreCalculateBSpline();
    3037     return true;
    3038   }
    3039   return false;
    3040 }
    3041 
    3042 /*------------------------------------------------------------------*/
    3043 
    3044 bool ResponseCalibration::FitCalibrationPointsV4(int chipNumber)
    3045 {
    3046   if (!fRecorded || fFitted)
    3047     return true;
    3048   int i;
    3049   double par[2];
    3050  
    3051   CalibrationData *data = fCalibrationData[chipNumber];
    3052   CalibrationData::CalibrationDataChannel * chn = data->fChannel[fCurrentFitChannel];
    3053  
    3054   if (fCurrentFitBin == 0 && fCurrentFitChannel == 0) {
    3055     for (i = 0; i < fNumberOfPoints; i++)
    3056       fWWFit[i] = 1;
    3057   }
    3058  
    3059   for (i = 0; i < fNumberOfPoints; i++) {
    3060     fXXFit[i] = 1.0 * i / (static_cast<double>(fNumberOfPoints) - 1) + 0.1;
    3061     fYYFit[i] = fResponseX[fCurrentFitChannel][fCurrentFitBin][i];
    3062     if (fCurrentFitBin == 10 && fCurrentFitChannel == 1) {
    3063       fXXSave[i] = fXXFit[i];
    3064       fYYSave[i] = fYYFit[i];
    3065     }
    3066   }
    3067  
    3068   DRSBoard::LinearRegression(fXXFit, fYYFit, fNumberOfPoints, &par[1], &par[0]);
    3069   chn->fOffset[fCurrentFitBin] = static_cast<short>(par[0] + 0.5);
    3070   chn->fGain[fCurrentFitBin] = static_cast<short>(par[1] + 0.5);
    3071  
    3072   if (fCurrentFitChannel == 1 && fCurrentFitBin == 10) {
    3073 #ifdef DEBUG_CALIB
    3074     printf("gain:%d, offset:%d\n", chn->fGain[10], chn->fOffset[10]);
    3075 #endif
    3076     for (i = 0; i < fNumberOfPoints; i++) {
    3077       fXXSave[i] = fXXFit[i];
    3078       fYYSave[i] = (fYYFit[i] - chn->fOffset[10]) / chn->fGain[10] - fXXFit[i];
    3079     }
    3080   }
    3081  
    3082   fCurrentFitBin++;
    3083   if (fCurrentFitBin == kNumberOfBins) {
    3084     fCurrentFitChannel++;
    3085     fCurrentFitBin = 0;
    3086   }
    3087   if (fCurrentFitChannel == kNumberOfCalibChannels) {
    3088     fFitted = true;
    3089     fOffset = true;
    3090     fCalibrationData[chipNumber]->fRead = true;
    3091     fCalibrationData[chipNumber]->fHasOffsetCalibration = false;
    3092     return true;
    3093   }
    3094  
    3095   return false;
    3096 }
    3097 
    3098 unsigned int millitime()
    3099 {
    3100   struct timeval tv;
    3101  
    3102   gettimeofday(&tv, NULL);
    3103  
    3104   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
     5805   return 0;
    31055806}
    31065807
     
    31095810bool ResponseCalibration::OffsetCalibration(int chipNumber)
    31105811{
    3111   if (!fFitted || fOffset)
    3112     return true;
    3113   int k, ii, j;
    3114   int t1, t2;
    3115   float mean,error;
    3116   CalibrationData *data = fCalibrationData[chipNumber];
    3117   CalibrationData::CalibrationDataChannel * chn;
    3118  
    3119   if (fCurrentSample == 0) {
    3120     data->fHasOffsetCalibration = false;
    3121     fBoard->SetCalibVoltage(0.0);
    3122     fBoard->EnableAcal(1, 0.0);
    3123   }
    3124   // Loop Over Number Of Samples For Statistics
    3125   t1 = millitime();
    3126   fBoard->SoftTrigger();
    3127   while (fBoard->IsBusy()) {
    3128   }
    3129   fBoard->TransferWaves();
    3130   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3131     fBoard->GetADCWave(chipNumber, ii, fWaveFormOffsetADC[ii][fCurrentSample]);
    3132     fBoard->CalibrateWaveform(chipNumber, ii, fWaveFormOffsetADC[ii][fCurrentSample], fWaveFormOffset[ii][fCurrentSample],
    3133                               true, false, false, 0);
    3134   }
    3135   fBoard->StartDomino();
    3136   fBoard->IsBusy();
    3137   fBoard->IsBusy();
    3138   fBoard->IsBusy();
    3139   t2 = millitime();
    3140   while (t2 - t1 < (1000 / fTriggerFrequency)) {
    3141     t2 = millitime();
    3142   }
    3143   fCurrentSample++;
    3144  
    3145   if (fCurrentSample == fNumberOfSamples) {
    3146     // Average Sample Points
    3147     float *sample = new float[fNumberOfSamples];
    3148     for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3149       chn = data->fChannel[ii];
    3150       for (k = 0; k < kNumberOfBins; k++) {
    3151         for (j = 0; j < fNumberOfSamples; j++)
    3152           sample[j] = static_cast<float>(fWaveFormOffset[ii][j][k]);
    3153         Average(1, sample, fNumberOfSamples, mean, error, 2);
    3154         chn->fOffset[k] = static_cast<short>(mean);
    3155         for (j = 0; j < fNumberOfSamples; j++)
    3156           sample[j] = fWaveFormOffsetADC[ii][j][k];
    3157         Average(1, sample, fNumberOfSamples, mean, error, 2);
    3158         chn->fOffsetADC[k] = static_cast<unsigned short>(mean);
    3159       }
    3160     }
    3161     fOffset = true;
    3162     fCalibrationData[chipNumber]->fHasOffsetCalibration = true;
    3163     delete sample;
    3164     return true;
    3165   }
    3166  
    3167   return false;
     5812   if (!fFitted || fOffset)
     5813      return true;
     5814   if (fBoard->GetDRSType() == 3)
     5815      return OffsetCalibrationV4(chipNumber);
     5816   else
     5817      return OffsetCalibrationV3(chipNumber);
     5818}
     5819
     5820/*------------------------------------------------------------------*/
     5821
     5822bool ResponseCalibration::OffsetCalibrationV3(int chipNumber)
     5823{
     5824   int k, ii, j;
     5825   int t1, t2;
     5826   float mean, error;
     5827   CalibrationData *data = fCalibrationData[chipNumber];
     5828   CalibrationData::CalibrationDataChannel * chn;
     5829
     5830   if (fCurrentSample == 0) {
     5831      data->fHasOffsetCalibration = false;
     5832      fBoard->SetCalibVoltage(0.0);
     5833      fBoard->EnableAcal(0, 0.0);
     5834   }
     5835   // Loop Over Number Of Samples For Statistics
     5836   t1 = millitime();
     5837   fBoard->SoftTrigger();
     5838   while (fBoard->IsBusy()) {
     5839   }
     5840   fBoard->TransferWaves();
     5841   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5842      fBoard->GetRawWave(chipNumber, ii, fWaveFormOffsetADC[ii][fCurrentSample]);
     5843      fBoard->CalibrateWaveform(chipNumber, ii, fWaveFormOffsetADC[ii][fCurrentSample],
     5844                                fWaveFormOffset[ii][fCurrentSample], true, false, false, 0, true);
     5845   }
     5846   fBoard->StartDomino();
     5847   fBoard->IsBusy();
     5848   fBoard->IsBusy();
     5849   fBoard->IsBusy();
     5850   t2 = millitime();
     5851   while (t2 - t1 < (1000 / fTriggerFrequency)) {
     5852      t2 = millitime();
     5853   }
     5854   fCurrentSample++;
     5855
     5856   if (fCurrentSample == fNumberOfSamples) {
     5857      // Average Sample Points
     5858      float *sample = new float[fNumberOfSamples];
     5859      for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5860         chn = data->fChannel[ii];
     5861         for (k = 0; k < kNumberOfBins; k++) {
     5862            for (j = 0; j < fNumberOfSamples; j++)
     5863               sample[j] = static_cast < float >(fWaveFormOffset[ii][j][k]);
     5864            Average(1, sample, fNumberOfSamples, mean, error, 2);
     5865            chn->fOffset[k] = static_cast < short >(mean);
     5866            for (j = 0; j < fNumberOfSamples; j++)
     5867               sample[j] = fWaveFormOffsetADC[ii][j][k];
     5868            Average(1, sample, fNumberOfSamples, mean, error, 2);
     5869            chn->fOffsetADC[k] = static_cast < unsigned short >(mean);
     5870         }
     5871      }
     5872      fOffset = true;
     5873      fCalibrationData[chipNumber]->fHasOffsetCalibration = true;
     5874      delete sample;
     5875      return true;
     5876   }
     5877
     5878   return false;
     5879}
     5880
     5881/*------------------------------------------------------------------*/
     5882
     5883bool ResponseCalibration::OffsetCalibrationV4(int chipNumber)
     5884{
     5885   int k, ii, j;
     5886   float mean, error;
     5887   CalibrationData *data = fCalibrationData[chipNumber];
     5888   CalibrationData::CalibrationDataChannel * chn;
     5889
     5890   /* switch DRS to input, hope that no real signal occurs */
     5891   if (fCurrentSample == 0) {
     5892      data->fHasOffsetCalibration = false;
     5893      fBoard->SetCalibVoltage(0.0);
     5894      fBoard->EnableAcal(0, 0.0);
     5895      /* one dummy trigger for unknown reasons */
     5896      fBoard->SoftTrigger();
     5897      while (fBoard->IsBusy());
     5898      fBoard->StartDomino();
     5899      Sleep(50);
     5900   }
     5901   // Loop Over Number Of Samples For Statistics
     5902   fBoard->SoftTrigger();
     5903   while (fBoard->IsBusy());
     5904   fBoard->TransferWaves();
     5905   for (ii = 0; ii < kNumberOfCalibChannelsV4; ii++)
     5906      fBoard->GetRawWave(chipNumber, ii, fWaveFormOffsetADC[ii][fCurrentSample]);
     5907
     5908   fBoard->StartDomino();
     5909   Sleep(50);
     5910   fCurrentSample++;
     5911
     5912   if (fBoard->Debug()) {
     5913      printf("%02d\r", fNumberOfSamples - fCurrentSample);
     5914      fflush(stdout);
     5915   }
     5916
     5917   if (fCurrentSample == fNumberOfSamples) {
     5918      // Average Sample Points
     5919      float *sample = new float[fNumberOfSamples];
     5920      for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5921         chn = data->fChannel[ii];
     5922         for (k = 0; k < kNumberOfBins; k++) {
     5923            for (j = 0; j < fNumberOfSamples; j++)
     5924               sample[j] = static_cast < float >(fWaveFormOffsetADC[ii][j][k]);
     5925            Average(1, sample, fNumberOfSamples, mean, error, 2);
     5926            chn->fOffset[k] = static_cast < unsigned short >(mean);
     5927         }
     5928      }
     5929      fOffset = true;
     5930      fCalibrationData[chipNumber]->fHasOffsetCalibration = true;
     5931      delete sample;
     5932      return true;
     5933   }
     5934
     5935   return false;
    31685936}
    31695937
     
    31755943                                     int showStatistics)
    31765944{
    3177   int ii, j, i;
    3178   fInitialized = true;
    3179   fNumberOfPointsLowVolt = numberOfPointsLowVolt;
    3180   fNumberOfPoints = numberOfPoints;
    3181   fNumberOfMode2Bins = numberOfMode2Bins;
    3182   fNumberOfSamples = numberOfSamples;
    3183   fNumberOfGridPoints = numberOfGridPoints;
    3184   fNumberOfXConstPoints = numberOfXConstPoints;
    3185   fNumberOfXConstGridPoints = numberOfXConstGridPoints;
    3186   fTriggerFrequency = triggerFrequency;
    3187   fShowStatistics = showStatistics;
    3188   fCurrentPoint = 0;
    3189   fCurrentSample = 0;
    3190   fCurrentFitChannel = 0;
    3191   fCurrentFitBin = 0;
    3192   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3193     for (j = 0; j < kNumberOfBins; j++) {
    3194       fResponseX[ii][j] = new float[fNumberOfPoints + fNumberOfPointsLowVolt];
    3195     }
    3196   }
    3197   fResponseY = new float[fNumberOfPoints + fNumberOfPointsLowVolt];
    3198   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3199     fWaveFormMode3[ii] = new unsigned short *[fNumberOfSamples];
    3200     fWaveFormMode2[ii] = new unsigned short *[fNumberOfSamples];
    3201     fWaveFormOffset[ii] = new short *[fNumberOfSamples];
    3202     fWaveFormOffsetADC[ii] = new unsigned short *[fNumberOfSamples];
    3203     for (i = 0; i < fNumberOfSamples; i++) {
    3204       fWaveFormMode3[ii][i] = new unsigned short[kNumberOfBins];
    3205       fWaveFormMode2[ii][i] = new unsigned short[kNumberOfBins];
    3206       fWaveFormOffset[ii][i] = new short[kNumberOfBins];
    3207       fWaveFormOffsetADC[ii][i] = new unsigned short[kNumberOfBins];
    3208     }
    3209   }
    3210   fSamples = new unsigned short[fNumberOfSamples];
    3211   fSampleUsed = new int[fNumberOfSamples];
    3212  
    3213   for (j = 0; j < kNumberOfBins; j++) {
    3214     fRes[j] = new float[fNumberOfGridPoints];
    3215     fResX[j] = new float[fNumberOfGridPoints];
    3216   }
    3217   for (i = 0; i < 2; i++) {
    3218     fPntX[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
    3219     fPntY[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
    3220     fUValues[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
    3221   }
    3222   fXXFit = new double[fNumberOfPoints];
    3223   fYYFit = new double[fNumberOfPoints];
    3224   fWWFit = new double[fNumberOfPoints];
    3225   fYYFitRes = new double[fNumberOfPoints];
    3226   fYYSave = new double[fNumberOfPoints];
    3227   fXXSave = new double[fNumberOfPoints];
    3228  
    3229   fStatisticsApprox = new float *[fNumberOfPoints];
    3230   fStatisticsApproxExt = new float *[fNumberOfPoints];
    3231   for (i = 0; i < fNumberOfPoints; i++) {
    3232     fStatisticsApprox[i] = new float[kNumberOfCalibChannels * kNumberOfBins];
    3233     fStatisticsApproxExt[i] = new float[kNumberOfCalibChannels * kNumberOfBins];
    3234   }
    3235   for (i = 0; i < kNumberOfChips; i++) {
    3236     fCalibrationData[i] = new CalibrationData(numberOfXConstGridPoints);
    3237   }
     5945   int ii, j, i;
     5946   fInitialized = true;
     5947   fNumberOfPointsLowVolt = numberOfPointsLowVolt;
     5948   fNumberOfPoints = numberOfPoints;
     5949   fNumberOfMode2Bins = numberOfMode2Bins;
     5950   fNumberOfSamples = numberOfSamples;
     5951   fNumberOfGridPoints = numberOfGridPoints;
     5952   fNumberOfXConstPoints = numberOfXConstPoints;
     5953   fNumberOfXConstGridPoints = numberOfXConstGridPoints;
     5954   fTriggerFrequency = triggerFrequency;
     5955   fShowStatistics = showStatistics;
     5956   fCurrentPoint = 0;
     5957   fCurrentSample = 0;
     5958   fCurrentFitChannel = 0;
     5959   fCurrentFitBin = 0;
     5960   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5961      for (j = 0; j < kNumberOfBins; j++) {
     5962         fResponseX[ii][j] = new float[fNumberOfPoints + fNumberOfPointsLowVolt];
     5963      }
     5964   }
     5965   fResponseY = new float[fNumberOfPoints + fNumberOfPointsLowVolt];
     5966   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     5967      fWaveFormMode3[ii] = new unsigned short *[fNumberOfSamples];
     5968      fWaveFormMode2[ii] = new unsigned short *[fNumberOfSamples];
     5969      fWaveFormOffset[ii] = new short *[fNumberOfSamples];
     5970      fWaveFormOffsetADC[ii] = new unsigned short *[fNumberOfSamples];
     5971      for (i = 0; i < fNumberOfSamples; i++) {
     5972         fWaveFormMode3[ii][i] = new unsigned short[kNumberOfBins];
     5973         fWaveFormMode2[ii][i] = new unsigned short[kNumberOfBins];
     5974         fWaveFormOffset[ii][i] = new short[kNumberOfBins];
     5975         fWaveFormOffsetADC[ii][i] = new unsigned short[kNumberOfBins];
     5976      }
     5977   }
     5978   fSamples = new unsigned short[fNumberOfSamples];
     5979   fSampleUsed = new int[fNumberOfSamples];
     5980
     5981   for (j = 0; j < kNumberOfBins; j++) {
     5982      fRes[j] = new float[fNumberOfGridPoints];
     5983      fResX[j] = new float[fNumberOfGridPoints];
     5984   }
     5985   for (i = 0; i < 2; i++) {
     5986      fPntX[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
     5987      fPntY[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
     5988      fUValues[i] = new float[fNumberOfPoints * (1 - i) + fNumberOfXConstPoints * i];
     5989   }
     5990   fXXFit = new double[fNumberOfPoints];
     5991   fYYFit = new double[fNumberOfPoints];
     5992   fWWFit = new double[fNumberOfPoints];
     5993   fYYFitRes = new double[fNumberOfPoints];
     5994   fYYSave = new double[fNumberOfPoints];
     5995   fXXSave = new double[fNumberOfPoints];
     5996
     5997   fStatisticsApprox = new float *[fNumberOfPoints];
     5998   fStatisticsApproxExt = new float *[fNumberOfPoints];
     5999   for (i = 0; i < fNumberOfPoints; i++) {
     6000      fStatisticsApprox[i] = new float[kNumberOfCalibChannelsV3 * kNumberOfBins];
     6001      fStatisticsApproxExt[i] = new float[kNumberOfCalibChannelsV3 * kNumberOfBins];
     6002   }
     6003   for (i = 0; i < kNumberOfChipsMax; i++) {
     6004      fCalibrationData[i] = new CalibrationData(numberOfXConstGridPoints);
     6005   }
    32386006}
    32396007
     
    32426010void ResponseCalibration::DeleteFields()
    32436011{
    3244   if (!fInitialized)
    3245     return;
    3246   fInitialized = false;
    3247   int ii, j, i;
    3248   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3249     for (j = 0; j < kNumberOfBins; j++) {
    3250       delete fResponseX[ii][j];
    3251     }
    3252   }
    3253   delete fResponseY;
    3254   for (ii = 0; ii < kNumberOfCalibChannels; ii++) {
    3255     for (i = 0; i < fNumberOfSamples; i++) {
    3256       if (fWaveFormMode3[ii] != NULL)
    3257         delete fWaveFormMode3[ii][i];
    3258       if (fWaveFormMode2[ii] != NULL)
    3259         delete fWaveFormMode2[ii][i];
    3260       if (fWaveFormOffset[ii] != NULL)
    3261         delete fWaveFormOffset[ii][i];
    3262       if (fWaveFormOffsetADC[ii] != NULL)
    3263         delete fWaveFormOffsetADC[ii][i];
    3264     }
    3265     delete fWaveFormMode3[ii];
    3266     delete fWaveFormMode2[ii];
    3267     delete fWaveFormOffset[ii];
    3268     delete fWaveFormOffsetADC[ii];
    3269   }
    3270   delete fSamples;
    3271   delete fSampleUsed;
    3272  
    3273   for (j = 0; j < kNumberOfBins; j++) {
    3274     delete fRes[j];
    3275     delete fResX[j];
    3276   }
    3277   for (i = 0; i < 2; i++) {
    3278     delete fPntX[i];
    3279     delete fPntY[i];
    3280     delete fUValues[i];
    3281   }
    3282   delete fXXFit;
    3283   delete fYYFit;
    3284   delete fWWFit;
    3285   delete fYYFitRes;
    3286   delete fYYSave;
    3287   delete fXXSave;
    3288  
    3289   for (i = 0; i < fNumberOfPoints; i++) {
    3290     delete fStatisticsApprox[i];
    3291     delete fStatisticsApproxExt[i];
    3292   }
    3293   delete fStatisticsApprox;
    3294   delete fStatisticsApproxExt;
    3295   for (i = 0; i < kNumberOfChips; i++)
    3296     delete fCalibrationData[i];
     6012   if (!fInitialized)
     6013      return;
     6014   fInitialized = false;
     6015   int ii, j, i;
     6016   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     6017      for (j = 0; j < kNumberOfBins; j++) {
     6018         delete fResponseX[ii][j];
     6019      }
     6020   }
     6021   delete fResponseY;
     6022   for (ii = 0; ii < kNumberOfCalibChannelsV3; ii++) {
     6023      for (i = 0; i < fNumberOfSamples; i++) {
     6024         if (fWaveFormMode3[ii] != NULL)
     6025            delete fWaveFormMode3[ii][i];
     6026         if (fWaveFormMode2[ii] != NULL)
     6027            delete fWaveFormMode2[ii][i];
     6028         if (fWaveFormOffset[ii] != NULL)
     6029            delete fWaveFormOffset[ii][i];
     6030         if (fWaveFormOffsetADC[ii] != NULL)
     6031            delete fWaveFormOffsetADC[ii][i];
     6032      }
     6033      delete fWaveFormMode3[ii];
     6034      delete fWaveFormMode2[ii];
     6035      delete fWaveFormOffset[ii];
     6036      delete fWaveFormOffsetADC[ii];
     6037   }
     6038   delete fSamples;
     6039   delete fSampleUsed;
     6040
     6041   for (j = 0; j < kNumberOfBins; j++) {
     6042      delete fRes[j];
     6043      delete fResX[j];
     6044   }
     6045   for (i = 0; i < 2; i++) {
     6046      delete fPntX[i];
     6047      delete fPntY[i];
     6048      delete fUValues[i];
     6049   }
     6050   delete fXXFit;
     6051   delete fYYFit;
     6052   delete fWWFit;
     6053   delete fYYFitRes;
     6054   delete fYYSave;
     6055   delete fXXSave;
     6056
     6057   for (i = 0; i < fNumberOfPoints; i++) {
     6058      delete fStatisticsApprox[i];
     6059      delete fStatisticsApproxExt[i];
     6060   }
     6061   delete fStatisticsApprox;
     6062   delete fStatisticsApproxExt;
     6063   for (i = 0; i < kNumberOfChipsMax; i++)
     6064      delete fCalibrationData[i];
    32976065}
    32986066
     
    33016069double ResponseCalibration::GetTemperature(unsigned int chipIndex)
    33026070{
    3303   if (fCalibrationData[chipIndex]==NULL)
    3304     return 0;
    3305   if (!fCalibrationData[chipIndex]->fRead)
    3306     return 0;
    3307   return (fCalibrationData[chipIndex]->fStartTemperature + fCalibrationData[chipIndex]->fEndTemperature) / 2;
     6071   if (fCalibrationData[chipIndex] == NULL)
     6072      return 0;
     6073   if (!fCalibrationData[chipIndex]->fRead)
     6074      return 0;
     6075   return (fCalibrationData[chipIndex]->fStartTemperature + fCalibrationData[chipIndex]->fEndTemperature) / 2;
    33086076}
    33096077
     
    33116079
    33126080bool ResponseCalibration::Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform,
    3313                                     short *uWaveform, int triggerCell, float threshold)
    3314 {
    3315   int i;
    3316   int hasOffset;
    3317   bool aboveThreshold;
    3318   float wave, v;
    3319   int j,irot;
    3320  
    3321   CalibrationData *data = fCalibrationData[chipIndex];
    3322   CalibrationData::CalibrationDataChannel * chn;
    3323  
    3324   if (channel > kNumberOfCalibChannels || data == NULL) {
    3325     for (i = 0; i < kNumberOfBins; i++) {
    3326       uWaveform[i] = adcWaveform[i];
    3327     }
    3328     return true;
    3329   }
    3330   if (!data->fRead) {
    3331     for (i = 0; i < kNumberOfBins; i++) {
    3332       uWaveform[i] = adcWaveform[i];
    3333     }
    3334     return true;
    3335   }
    3336  
    3337   chn = data->fChannel[channel];
    3338  
    3339   hasOffset = data->fHasOffsetCalibration;
    3340   aboveThreshold = (threshold == 0);   // If threshold equal zero, always return true
    3341  
    3342   // Calibrate
    3343   for (i = 0; i < kNumberOfBins; i++) {
    3344     if (fBoard->GetChipVersion() != 3) {
    3345       irot = i;
    3346       if (triggerCell > -1)
    3347         irot = (triggerCell + i) % kNumberOfBins;
    3348       if (adcWaveform[irot] > chn->fLookUpOffset[irot]) {
    3349         uWaveform[i] =
    3350           ((chn->fLookUp[irot][0] - chn->fLookUp[irot][1]) * (adcWaveform[irot] - chn->fLookUpOffset[irot]) +
    3351            chn->fLookUp[irot][0]);
    3352       } else if (adcWaveform[irot] <= chn->fLookUpOffset[irot]
    3353                  && adcWaveform[irot] > chn->fLookUpOffset[irot] - chn->fNumberOfLookUpPoints[irot]) {
    3354         uWaveform[i] = chn->fLookUp[irot][chn->fLookUpOffset[irot] - adcWaveform[irot]];
     6081                                    short *uWaveform, int triggerCell, float threshold, bool offsetCalib)
     6082{
     6083   int i;
     6084   unsigned int NumberOfCalibChannels;
     6085   int hasOffset;
     6086   bool aboveThreshold;
     6087   float wave, v;
     6088   int j, irot;
     6089
     6090   CalibrationData *data = fCalibrationData[chipIndex];
     6091   CalibrationData::CalibrationDataChannel * chn;
     6092
     6093   if (fBoard->GetDRSType() == 3)
     6094      NumberOfCalibChannels = kNumberOfCalibChannelsV4;
     6095   else
     6096      NumberOfCalibChannels = kNumberOfCalibChannelsV3;
     6097
     6098   if (channel >= NumberOfCalibChannels || data == NULL) {
     6099      for (i = 0; i < kNumberOfBins; i++) {
     6100         irot = i;
     6101         if (triggerCell > -1)
     6102            irot = (triggerCell + i) % kNumberOfBins;
     6103
     6104         uWaveform[i] = adcWaveform[irot];
     6105      }
     6106      return true;
     6107   }
     6108   if (!data->fRead) {
     6109      for (i = 0; i < kNumberOfBins; i++) {
     6110         uWaveform[i] = adcWaveform[i];
     6111      }
     6112      return true;
     6113   }
     6114
     6115   chn = data->fChannel[channel];
     6116
     6117   hasOffset = data->fHasOffsetCalibration;
     6118   aboveThreshold = (threshold == 0);   // if threshold equal zero, always return true
     6119
     6120   short offset;
     6121
     6122   // Calibrate
     6123   for (i = 0; i < kNumberOfBins; i++) {
     6124      if (fBoard->GetDRSType() != 3) {
     6125         irot = i;
     6126         if (triggerCell > -1)
     6127            irot = (triggerCell + i) % kNumberOfBins;
     6128         offset = offsetCalib ? chn->fOffset[irot] : 0;
     6129         if (adcWaveform[irot] > chn->fLookUpOffset[irot]) {
     6130            uWaveform[i] =
     6131                ((chn->fLookUp[irot][0] - chn->fLookUp[irot][1]) * (adcWaveform[irot] -
     6132                                                                    chn->fLookUpOffset[irot]) +
     6133                 chn->fLookUp[irot][0]);
     6134         } else if (adcWaveform[irot] <= chn->fLookUpOffset[irot]
     6135                    && adcWaveform[irot] > chn->fLookUpOffset[irot] - chn->fNumberOfLookUpPoints[irot]) {
     6136            uWaveform[i] = chn->fLookUp[irot][chn->fLookUpOffset[irot] - adcWaveform[irot]];
     6137         } else {
     6138            wave = 0;
     6139            for (j = 0; j < kBSplineOrder; j++) {
     6140               wave +=
     6141                   chn->fData[irot][data->fBSplineOffsetLookUp[adcWaveform[irot]][chn->fLimitGroup[irot]] + j]
     6142                   * data->fBSplineLookUp[adcWaveform[irot]][chn->fLimitGroup[irot]][j];
     6143            }
     6144            uWaveform[i] = static_cast < short >(wave);
     6145         }
     6146         // Offset Calibration
     6147         if (hasOffset)
     6148            uWaveform[i] -= offset;
    33556149      } else {
    3356         wave = 0;
    3357         for (j = 0; j < kBSplineOrder; j++) {
    3358           wave += chn->fData[irot][data->fBSplineOffsetLookUp[adcWaveform[irot]][chn->fLimitGroup[irot]] + j]
    3359             * data->fBSplineLookUp[adcWaveform[irot]][chn->fLimitGroup[irot]][j];
    3360         }
    3361         uWaveform[i] = static_cast<short>(wave);
    3362       }
    3363       // Offset Calibration
    3364       if (hasOffset)
    3365         uWaveform[i] -= chn->fOffset[irot];
    3366     } else {
    3367       if (chn->fGain[i] > 3800) {
    3368         //if (channel == 1 && i == 10)
    3369         //   printf("gain:%d offset:%d value:%d\n", chn->fGain[i], chn->fOffset[i], adcWaveform[i]);
    3370         v = static_cast<float>(adcWaveform[i] - chn->fOffset[i]) / chn->fGain[i];
    3371         uWaveform[i] = static_cast<short>(v * 1000 / GetPrecision() + 0.5);
    3372       } else
    3373         uWaveform[i] = 0;
    3374     }
    3375    
    3376     // Check for Threshold
    3377     if (!aboveThreshold) {
    3378       if (uWaveform[i] >= threshold)
    3379         aboveThreshold = true;
    3380     }
    3381   }
    3382   return aboveThreshold;
    3383 }
    3384 
    3385 /*------------------------------------------------------------------*/
    3386 
    3387 bool ResponseCalibration::SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform,
    3388                                             unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel)
    3389 {
    3390   int i;
    3391   CalibrationData *data = fCalibrationData[chipIndex];
    3392   CalibrationData::CalibrationDataChannel * chn;
    3393  
    3394   if (channel >= kNumberOfCalibChannels || data == NULL)
    3395     return false;
    3396   if (!data->fRead || !data->fHasOffsetCalibration)
    3397     return false;
    3398  
    3399   chn = data->fChannel[channel];
    3400   for (i = 0; i < kNumberOfBins; i++)
    3401     adcCalibratedWaveform[i] = adcWaveform[i]-chn->fOffsetADC[i]+newBaseLevel;
    3402   return true;
     6150         irot = i;
     6151         if (triggerCell > -1)
     6152            irot = (triggerCell + i) % kNumberOfBins;
     6153#if 0                           /* not enabled yet for DRS3 */
     6154         offset = offsetCalib ? chn->fOffset[irot] : 0;
     6155#else
     6156         offset = chn->fOffset[irot];
     6157#endif
     6158         v = static_cast < float >(adcWaveform[irot] - offset) / chn->fGain[irot];
     6159         uWaveform[i] = static_cast < short >(v * 1000 / GetPrecision() + 0.5);
     6160      }
     6161
     6162      // Check for Threshold
     6163      if (!aboveThreshold) {
     6164         if (uWaveform[i] >= threshold)
     6165            aboveThreshold = true;
     6166      }
     6167   }
     6168   return aboveThreshold;
     6169}
     6170
     6171/*------------------------------------------------------------------*/
     6172
     6173bool ResponseCalibration::SubtractADCOffset(unsigned int chipIndex, unsigned int channel,
     6174                                            unsigned short *adcWaveform,
     6175                                            unsigned short *adcCalibratedWaveform,
     6176                                            unsigned short newBaseLevel)
     6177{
     6178   int i;
     6179   unsigned int NumberOfCalibChannels;
     6180   CalibrationData *data = fCalibrationData[chipIndex];
     6181   CalibrationData::CalibrationDataChannel * chn;
     6182
     6183   if (fBoard->GetDRSType() == 3)
     6184      NumberOfCalibChannels = kNumberOfCalibChannelsV4;
     6185   else
     6186      NumberOfCalibChannels = kNumberOfCalibChannelsV3;
     6187
     6188   if (channel >= NumberOfCalibChannels || data == NULL)
     6189      return false;
     6190   if (!data->fRead || !data->fHasOffsetCalibration)
     6191      return false;
     6192
     6193   chn = data->fChannel[channel];
     6194   for (i = 0; i < kNumberOfBins; i++)
     6195      adcCalibratedWaveform[i] = adcWaveform[i] - chn->fOffsetADC[i] + newBaseLevel;
     6196   return true;
    34036197}
    34046198
     
    34086202bool ResponseCalibration::ReadCalibration(unsigned int chipIndex)
    34096203{
    3410   if (fBoard->GetChipVersion() == 3)
    3411     return ReadCalibrationV4(chipIndex);
    3412   else
    3413     return ReadCalibrationV3(chipIndex);
     6204  if (fBoard->GetDRSType() == 3) return ReadCalibrationV4(chipIndex);
     6205  else return ReadCalibrationV3(chipIndex);
    34146206}
    34156207
     
    34186210bool ResponseCalibration::ReadCalibrationV3(unsigned int chipIndex)
    34196211{
    3420   int k, l, m, num;
    3421   unsigned char ng;
    3422   short tempShort;
    3423   char fileName[2000];
    3424   FILE *fileHandle;
    3425   char calibDir[1000];
    3426  
    3427   // Read Response Calibration
    3428   delete fCalibrationData[chipIndex];
    3429   fCalibrationData[chipIndex] = NULL;
    3430  
    3431   fBoard->GetCalibrationDirectory(calibDir);
    3432   sprintf(fileName, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", calibDir,
    3433           fBoard->GetCMCSerialNumber(), fBoard->GetCMCSerialNumber(), chipIndex,
    3434           static_cast<int>(fBoard->GetFrequency() * 1000));
    3435  
    3436   fileHandle = fopen(fileName, "rb");
    3437   if (fileHandle == NULL) {
    3438     printf("Board %d --> Could not find response calibration file:\n", fBoard->GetCMCSerialNumber());
    3439     printf("%s\n", fileName);
    3440     return false;
    3441   }
    3442   // Number Of Grid Points
    3443   num = fread(&ng, 1, 1, fileHandle);
    3444   if (num != 1) {
    3445     printf("Error while reading response calibration file '%s'\n", fileName);
    3446     printf("   at 'NumberOfGridPoints'.\n");
    3447     return false;
    3448   }
    3449  
    3450   fCalibrationData[chipIndex] = new CalibrationData(ng);
    3451   CalibrationData *data = fCalibrationData[chipIndex];
    3452   CalibrationData::CalibrationDataChannel * chn;
    3453   data->fRead = true;
    3454   data->fHasOffsetCalibration = 1;
    3455   data->DeletePreCalculatedBSpline();
    3456   fCalibrationValid[chipIndex] = true;
    3457  
    3458   // Start Temperature
    3459   num = fread(&tempShort, 2, 1, fileHandle);
    3460   if (num != 1) {
    3461     printf("Error while reading response calibration file '%s'\n", fileName);
    3462     printf("   at 'StartTemperature'.\n");
    3463     return false;
    3464   }
    3465   data->fStartTemperature = static_cast<float>(tempShort) / 10;
    3466   // End Temperature
    3467   num = fread(&tempShort, 2, 1, fileHandle);
    3468   if (num != 1) {
    3469     printf("Error while reading response calibration file '%s'\n", fileName);
    3470     printf("   at 'EndTemperature'.\n");
    3471     return false;
    3472   }
    3473   data->fEndTemperature = static_cast<float>(tempShort) / 10;
    3474   if (fBoard->GetChipVersion() != 3) {
    3475     // Min
    3476     num = fread(&data->fMin, 4, 1, fileHandle);
    3477     if (num != 1) {
     6212   int k, l, m, num;
     6213   unsigned char ng;
     6214   short tempShort;
     6215   char fileName[2000];
     6216   FILE *fileHandle;
     6217   char calibDir[1000];
     6218
     6219   // Read Response Calibration
     6220   delete fCalibrationData[chipIndex];
     6221   fCalibrationData[chipIndex] = NULL;
     6222
     6223   fBoard->GetCalibrationDirectory(calibDir);
     6224   sprintf(fileName, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", calibDir,
     6225           fBoard->GetBoardSerialNumber(), fBoard->GetBoardSerialNumber(), chipIndex,
     6226           static_cast < int >(fBoard->GetFrequency() * 1000));
     6227
     6228   fileHandle = fopen(fileName, "rb");
     6229   if (fileHandle == NULL) {
     6230      printf("Board %d --> Could not find response calibration file:\n", fBoard->GetBoardSerialNumber());
     6231      printf("%s\n", fileName);
     6232      return false;
     6233   }
     6234   // Number Of Grid Points
     6235   num = fread(&ng, 1, 1, fileHandle);
     6236   if (num != 1) {
    34786237      printf("Error while reading response calibration file '%s'\n", fileName);
    3479       printf("   at 'Min'.\n");
     6238      printf("   at 'NumberOfGridPoints'.\n");
    34806239      return false;
    3481     }
    3482     // Max
    3483     num = fread(&data->fMax, 4, 1, fileHandle);
    3484     if (num != 1) {
     6240   }
     6241
     6242   fCalibrationData[chipIndex] = new CalibrationData(ng);
     6243   CalibrationData *data = fCalibrationData[chipIndex];
     6244   CalibrationData::CalibrationDataChannel * chn;
     6245   data->fRead = true;
     6246   data->fHasOffsetCalibration = 1;
     6247   data->DeletePreCalculatedBSpline();
     6248   fCalibrationValid[chipIndex] = true;
     6249
     6250   // Start Temperature
     6251   num = fread(&tempShort, 2, 1, fileHandle);
     6252   if (num != 1) {
    34856253      printf("Error while reading response calibration file '%s'\n", fileName);
    3486       printf("   at 'Max'.\n");
     6254      printf("   at 'StartTemperature'.\n");
    34876255      return false;
    3488     }
    3489     // Number Of Limit Groups
    3490     num = fread(&data->fNumberOfLimitGroups, 1, 1, fileHandle);
    3491     if (num != 1) {
     6256   }
     6257   data->fStartTemperature = static_cast < float >(tempShort) / 10;
     6258   // End Temperature
     6259   num = fread(&tempShort, 2, 1, fileHandle);
     6260   if (num != 1) {
    34926261      printf("Error while reading response calibration file '%s'\n", fileName);
    3493       printf("   at 'NumberOfLimitGroups'.\n");
     6262      printf("   at 'EndTemperature'.\n");
    34946263      return false;
    3495     }
    3496   }
    3497   // Read channel
    3498   for (k = 0; k < kNumberOfCalibChannels; k++) {
    3499     chn = data->fChannel[k];
    3500     for (l = 0; l < kNumberOfBins; l++) {
    3501       if (fBoard->GetChipVersion() != 3) {
    3502         // Range Group
    3503         num = fread(&chn->fLimitGroup[l], 1, 1, fileHandle);
    3504         if (num != 1) {
    3505           printf("Error while reading response calibration file '%s'\n", fileName);
    3506           printf("   at 'RangeGroup' of channel %d bin %d.\n", k, l);
    3507           return false;
    3508         }
    3509         // Look Up Offset
    3510         num = fread(&chn->fLookUpOffset[l], 2, 1, fileHandle);
    3511         if (num != 1) {
    3512           printf("Error while reading response calibration file '%s'\n", fileName);
    3513           printf("   at 'LookUpOffset' of channel %d bin %d.\n", k, l);
    3514           return false;
    3515         }
    3516         // Number Of Look Up Points
    3517         num = fread(&chn->fNumberOfLookUpPoints[l], 1, 1, fileHandle);
    3518         if (num != 1) {
    3519           printf("Error while reading response calibration file '%s'\n", fileName);
    3520           printf("   at 'NumberOfLookUpPoints' of channel %d bin %d.\n", k, l);
    3521           return false;
    3522         }
    3523         // Look Up Points
    3524         delete chn->fLookUp[l];
    3525         chn->fLookUp[l] = new unsigned char[chn->fNumberOfLookUpPoints[l]];
    3526         for (m = 0; m < chn->fNumberOfLookUpPoints[l]; m++) {
    3527           num = fread(&chn->fLookUp[l][m], 1, 1, fileHandle);
    3528           if (num != 1) {
    3529             printf("Error while reading response calibration file '%s'\n", fileName);
    3530             printf("   at 'LookUp %d' of channel %d bin %d.\n", m, k, l);
    3531             return false;
    3532           }
    3533         }
    3534         // Points
    3535         for (m = 0; m < data->fNumberOfGridPoints; m++) {
    3536           num = fread(&chn->fData[l][m], 2, 1, fileHandle);
    3537           if (num != 1) {
    3538             printf("Error while reading response calibration file '%s'\n", fileName);
    3539             printf("   at 'Point %d' of channel %d bin %d.\n", m, k, l);
    3540             return false;
    3541           }
    3542         }
    3543         // ADC Offset
    3544         num = fread(&chn->fOffsetADC[l], 2, 1, fileHandle);
    3545         if (num != 1) {
    3546           printf("Error while reading response calibration file '%s'\n", fileName);
    3547           printf("   at 'ADC Offset' of channel %d bin %d.\n", k, l);
    3548           return false;
    3549         }
    3550       }
    3551       // Offset
    3552       num = fread(&chn->fOffset[l], 2, 1, fileHandle);
     6264   }
     6265   data->fEndTemperature = static_cast < float >(tempShort) / 10;
     6266   if (fBoard->GetDRSType() != 3) {
     6267      // Min
     6268      num = fread(&data->fMin, 4, 1, fileHandle);
    35536269      if (num != 1) {
    3554         printf("Error while reading response calibration file '%s'\n", fileName);
    3555         printf("   at 'Offset' of channel %d bin %d.\n", k, l);
    3556         return false;
    3557       }
    3558       if (fBoard->GetChipVersion() == 3) {
    3559         // Gain
    3560         num = fread(&chn->fGain[l], 2, 1, fileHandle);
    3561         if (num != 1) {
    3562           printf("Error while reading response calibration file '%s'\n", fileName);
    3563           printf("   at 'Gain' of channel %d bin %d.\n", k, l);
    3564           return false;
    3565         }
    3566       }
    3567     }
    3568   }
    3569   fclose(fileHandle);
    3570  
    3571   if (fBoard->GetChipVersion() != 3) {
    3572     data->PreCalculateBSpline();
    3573   }
    3574  
    3575   return true;
     6270         printf("Error while reading response calibration file '%s'\n", fileName);
     6271         printf("   at 'Min'.\n");
     6272         return false;
     6273      }
     6274      // Max
     6275      num = fread(&data->fMax, 4, 1, fileHandle);
     6276      if (num != 1) {
     6277         printf("Error while reading response calibration file '%s'\n", fileName);
     6278         printf("   at 'Max'.\n");
     6279         return false;
     6280      }
     6281      // Number Of Limit Groups
     6282      num = fread(&data->fNumberOfLimitGroups, 1, 1, fileHandle);
     6283      if (num != 1) {
     6284         printf("Error while reading response calibration file '%s'\n", fileName);
     6285         printf("   at 'NumberOfLimitGroups'.\n");
     6286         return false;
     6287      }
     6288   }
     6289   // read channel
     6290   for (k = 0; k < kNumberOfCalibChannelsV3; k++) {
     6291      chn = data->fChannel[k];
     6292      for (l = 0; l < kNumberOfBins; l++) {
     6293         if (fBoard->GetDRSType() != 3) {
     6294            // Range Group
     6295            num = fread(&chn->fLimitGroup[l], 1, 1, fileHandle);
     6296            if (num != 1) {
     6297               printf("Error while reading response calibration file '%s'\n", fileName);
     6298               printf("   at 'RangeGroup' of channel %d bin %d.\n", k, l);
     6299               return false;
     6300            }
     6301            // Look Up Offset
     6302            num = fread(&chn->fLookUpOffset[l], 2, 1, fileHandle);
     6303            if (num != 1) {
     6304               printf("Error while reading response calibration file '%s'\n", fileName);
     6305               printf("   at 'LookUpOffset' of channel %d bin %d.\n", k, l);
     6306               return false;
     6307            }
     6308            // Number Of Look Up Points
     6309            num = fread(&chn->fNumberOfLookUpPoints[l], 1, 1, fileHandle);
     6310            if (num != 1) {
     6311               printf("Error while reading response calibration file '%s'\n", fileName);
     6312               printf("   at 'NumberOfLookUpPoints' of channel %d bin %d.\n", k, l);
     6313               return false;
     6314            }
     6315            // Look Up Points
     6316            delete chn->fLookUp[l];
     6317            chn->fLookUp[l] = new unsigned char[chn->fNumberOfLookUpPoints[l]];
     6318            for (m = 0; m < chn->fNumberOfLookUpPoints[l]; m++) {
     6319               num = fread(&chn->fLookUp[l][m], 1, 1, fileHandle);
     6320               if (num != 1) {
     6321                  printf("Error while reading response calibration file '%s'\n", fileName);
     6322                  printf("   at 'LookUp %d' of channel %d bin %d.\n", m, k, l);
     6323                  return false;
     6324               }
     6325            }
     6326            // Points
     6327            for (m = 0; m < data->fNumberOfGridPoints; m++) {
     6328               num = fread(&chn->fData[l][m], 2, 1, fileHandle);
     6329               if (num != 1) {
     6330                  printf("Error while reading response calibration file '%s'\n", fileName);
     6331                  printf("   at 'Point %d' of channel %d bin %d.\n", m, k, l);
     6332                  return false;
     6333               }
     6334            }
     6335            // ADC Offset
     6336            num = fread(&chn->fOffsetADC[l], 2, 1, fileHandle);
     6337            if (num != 1) {
     6338               printf("Error while reading response calibration file '%s'\n", fileName);
     6339               printf("   at 'ADC Offset' of channel %d bin %d.\n", k, l);
     6340               return false;
     6341            }
     6342         }
     6343         // Offset
     6344         num = fread(&chn->fOffset[l], 2, 1, fileHandle);
     6345         if (num != 1) {
     6346            printf("Error while reading response calibration file '%s'\n", fileName);
     6347            printf("   at 'Offset' of channel %d bin %d.\n", k, l);
     6348            return false;
     6349         }
     6350         if (fBoard->GetDRSType() == 3) {
     6351            // Gain
     6352            num = fread(&chn->fGain[l], 2, 1, fileHandle);
     6353            if (num != 1) {
     6354               printf("Error while reading response calibration file '%s'\n", fileName);
     6355               printf("   at 'Gain' of channel %d bin %d.\n", k, l);
     6356               return false;
     6357            }
     6358         }
     6359      }
     6360   }
     6361   fclose(fileHandle);
     6362
     6363   if (fBoard->GetDRSType() != 3) {
     6364      data->PreCalculateBSpline();
     6365   }
     6366
     6367   return true;
    35766368}
    35776369
     
    35806372bool ResponseCalibration::ReadCalibrationV4(unsigned int chipIndex)
    35816373{
    3582   int k, l, num;
    3583   char fileName[2000];
    3584   FILE *fileHandle;
    3585   char calibDir[1000];
    3586  
    3587   // Read Response Calibration
    3588  
    3589   fBoard->GetCalibrationDirectory(calibDir);
    3590   sprintf(fileName, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", calibDir,
    3591           fBoard->GetCMCSerialNumber(), fBoard->GetCMCSerialNumber(), chipIndex,
    3592           static_cast<int>(fBoard->GetFrequency() * 1000));
    3593  
    3594   fileHandle = fopen(fileName, "rb");
    3595   if (fileHandle == NULL) {
    3596     printf("Board %d --> Could not find response calibration file:\n", fBoard->GetCMCSerialNumber());
    3597     printf("%s\n", fileName);
    3598     return false;
    3599   }
    3600  
    3601   if (fInitialized)
    3602     delete fCalibrationData[chipIndex];
    3603   fCalibrationData[chipIndex] = new CalibrationData(1);
    3604   CalibrationData *data = fCalibrationData[chipIndex];
    3605   CalibrationData::CalibrationDataChannel * chn;
    3606   data->fRead = true;
    3607   data->fHasOffsetCalibration = 1;
    3608   fCalibrationValid[chipIndex] = true;
    3609   data->fStartTemperature = 0;
    3610   data->fEndTemperature = 0;
    3611  
    3612   // read channel
    3613   for (k = 0; k < kNumberOfCalibChannels; k++) {
    3614     chn = data->fChannel[k];
    3615     for (l = 0; l < kNumberOfBins; l++) {
    3616       // Offset
    3617       num = fread(&chn->fOffset[l], 2, 1, fileHandle);
    3618       if (num != 1) {
    3619         printf("Error while reading response calibration file '%s'\n", fileName);
    3620         printf("   at 'Offset' of channel %d bin %d.\n", k, l);
    3621         return false;
    3622       }
    3623       if (fBoard->GetChipVersion() == 3) {
    3624         // Gain
    3625         num = fread(&chn->fGain[l], 2, 1, fileHandle);
    3626         if (num != 1) {
    3627           printf("Error while reading response calibration file '%s'\n", fileName);
    3628           printf("   at 'Gain' of channel %d bin %d.\n", k, l);
    3629           return false;
    3630         }
    3631       }
    3632     }
    3633   }
    3634  
    3635   fclose(fileHandle);
    3636   return true;
     6374   int k, l, num;
     6375   char fileName[2000];
     6376   FILE *fileHandle;
     6377   char calibDir[1000];
     6378
     6379   // Read Response Calibration
     6380
     6381   fBoard->GetCalibrationDirectory(calibDir);
     6382   sprintf(fileName, "%s/board%d/ResponseCalib_board%d_chip%d_%dMHz.bin", calibDir,
     6383           fBoard->GetBoardSerialNumber(), fBoard->GetBoardSerialNumber(), chipIndex,
     6384           static_cast < int >(fBoard->GetFrequency() * 1000));
     6385
     6386   fileHandle = fopen(fileName, "rb");
     6387   if (fileHandle == NULL) {
     6388      printf("Board %d --> Could not find response calibration file:\n", fBoard->GetBoardSerialNumber());
     6389      printf("%s\n", fileName);
     6390      return false;
     6391   }
     6392
     6393   if (fInitialized)
     6394      delete fCalibrationData[chipIndex];
     6395   fCalibrationData[chipIndex] = new CalibrationData(1);
     6396   CalibrationData *data = fCalibrationData[chipIndex];
     6397   CalibrationData::CalibrationDataChannel * chn;
     6398   data->fRead = true;
     6399   data->fHasOffsetCalibration = 1;
     6400   fCalibrationValid[chipIndex] = true;
     6401   data->fStartTemperature = 0;
     6402   data->fEndTemperature = 0;
     6403
     6404   // read channel
     6405   for (k = 0; k < kNumberOfCalibChannelsV4; k++) {
     6406      chn = data->fChannel[k];
     6407      for (l = 0; l < kNumberOfBins; l++) {
     6408         // Offset
     6409         num = fread(&chn->fOffset[l], 2, 1, fileHandle);
     6410         if (num != 1) {
     6411            printf("Error while reading response calibration file '%s'\n", fileName);
     6412            printf("   at 'Offset' of channel %d bin %d.\n", k, l);
     6413            return false;
     6414         }
     6415         if (fBoard->GetDRSType() == 3) {
     6416            // Gain
     6417            num = fread(&chn->fGain[l], 2, 1, fileHandle);
     6418            if (num != 1) {
     6419               printf("Error while reading response calibration file '%s'\n", fileName);
     6420               printf("   at 'Gain' of channel %d bin %d.\n", k, l);
     6421               return false;
     6422            }
     6423         }
     6424      }
     6425   }
     6426
     6427   fclose(fileHandle);
     6428   return true;
    36376429}
    36386430
     
    36416433float ResponseCalibration::GetValue(float *coefficients, float u, int n)
    36426434{
    3643   int j, ii;
    3644   float bsplines[4];
    3645   ii = CalibrationData::CalculateBSpline(n, u, bsplines);
    3646  
    3647   float s = 0;
    3648   for (j = 0; j < kBSplineOrder; j++) {
    3649     s += coefficients[ii + j] * bsplines[j];
    3650   }
    3651   return s;
     6435   int j, ii;
     6436   float bsplines[4];
     6437   ii = CalibrationData::CalculateBSpline(n, u, bsplines);
     6438
     6439   float s = 0;
     6440   for (j = 0; j < kBSplineOrder; j++) {
     6441      s += coefficients[ii + j] * bsplines[j];
     6442   }
     6443   return s;
    36526444}
    36536445
     
    36566448int ResponseCalibration::Approx(float *p, float *uu, int np, int nu, float *coef)
    36576449{
    3658   int i, iu, j;
    3659  
    3660   const int mbloc = 50;
    3661   int ip = 0;
    3662   int ir = 0;
    3663   int mt = 0;
    3664   int ileft, irow;
    3665   float bu[kBSplineOrder];
    3666   float *matrix[kBSplineOrder + 2];
    3667   for (i = 0; i < kBSplineOrder + 2; i++)
    3668     matrix[i] = new float[mbloc + nu + 1];
    3669   for (iu = kBSplineOrder - 1; iu < nu; iu++) {
    3670     for (i = 0; i < np; i++) {
    3671       if (1 <= uu[i])
    3672         ileft = nu - 1;
    3673       else if (uu[i] < 0)
    3674         ileft = kBSplineOrder - 2;
    3675       else
    3676         ileft = kBSplineOrder - 1 + static_cast<int>(uu[i] * (nu - kBSplineOrder + 1));
    3677       if (ileft != iu)
    3678         continue;
    3679       irow = ir + mt;
    3680       mt++;
    3681       CalibrationData::CalculateBSpline(nu, uu[i], bu);
    3682       for (j = 0; j < kBSplineOrder; j++) {
    3683         matrix[j][irow] = bu[j];
    3684       }
    3685       matrix[kBSplineOrder][irow] = p[i];
    3686       if (mt < mbloc)
    3687         continue;
     6450   int i, iu, j;
     6451
     6452   const int mbloc = 50;
     6453   int ip = 0;
     6454   int ir = 0;
     6455   int mt = 0;
     6456   int ileft, irow;
     6457   float bu[kBSplineOrder];
     6458   float *matrix[kBSplineOrder + 2];
     6459   for (i = 0; i < kBSplineOrder + 2; i++)
     6460      matrix[i] = new float[mbloc + nu + 1];
     6461   for (iu = kBSplineOrder - 1; iu < nu; iu++) {
     6462      for (i = 0; i < np; i++) {
     6463         if (1 <= uu[i])
     6464            ileft = nu - 1;
     6465         else if (uu[i] < 0)
     6466            ileft = kBSplineOrder - 2;
     6467         else
     6468            ileft = kBSplineOrder - 1 + static_cast < int >(uu[i] * (nu - kBSplineOrder + 1));
     6469         if (ileft != iu)
     6470            continue;
     6471         irow = ir + mt;
     6472         mt++;
     6473         CalibrationData::CalculateBSpline(nu, uu[i], bu);
     6474         for (j = 0; j < kBSplineOrder; j++) {
     6475            matrix[j][irow] = bu[j];
     6476         }
     6477         matrix[kBSplineOrder][irow] = p[i];
     6478         if (mt < mbloc)
     6479            continue;
     6480         LeastSquaresAccumulation(matrix, kBSplineOrder, &ip, &ir, mt, iu - kBSplineOrder + 1);
     6481         mt = 0;
     6482      }
     6483      if (mt == 0)
     6484         continue;
    36886485      LeastSquaresAccumulation(matrix, kBSplineOrder, &ip, &ir, mt, iu - kBSplineOrder + 1);
    36896486      mt = 0;
    3690     }
    3691     if (mt == 0)
    3692       continue;
    3693     LeastSquaresAccumulation(matrix, kBSplineOrder, &ip, &ir, mt, iu - kBSplineOrder + 1);
    3694     mt = 0;
    3695   }
    3696   if (!LeastSquaresSolving(matrix, kBSplineOrder, ip, ir, coef, nu)) {
    3697     for (i = 0; i < kBSplineOrder + 2; i++)
     6487   }
     6488   if (!LeastSquaresSolving(matrix, kBSplineOrder, ip, ir, coef, nu)) {
     6489      for (i = 0; i < kBSplineOrder + 2; i++)
     6490         delete matrix[i];
     6491      return 0;
     6492   }
     6493
     6494   for (i = 0; i < kBSplineOrder + 2; i++)
    36986495      delete matrix[i];
    3699     return 0;
    3700   }
    3701  
    3702   for (i = 0; i < kBSplineOrder + 2; i++)
    3703     delete matrix[i];
    3704   return 1;
     6496   return 1;
    37056497}
    37066498
     
    37096501void ResponseCalibration::LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt)
    37106502{
    3711   int i, j, l, mu, k, kh;
    3712   float rho;
    3713  
    3714   if (mt <= 0)
    3715     return;
    3716   if (jt != *ip) {
    3717     if (jt > (*ir)) {
    3718       for (i = 0; i < mt; i++) {
    3719         for (j = 0; j < nb + 1; j++) {
    3720           matrix[j][jt + mt - i] = matrix[j][(*ir) + mt - i];
    3721         }
    3722       }
    3723       for (i = 0; i < jt - (*ir); i++) {
    3724         for (j = 0; j < nb + 1; j++) {
    3725           matrix[j][(*ir) + i] = 0;
    3726         }
    3727       }
    3728       *ir = jt;
    3729     }
    3730     mu = min(nb - 1, (*ir) - (*ip) - 1);
    3731     if (mu != 0) {
    3732       for (l = 0; l < mu; l++) {
    3733         k = min(l + 1, jt - (*ip));
    3734         for (i = l + 1; i < nb; i++) {
    3735           matrix[i - k][(*ip) + l + 1] = matrix[i][(*ip) + l + 1];
    3736         }
    3737         for (i = 0; i < k; i++) {
    3738           matrix[nb - i - 1][(*ip) + l + 1] = 0;
    3739         }
    3740       }
    3741     }
    3742     *ip = jt;
    3743   }
    3744   kh = min(nb + 1, (*ir) + mt - (*ip));
    3745  
    3746   for (i = 0; i < kh; i++) {
    3747     Housholder(i, max(i + 1, (*ir) - (*ip)), (*ir) + mt - (*ip), matrix, i, (*ip), &rho, matrix, i + 1,
    3748                (*ip), 1, nb - i);
    3749   }
    3750  
    3751   *ir = (*ip) + kh;
    3752   if (kh < nb + 1)
    3753     return;
    3754   for (i = 0; i < nb; i++) {
    3755     matrix[i][(*ir) - 1] = 0;
    3756   }
     6503   int i, j, l, mu, k, kh;
     6504   float rho;
     6505
     6506   if (mt <= 0)
     6507      return;
     6508   if (jt != *ip) {
     6509      if (jt > (*ir)) {
     6510         for (i = 0; i < mt; i++) {
     6511            for (j = 0; j < nb + 1; j++) {
     6512               matrix[j][jt + mt - i] = matrix[j][(*ir) + mt - i];
     6513            }
     6514         }
     6515         for (i = 0; i < jt - (*ir); i++) {
     6516            for (j = 0; j < nb + 1; j++) {
     6517               matrix[j][(*ir) + i] = 0;
     6518            }
     6519         }
     6520         *ir = jt;
     6521      }
     6522      mu = min(nb - 1, (*ir) - (*ip) - 1);
     6523      if (mu != 0) {
     6524         for (l = 0; l < mu; l++) {
     6525            k = min(l + 1, jt - (*ip));
     6526            for (i = l + 1; i < nb; i++) {
     6527               matrix[i - k][(*ip) + l + 1] = matrix[i][(*ip) + l + 1];
     6528            }
     6529            for (i = 0; i < k; i++) {
     6530               matrix[nb - i - 1][(*ip) + l + 1] = 0;
     6531            }
     6532         }
     6533      }
     6534      *ip = jt;
     6535   }
     6536   kh = min(nb + 1, (*ir) + mt - (*ip));
     6537
     6538   for (i = 0; i < kh; i++) {
     6539      Housholder(i, max(i + 1, (*ir) - (*ip)), (*ir) + mt - (*ip), matrix, i, (*ip), &rho, matrix, i + 1,
     6540                 (*ip), 1, nb - i);
     6541   }
     6542
     6543   *ir = (*ip) + kh;
     6544   if (kh < nb + 1)
     6545      return;
     6546   for (i = 0; i < nb; i++) {
     6547      matrix[i][(*ir) - 1] = 0;
     6548   }
    37576549}
    37586550
     
    37616553int ResponseCalibration::LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n)
    37626554{
    3763   int i, j, l, ii;
    3764   float s, rsq;
    3765   for (j = 0; j < n; j++) {
    3766     x[j] = matrix[nb][j];
    3767   }
    3768   rsq = 0;
    3769   if (n <= ir - 1) {
    3770     for (j = n; j < ir; j++) {
    3771       rsq += pow(matrix[nb][j], 2);
    3772     }
    3773   }
    3774  
    3775   for (ii = 0; ii < n; ii++) {
    3776     i = n - ii - 1;
    3777     s = 0;
    3778     l = max(0, i - ip);
    3779     if (i != n - 1) {
    3780       for (j = 1; j < min(n - i, nb); j++) {
    3781         s += matrix[j + l][i] * x[i + j];
    3782       }
    3783     }
    3784     if (matrix[l][i] == 0) {
    3785       printf("Error in LeastSquaresSolving.\n");
    3786       return 0;
    3787     }
    3788     x[i] = (x[i] - s) / matrix[l][i];
    3789   }
    3790   return 1;
     6555   int i, j, l, ii;
     6556   float s, rsq;
     6557   for (j = 0; j < n; j++) {
     6558      x[j] = matrix[nb][j];
     6559   }
     6560   rsq = 0;
     6561   if (n <= ir - 1) {
     6562      for (j = n; j < ir; j++) {
     6563         rsq += pow(matrix[nb][j], 2);
     6564      }
     6565   }
     6566
     6567   for (ii = 0; ii < n; ii++) {
     6568      i = n - ii - 1;
     6569      s = 0;
     6570      l = max(0, i - ip);
     6571      if (i != n - 1) {
     6572         for (j = 1; j < min(n - i, nb); j++) {
     6573            s += matrix[j + l][i] * x[i + j];
     6574         }
     6575      }
     6576      if (matrix[l][i] == 0) {
     6577         printf("Error in LeastSquaresSolving.\n");
     6578         return 0;
     6579      }
     6580      x[i] = (x[i] - s) / matrix[l][i];
     6581   }
     6582   return 1;
    37916583}
    37926584
     
    37966588                                     float **c, int iC1, int iC2, int ice, int ncv)
    37976589{
    3798   int i, j, incr;
    3799   float tol = static_cast<float>(1e-20);
    3800   float tolb = static_cast<float>(1e-24);
    3801   float cl, clinv, sm, b;
    3802  
    3803   if (lpivot < 0 || lpivot >= l1 || l1 > m - 1)
    3804     return;
    3805   cl = fabs(u[iU1][iU2 + lpivot]);
    3806  
    3807   // Construct the transformation
    3808   for (j = l1 - 1; j < m; j++)
    3809     cl = max(fabsf(u[iU1][iU2 + j]), cl);
    3810   if (cl < tol)
    3811     return;
    3812   clinv = 1 / cl;
    3813   sm = pow(u[iU1][iU2 + lpivot] * clinv, 2);
    3814   for (j = l1; j < m; j++) {
    3815     sm = sm + pow(u[iU1][iU2 + j] * clinv, 2);
    3816   }
    3817   cl *= sqrt(sm);
    3818   if (u[iU1][iU2 + lpivot] > 0)
    3819     cl = -cl;
    3820   *up = u[iU1][iU2 + lpivot] - cl;
    3821   u[iU1][iU2 + lpivot] = cl;
    3822  
    3823   if (ncv <= 0)
    3824     return;
    3825   b = (*up) * u[iU1][iU2 + lpivot];
    3826   if (fabs(b) < tolb)
    3827     return;
    3828   if (b >= 0)
    3829     return;
    3830   b = 1 / b;
    3831   incr = ice * (l1 - lpivot);
    3832   for (j = 0; j < ncv; j++) {
    3833     sm = c[iC1 + j][iC2 + lpivot] * (*up);
    3834     for (i = l1; i < m; i++) {
    3835       sm = sm + c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] * u[iU1][iU2 + i];
    3836     }
    3837     if (sm == 0)
    3838       continue;
    3839     sm *= b;
    3840     c[iC1 + j][iC2 + lpivot] = c[iC1 + j][iC2 + lpivot] + sm * (*up);
    3841     for (i = l1; i < m; i++) {
    3842       c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] =
    3843         c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] + sm * u[iU1][iU2 + i];
    3844     }
    3845   }
     6590   int i, j, incr;
     6591   float tol = static_cast < float >(1e-20);
     6592   float tolb = static_cast < float >(1e-24);
     6593   float cl, clinv, sm, b;
     6594
     6595   if (lpivot < 0 || lpivot >= l1 || l1 > m - 1)
     6596      return;
     6597   cl = fabs(u[iU1][iU2 + lpivot]);
     6598
     6599   // Construct the transformation
     6600   for (j = l1 - 1; j < m; j++)
     6601      cl = max(fabsf(u[iU1][iU2 + j]), cl);
     6602   if (cl < tol)
     6603      return;
     6604   clinv = 1 / cl;
     6605   sm = pow(u[iU1][iU2 + lpivot] * clinv, 2);
     6606   for (j = l1; j < m; j++) {
     6607      sm = sm + pow(u[iU1][iU2 + j] * clinv, 2);
     6608   }
     6609   cl *= sqrt(sm);
     6610   if (u[iU1][iU2 + lpivot] > 0)
     6611      cl = -cl;
     6612   *up = u[iU1][iU2 + lpivot] - cl;
     6613   u[iU1][iU2 + lpivot] = cl;
     6614
     6615   if (ncv <= 0)
     6616      return;
     6617   b = (*up) * u[iU1][iU2 + lpivot];
     6618   if (fabs(b) < tolb)
     6619      return;
     6620   if (b >= 0)
     6621      return;
     6622   b = 1 / b;
     6623   incr = ice * (l1 - lpivot);
     6624   for (j = 0; j < ncv; j++) {
     6625      sm = c[iC1 + j][iC2 + lpivot] * (*up);
     6626      for (i = l1; i < m; i++) {
     6627         sm = sm + c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] * u[iU1][iU2 + i];
     6628      }
     6629      if (sm == 0)
     6630         continue;
     6631      sm *= b;
     6632      c[iC1 + j][iC2 + lpivot] = c[iC1 + j][iC2 + lpivot] + sm * (*up);
     6633      for (i = l1; i < m; i++) {
     6634         c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] =
     6635             c[iC1 + j][iC2 + lpivot + incr + (i - l1) * ice] + sm * u[iU1][iU2 + i];
     6636      }
     6637   }
    38466638}
    38476639
     
    38506642int ResponseCalibration::MakeDir(const char *path)
    38516643{
    3852   struct stat buf;
    3853   if (stat(path, &buf))
    3854     return mkdir(path, 0711);
    3855   return 0;
     6644   struct stat buf;
     6645   if (stat(path, &buf)) {
     6646#ifdef _MSC_VER
     6647      return mkdir(path);
     6648#else
     6649      return mkdir(path, 0711);
     6650#endif                          // R__UNIX
     6651   }
     6652   return 0;
    38566653}
    38576654
     
    38596656
    38606657ResponseCalibration::ResponseCalibration(DRSBoard *board)
    3861   :fBoard(board)
    3862    ,fPrecision(0.1) // mV
    3863    ,fInitialized(false)
    3864    ,fRecorded(false)
    3865    ,fFitted(false)
    3866    ,fOffset(false)
    3867    ,fNumberOfPointsLowVolt(0)
    3868    ,fNumberOfPoints(0)
    3869    ,fNumberOfMode2Bins(0)
    3870    ,fNumberOfSamples(0)
    3871    ,fNumberOfGridPoints(0)
    3872    ,fNumberOfXConstPoints(0)
    3873    ,fNumberOfXConstGridPoints(0)
    3874    ,fTriggerFrequency(0)
    3875    ,fShowStatistics(0)
    3876    ,fCalibFile(0)
    3877    ,fCurrentLowVoltPoint(0)
    3878    ,fCurrentPoint(0)
    3879    ,fCurrentSample(0)
    3880    ,fCurrentFitChannel(0)
    3881    ,fCurrentFitBin(0)
    3882    ,fResponseY(0)
    3883    ,fSamples(0)
    3884    ,fSampleUsed(0)
    3885    ,fXXFit(0)
    3886    ,fYYFit(0)
    3887    ,fWWFit(0)
    3888    ,fYYFitRes(0)
    3889    ,fYYSave(0)
    3890    ,fXXSave(0)
    3891    ,fStatisticsApprox(0)
    3892    ,fStatisticsApproxExt(0)
    3893 {
    3894   int i;
    3895   // Initializing the Calibration Class
    3896   CalibrationData::fIntRevers[0] = 0;
    3897   for (i = 1; i < 2 * kBSplineOrder - 2; i++) {
    3898     CalibrationData::fIntRevers[i] = static_cast<float>(1.) / i;
    3899   }
    3900   for (i = 0; i < kNumberOfChips; i++) {
    3901     fCalibrationData[i] = NULL;
    3902   }
    3903   // Initializing the Calibration Creation
    3904   fCalibrationValid[0] = false;
    3905   fCalibrationValid[1] = false;
     6658:  fBoard(board)
     6659    , fPrecision(0.1)           // mV
     6660    , fInitialized(false)
     6661    , fRecorded(false)
     6662    , fFitted(false)
     6663    , fOffset(false)
     6664    , fNumberOfPointsLowVolt(0)
     6665    , fNumberOfPoints(0)
     6666    , fNumberOfMode2Bins(0)
     6667    , fNumberOfSamples(0)
     6668    , fNumberOfGridPoints(0)
     6669    , fNumberOfXConstPoints(0)
     6670    , fNumberOfXConstGridPoints(0)
     6671    , fTriggerFrequency(0)
     6672    , fShowStatistics(0)
     6673    , fCalibFile(0)
     6674    , fCurrentLowVoltPoint(0)
     6675    , fCurrentPoint(0)
     6676    , fCurrentSample(0)
     6677    , fCurrentFitChannel(0)
     6678    , fCurrentFitBin(0)
     6679    , fResponseY(0)
     6680    , fSamples(0)
     6681    , fSampleUsed(0)
     6682    , fXXFit(0)
     6683    , fYYFit(0)
     6684    , fWWFit(0)
     6685    , fYYFitRes(0)
     6686    , fYYSave(0)
     6687    , fXXSave(0)
     6688    , fStatisticsApprox(0)
     6689    , fStatisticsApproxExt(0)
     6690{
     6691   int i;
     6692   // Initializing the Calibration Class
     6693   CalibrationData::fIntRevers[0] = 0;
     6694   for (i = 1; i < 2 * kBSplineOrder - 2; i++) {
     6695      CalibrationData::fIntRevers[i] = static_cast < float >(1.) / i;
     6696   }
     6697   for (i = 0; i < kNumberOfChipsMax; i++) {
     6698      fCalibrationData[i] = NULL;
     6699   }
     6700   // Initializing the Calibration Creation
     6701   fCalibrationValid[0] = false;
     6702   fCalibrationValid[1] = false;
     6703   
     6704   fBoard = board;
    39066705}
    39076706
     
    39106709ResponseCalibration::~ResponseCalibration()
    39116710{
    3912   // Deleting the Calibration Creation
    3913   DeleteFields();
     6711   // Delete the Calibration
     6712   for (int i=0 ; i<kNumberOfChipsMax ; i++)
     6713      delete fCalibrationData[i];
     6714
     6715   // Deleting the Calibration Creation
     6716   DeleteFields();
    39146717}
    39156718
     
    39186721float ResponseCalibration::CalibrationData::fIntRevers[2 * kBSplineOrder - 2];
    39196722ResponseCalibration::CalibrationData::CalibrationData(int numberOfGridPoints)
    3920   :fRead(false)
    3921    ,fNumberOfGridPoints(numberOfGridPoints)
    3922    ,fHasOffsetCalibration(0)
    3923    ,fStartTemperature(0)
    3924    ,fEndTemperature(0)
    3925    ,fMin(0)
    3926    ,fMax(0)
    3927    ,fNumberOfLimitGroups(0)
    3928 {
    3929   int i;
    3930   for (i = 0; i < kNumberOfCalibChannels; i++) {
    3931     fChannel[i] = new CalibrationDataChannel(numberOfGridPoints);
    3932   }
    3933   for (i = 0; i < kNumberOfADCBins; i++) {
    3934     fBSplineOffsetLookUp[i] = NULL;
    3935     fBSplineLookUp[i] = NULL;
    3936   }
     6723:fRead(false)
     6724, fNumberOfGridPoints(numberOfGridPoints)
     6725, fHasOffsetCalibration(0)
     6726, fStartTemperature(0)
     6727, fEndTemperature(0)
     6728, fMin(0)
     6729, fMax(0)
     6730, fNumberOfLimitGroups(0)
     6731{
     6732   int i;
     6733   for (i = 0; i < kNumberOfCalibChannelsV3; i++) {
     6734      fChannel[i] = new CalibrationDataChannel(numberOfGridPoints);
     6735   }
     6736   for (i = 0; i < kNumberOfADCBins; i++) {
     6737      fBSplineOffsetLookUp[i] = NULL;
     6738      fBSplineLookUp[i] = NULL;
     6739   }
    39376740};
    39386741
     
    39416744void ResponseCalibration::CalibrationData::PreCalculateBSpline()
    39426745{
    3943   int i, j;
    3944   float uu;
    3945   float xmin, xrange;
    3946   int nk = fNumberOfGridPoints - kBSplineOrder + 1;
    3947   for (i = 0; i < kNumberOfADCBins; i++) {
    3948     fBSplineLookUp[i] = new float *[fNumberOfLimitGroups];
    3949     fBSplineOffsetLookUp[i] = new int[fNumberOfLimitGroups];
    3950     for (j = 0; j < fNumberOfLimitGroups; j++) {
    3951       fBSplineLookUp[i][j] = new float[kBSplineOrder];
    3952       xmin = fMin + j * kBSplineXMinOffset;
    3953       xrange = fMax - xmin;
    3954       uu = (i - xmin) / xrange;
    3955       if (i < xmin) {
    3956         uu = 0;
    3957       }
    3958       if (i - xmin > xrange) {
    3959         uu = 1;
    3960       }
    3961       fBSplineOffsetLookUp[i][j] = static_cast<int>(uu * nk);
    3962       CalculateBSpline(fNumberOfGridPoints, uu, fBSplineLookUp[i][j]);
    3963     }
    3964   }
     6746   int i, j;
     6747   float uu;
     6748   float xmin, xrange;
     6749   int nk = fNumberOfGridPoints - kBSplineOrder + 1;
     6750   for (i = 0; i < kNumberOfADCBins; i++) {
     6751      fBSplineLookUp[i] = new float *[fNumberOfLimitGroups];
     6752      fBSplineOffsetLookUp[i] = new int[fNumberOfLimitGroups];
     6753      for (j = 0; j < fNumberOfLimitGroups; j++) {
     6754         fBSplineLookUp[i][j] = new float[kBSplineOrder];
     6755         xmin = fMin + j * kBSplineXMinOffset;
     6756         xrange = fMax - xmin;
     6757         uu = (i - xmin) / xrange;
     6758         if (i < xmin) {
     6759            uu = 0;
     6760         }
     6761         if (i - xmin > xrange) {
     6762            uu = 1;
     6763         }
     6764         fBSplineOffsetLookUp[i][j] = static_cast < int >(uu * nk);
     6765         CalculateBSpline(fNumberOfGridPoints, uu, fBSplineLookUp[i][j]);
     6766      }
     6767   }
    39656768}
    39666769
     
    39696772void ResponseCalibration::CalibrationData::DeletePreCalculatedBSpline()
    39706773{
    3971   int i, j;
    3972   for (i = 0; i < kNumberOfADCBins; i++) {
    3973     if (fBSplineLookUp[i]!=NULL) {
    3974       for (j = 0; j < fNumberOfLimitGroups; j++)
    3975         delete fBSplineLookUp[i][j];
    3976     }
    3977     delete fBSplineLookUp[i];
    3978     delete fBSplineOffsetLookUp[i];
    3979   }
     6774   int i, j;
     6775   for (i = 0; i < kNumberOfADCBins; i++) {
     6776      if (fBSplineLookUp[i] != NULL) {
     6777         for (j = 0; j < fNumberOfLimitGroups; j++)
     6778            delete fBSplineLookUp[i][j];
     6779      }
     6780      delete fBSplineLookUp[i];
     6781      delete fBSplineOffsetLookUp[i];
     6782   }
    39806783}
    39816784
     
    39846787ResponseCalibration::CalibrationData::~CalibrationData()
    39856788{
    3986   int i, j;
    3987   for (i = 0; i < kNumberOfCalibChannels; i++) {
    3988     delete fChannel[i];
    3989   }
    3990   for (i = 0; i < kNumberOfADCBins; i++) {
    3991     if (fBSplineLookUp[i]!=NULL) {
    3992       for (j = 0; j < fNumberOfLimitGroups; j++) {
    3993         delete fBSplineLookUp[i][j];
    3994       }
    3995     }
    3996     delete fBSplineLookUp[i];
    3997     delete fBSplineOffsetLookUp[i];
    3998   }
     6789   int i, j;
     6790   for (i = 0; i < kNumberOfCalibChannelsV3; i++) {
     6791      delete fChannel[i];
     6792   }
     6793   for (i = 0; i < kNumberOfADCBins; i++) {
     6794      if (fBSplineLookUp[i] != NULL) {
     6795         for (j = 0; j < fNumberOfLimitGroups; j++) {
     6796            delete fBSplineLookUp[i][j];
     6797         }
     6798      }
     6799      delete fBSplineLookUp[i];
     6800      delete fBSplineOffsetLookUp[i];
     6801   }
    39996802};
    40006803
     
    40036806int ResponseCalibration::CalibrationData::CalculateBSpline(int nGrid, float value, float *bsplines)
    40046807{
    4005   int minimum;
    4006   int maximum;
    4007   float xl;
    4008  
    4009   int nk = nGrid - kBSplineOrder + 1;
    4010   float vl = value * nk;
    4011   int ivl = static_cast<int>(vl);
    4012  
    4013   if (1 <= value) {
    4014     xl = vl - nk + 1;
    4015     minimum = 1 - nk;
    4016   } else if (value < 0) {
    4017     xl = vl;
    4018     minimum = 0;
    4019   } else {
    4020     xl = vl - ivl;
    4021     minimum = -ivl;
    4022   }
    4023   maximum = nk + minimum;
    4024  
    4025   // printf("xl = %f\n",xl);
    4026   float vm, vmprev;
    4027   int jl, ju;
    4028   int nb = 0;
    4029  
    4030   bsplines[0] = 1;
    4031   for (int i = 0; i < kBSplineOrder - 1; i++) {
    4032     vmprev = 0;
    4033     for (int j = 0; j < nb + 1; j++) {
    4034       jl = max(minimum, j - nb);
    4035       ju = min(maximum, j + 1);
    4036       vm = bsplines[j] * fIntRevers[ju - jl];
    4037       bsplines[j] = vm * (ju - xl) + vmprev;
    4038       vmprev = vm * (xl - jl);
    4039     }
    4040     nb++;
    4041     bsplines[nb] = vmprev;
    4042   }
    4043   return -minimum;
    4044 }
    4045 
    4046 /*------------------------------------------------------------------*/
    4047 
    4048 void ResponseCalibration::Average(int method,float *points,int numberOfPoints,float &mean,float &error,float sigmaBoundary)
    4049 {
    4050   // Methods :
    4051   // 0 : Average
    4052   // 1 : Average inside sigmaBoundary*sigma
    4053   int i;
    4054   float sum = 0;
    4055   float sumSquare = 0;
    4056  
    4057   if (method == 0 || method == 1) {
    4058     for (i = 0; i < numberOfPoints; i++) {
    4059       sum += points[i];
    4060       sumSquare += points[i]*points[i];
    4061     }
    4062    
    4063     mean = sum / numberOfPoints;
    4064     error = sqrt((sumSquare - sum * sum / numberOfPoints) / (numberOfPoints - 1));
    4065   }
    4066   if (method == 1) {
    4067     int numberOfGoodPoints = numberOfPoints;
    4068     bool found = true;
    4069     bool *goodSample = new bool[numberOfGoodPoints];
    4070     for (i = 0; i < numberOfGoodPoints; i++)
    4071       goodSample[i] = true;
    4072    
    4073     while (found) {
    4074       found = false;
     6808   int minimum;
     6809   int maximum;
     6810   float xl;
     6811
     6812   int nk = nGrid - kBSplineOrder + 1;
     6813   float vl = value * nk;
     6814   int ivl = static_cast < int >(vl);
     6815
     6816   if (1 <= value) {
     6817      xl = vl - nk + 1;
     6818      minimum = 1 - nk;
     6819   } else if (value < 0) {
     6820      xl = vl;
     6821      minimum = 0;
     6822   } else {
     6823      xl = vl - ivl;
     6824      minimum = -ivl;
     6825   }
     6826   maximum = nk + minimum;
     6827
     6828//   printf("xl = %f\n",xl);
     6829   float vm, vmprev;
     6830   int jl, ju;
     6831   int nb = 0;
     6832
     6833   bsplines[0] = 1;
     6834   for (int i = 0; i < kBSplineOrder - 1; i++) {
     6835      vmprev = 0;
     6836      for (int j = 0; j < nb + 1; j++) {
     6837         jl = max(minimum, j - nb);
     6838         ju = min(maximum, j + 1);
     6839         vm = bsplines[j] * fIntRevers[ju - jl];
     6840         bsplines[j] = vm * (ju - xl) + vmprev;
     6841         vmprev = vm * (xl - jl);
     6842      }
     6843      nb++;
     6844      bsplines[nb] = vmprev;
     6845   }
     6846   return -minimum;
     6847}
     6848
     6849/*------------------------------------------------------------------*/
     6850
     6851void ResponseCalibration::Average(int method, float *points, int numberOfPoints, float &mean, float &error,
     6852                                  float sigmaBoundary)
     6853{
     6854   // Methods :
     6855   // 0 : Average
     6856   // 1 : Average inside sigmaBoundary*sigma
     6857   int i;
     6858   float sum = 0;
     6859   float sumSquare = 0;
     6860
     6861   if (method == 0 || method == 1) {
    40756862      for (i = 0; i < numberOfPoints; i++) {
    4076         if (goodSample[i] && fabs(points[i] - mean) > sigmaBoundary * error) {
    4077           found = true;
    4078           goodSample[i] = false;
    4079           numberOfGoodPoints--;
    4080           sum -= points[i];
    4081           sumSquare -= points[i]*points[i];
    4082           mean = sum/numberOfGoodPoints;
    4083           error = sqrt((sumSquare - sum * sum / numberOfGoodPoints) / (numberOfGoodPoints - 1));
    4084         }
    4085       }
    4086     }
    4087     delete goodSample;
    4088   }
    4089 }
    4090 
    4091 
     6863         sum += points[i];
     6864         sumSquare += points[i] * points[i];
     6865      }
     6866
     6867      mean = sum / numberOfPoints;
     6868      error = sqrt((sumSquare - sum * sum / numberOfPoints) / (numberOfPoints - 1));
     6869   }
     6870   if (method == 1) {
     6871      int numberOfGoodPoints = numberOfPoints;
     6872      bool found = true;
     6873      bool *goodSample = new bool[numberOfGoodPoints];
     6874      for (i = 0; i < numberOfGoodPoints; i++)
     6875         goodSample[i] = true;
     6876
     6877      while (found) {
     6878         found = false;
     6879         for (i = 0; i < numberOfPoints; i++) {
     6880            if (goodSample[i] && fabs(points[i] - mean) > sigmaBoundary * error) {
     6881               found = true;
     6882               goodSample[i] = false;
     6883               numberOfGoodPoints--;
     6884               sum -= points[i];
     6885               sumSquare -= points[i] * points[i];
     6886               mean = sum / numberOfGoodPoints;
     6887               error = sqrt((sumSquare - sum * sum / numberOfGoodPoints) / (numberOfGoodPoints - 1));
     6888            }
     6889         }
     6890      }
     6891      delete goodSample;
     6892   }
     6893}
    40926894
    40936895
  • drsdaq/DRS/DRS.h

    r132 r176  
    1 
     1/********************************************************************
     2  DRS.h, S.Ritt, M. Schneebeli - PSI
     3
     4  $Id: DRS.h 14428 2009-10-19 12:59:46Z ritt $
     5
     6********************************************************************/
    27#ifndef DRS_H
    38#define DRS_H
    4 
    59#include <stdio.h>
    6 #include <math.h>
    710#include <string.h>
    8 #include <stdlib.h>
    9 #include <time.h>
    10 #include <sys/time.h>
    11 #include <assert.h>
    12 #include <algorithm>
    13 #include <sys/stat.h>
    14 #include <unistd.h>
    15 #include <sys/ioctl.h>
    16 
    17 #include "mxml.h"
    18 #include "strlcpy.h"
     11
     12#ifdef HAVE_LIBUSB
     13#   ifndef HAVE_USB
     14#      define HAVE_USB
     15#   endif
     16#endif
     17
     18#ifdef HAVE_USB
     19#   include <musbstd.h>
     20#endif                          // HAVE_USB
     21
     22#ifdef HAVE_VME
     23#   include <mvmestd.h>
     24#endif                          // HAVE_VME
    1925
    2026// Concurrent Technologies VME single board computer
     
    2329  #include "vme_rcc/vme_rcc.h"       // VME access
    2430  #include "cmem_rcc/cmem_rcc.h"     // Allocation of contiguous memory
    25   #include "rcc_time_stamp/tstamp.h" // Time stamp library
    26 #endif
    27 
    28 // Struck VME interface
    29 #ifdef STRUCK_VME
    30   #include "mvmestd.h"
    31 #endif
    32 
    33 // Control register bit definitions
    34 #define BIT_START_TRIG        (1<<0)    // Write a "1" to start domino wave
    35 #define BIT_REINIT_TRIG       (1<<1)    // Write a "1" to stop & reset DRS
    36 #define BIT_SOFT_TRIG         (1<<2)    // Write a "1" to stop and read data to RAM
    37 #define BIT_FLASH_TRIG        (1<<3)    // Write a "1" to write DAC0 & DAC1 into serial EEPROM
     31#endif
     32
     33/* disable "deprecated" warning */
     34#ifdef _MSC_VER
     35#pragma warning(disable: 4996)
     36#endif
     37
     38#ifndef NULL
     39#define NULL 0
     40#endif
     41
     42/* transport mode */
     43#define TR_VME   1
     44#define TR_USB   2
     45#define TR_USB2  3
     46
     47/* address types */
     48#ifndef T_CTRL
     49#define T_CTRL   1
     50#define T_STATUS 2
     51#define T_RAM    3
     52#define T_FIFO   4
     53#endif
     54
     55/*---- Register addresses ------------------------------------------*/
     56
     57#define REG_CTRL                     0x00000    /* 32 bit control reg */
     58#define REG_DAC_OFS                  0x00004
     59#define REG_DAC0                     0x00004
     60#define REG_DAC1                     0x00006
     61#define REG_DAC2                     0x00008
     62#define REG_DAC3                     0x0000A
     63#define REG_DAC4                     0x0000C
     64#define REG_DAC5                     0x0000E
     65#define REG_DAC6                     0x00010
     66#define REG_DAC7                     0x00012
     67#define REG_CHANNEL_CONFIG           0x00014    // low byte
     68#define REG_CONFIG                   0x00014    // high byte
     69#define REG_CHANNEL_MODE             0x00016
     70#define REG_ADCCLK_PHASE             0x00016
     71#define REG_FREQ_SET_HI              0x00018    // DRS2
     72#define REG_FREQ_SET_LO              0x0001A    // DRS2
     73#define REG_TRG_DELAY                0x00018    // DRS4
     74#define REG_FREQ_SET                 0x0001A    // DRS4
     75#define REG_TRIG_DELAY               0x0001C
     76#define REG_LMK_MSB                  0x0001C    // DRS4 Mezz
     77#define REG_CALIB_TIMING             0x0001E    // DRS2
     78#define REG_EEPROM_PAGE_EVAL         0x0001E    // DRS4 Eval
     79#define REG_EEPROM_PAGE_MEZZ         0x0001A    // DRS4 Mezz
     80#define REG_LMK_LSB                  0x0001E    // DRS4 Mezz
     81#define REG_WARMUP                   0x00020    // DRS4 Mezz
     82#define REG_COOLDOWN                 0x00022    // DRS4 Mezz
     83
     84#define REG_MAGIC                    0x00000
     85#define REG_BOARD_TYPE               0x00002
     86#define REG_STATUS                   0x00004
     87#define REG_RDAC_OFS                 0x0000E
     88#define REG_RDAC0                    0x00008
     89#define REG_STOP_CELL0               0x00008
     90#define REG_RDAC1                    0x0000A
     91#define REG_STOP_CELL1               0x0000A
     92#define REG_RDAC2                    0x0000C
     93#define REG_STOP_CELL2               0x0000C
     94#define REG_RDAC3                    0x0000E
     95#define REG_STOP_CELL3               0x0000E
     96#define REG_RDAC4                    0x00000
     97#define REG_RDAC5                    0x00002
     98#define REG_RDAC6                    0x00014
     99#define REG_RDAC7                    0x00016
     100#define REG_EVENTS_IN_FIFO           0x00018
     101#define REG_EVENT_COUNT              0x0001A
     102#define REG_FREQ1                    0x0001C
     103#define REG_FREQ2                    0x0001E
     104#define REG_TEMPERATURE              0x00020
     105#define REG_TRIGGER_BUS              0x00022
     106#define REG_SERIAL_BOARD             0x00024
     107#define REG_VERSION_FW               0x00026
     108
     109/*---- Control register bit definitions ----------------------------*/
     110
     111#define BIT_START_TRIG        (1<<0)    // write a "1" to start domino wave
     112#define BIT_REINIT_TRIG       (1<<1)    // write a "1" to stop & reset DRS
     113#define BIT_SOFT_TRIG         (1<<2)    // write a "1" to stop and read data to RAM
     114#define BIT_EEPROM_WRITE_TRIG (1<<3)    // write a "1" to write into serial EEPROM
     115#define BIT_EEPROM_READ_TRIG  (1<<4)    // write a "1" to read from serial EEPROM
    38116#define BIT_AUTOSTART        (1<<16)
    39 #define BIT_DMODE            (1<<17)    // 0: single shot, 1: circular
     117#define BIT_DMODE            (1<<17)    // (*DRS2*) 0: single shot, 1: circular
    40118#define BIT_LED              (1<<18)    // 1=on, 0=blink during readout
    41 #define BIT_TCAL_EN          (1<<19)    // Switch on (1) / off (0) for 33 MHz calib signal
    42 #define BIT_ZERO_SUPP        (1<<20)
    43 #define BIT_FREQ_AUTO_ADJ    (1<<21)
    44 #define BIT_ENABLE_TRIGGER   (1<<22)
    45 #define BIT_LONG_START_PULSE (1<<23)    // (*DRS2*) 0:short start pulse (> 0.8 GHz), 1:long start pulse (< 0.8 GHz)
    46 #define BIT_READOUT_MODE     (1<<23)    // (*DRS3*) 0:start from first bin, 1:start from domino stop
    47 #define BIT_DELAYED_START    (1<<24)    // Start domino wave 400 ns after soft trigger, used for waveform
    48                                         // Generator startup
    49 #define BIT_ACAL_EN          (1<<25)    // Connect DRS to inputs (0) or to DAC6 (1)
    50 #define BIT_TRIGGER_DELAYED  (1<<26)    // Select delayed trigger from trigger bus
    51 #define BIT_DACTIVE          (1<<27)    // Keep domino wave running during readout
    52 
    53 // Status register bit definitions
    54 #define BIT_RUNNING           (1<<0)    // One if domino wave running or readout in progress
    55 #define BIT_NEW_FREQ1         (1<<1)    // One if new frequency measurement available
     119#define BIT_TCAL_EN          (1<<19)    // switch on (1) / off (0) for 33 MHz calib signal
     120#define BIT_TCAL_SOURCE      (1<<20)
     121#define BIT_REFCLK_SOURCE    (1<<20)
     122#define BIT_FREQ_AUTO_ADJ    (1<<21)    // DRS2/3
     123#define BIT_TRANSP_MODE      (1<<21)    // DRS4
     124#define BIT_ENABLE_TRIGGER1  (1<<22)    // External LEMO/FP/TRBUS trigger
     125#define BIT_LONG_START_PULSE (1<<23)    // (*DRS2*) 0:short start pulse (>0.8GHz), 1:long start pulse (<0.8GHz)
     126#define BIT_READOUT_MODE     (1<<23)    // (*DRS3*,*DRS4*) 0:start from first bin, 1:start from domino stop
     127#define BIT_DELAYED_START    (1<<24)    // DRS2: start domino wave 400ns after soft trigger, used for waveform
     128                                        // generator startup
     129#define BIT_NEG_TRIGGER      (1<<24)    // DRS4: use high-to-low trigger if set
     130#define BIT_ACAL_EN          (1<<25)    // connect DRS to inputs (0) or to DAC6 (1)
     131#define BIT_TRIGGER_DELAYED  (1<<26)    // select delayed trigger from trigger bus
     132#define BIT_ADCCLK_INVERT    (1<<26)    // invert ADC clock
     133#define BIT_DACTIVE          (1<<27)    // keep domino wave running during readout
     134#define BIT_STANDBY_MODE     (1<<28)    // put chip in standby mode
     135#define BIT_TR_SOURCE1       (1<<29)    // trigger source selection bits
     136#define BIT_TR_SOURCE2       (1<<30)    // trigger source selection bits
     137#define BIT_ENABLE_TRIGGER2  (1<<31)    // analog threshold (internal) trigger
     138
     139/* DRS4 configuration register bit definitions */
     140#define BIT_CONFIG_DMODE      (1<<8)    // 0: single shot, 1: circular
     141#define BIT_CONFIG_PLLEN      (1<<9)    // write a "1" to enable the internal PLL
     142#define BIT_CONFIG_WSRLOOP   (1<<10)    // write a "1" to connect WSROUT to WSRIN internally
     143
     144/*---- Status register bit definitions -----------------------------*/
     145
     146#define BIT_RUNNING           (1<<0)    // one if domino wave running or readout in progress
     147#define BIT_NEW_FREQ1         (1<<1)    // one if new frequency measurement available
    56148#define BIT_NEW_FREQ2         (1<<2)
     149#define BIT_PLL_LOCKED0       (1<<1)    // 1 if PLL has locked (DRS4 evaluation board only)
     150#define BIT_PLL_LOCKED1       (1<<2)    // 1 if PLL DRS4 B has locked (DRS4 mezzanine board only)
     151#define BIT_PLL_LOCKED2       (1<<3)    // 1 if PLL DRS4 C has locked (DRS4 mezzanine board only)
     152#define BIT_PLL_LOCKED3       (1<<4)    // 1 if PLL DRS4 D has locked (DRS4 mezzanine board only)
     153#define BIT_SERIAL_BUSY       (1<<5)    // 1 if EEPROM operation in progress
     154#define BIT_LMK_LOCKED        (1<<6)    // 1 if PLL of LMK chip has locked (DRS4 mezzanine board only)
    57155
    58156enum DRSBoardConstants {
    59   kNumberOfChannels            =   10,
    60   kNumberOfCalibChannels       =   10,
    61   kNumberOfBins                = 1024,
    62   kNumberOfChips               =    2,
    63   kFrequencyCacheSize          =   10,
    64   kBSplineOrder                =    4,
    65   kPreCaliculatedBSplines      = 1000,
    66   kPreCaliculatedBSplineGroups =    5,
    67   kNumberOfADCBins             = 4096,
    68   kBSplineXMinOffset           =   20,
    69   kMaxNumberOfClockCycles      =  100,
     157   kNumberOfChannelsMax         =   10,
     158   kNumberOfCalibChannelsV3     =   10,
     159   kNumberOfCalibChannelsV4     =    8,
     160   kNumberOfBins                = 1024,
     161   kNumberOfChipsMax            =    4,
     162   kFrequencyCacheSize          =   10,
     163   kBSplineOrder                =    4,
     164   kPreCaliculatedBSplines      = 1000,
     165   kPreCaliculatedBSplineGroups =    5,
     166   kNumberOfADCBins             = 4096,
     167   kBSplineXMinOffset           =   20,
     168   kMaxNumberOfClockCycles      =  100,
    70169};
    71170
    72171enum DRSErrorCodes {
    73   kSuccess                     =  0,
    74   kInvalidTriggerSignal        = -1,
    75   kWrongChannelOrChip          = -2,
    76   kInvalidTransport            = -3,
    77   kZeroSuppression             = -4,
    78   kWaveNotAvailable            = -5
     172   kSuccess                     =  0,
     173   kInvalidTriggerSignal        = -1,
     174   kWrongChannelOrChip          = -2,
     175   kInvalidTransport            = -3,
     176   kZeroSuppression             = -4,
     177   kWaveNotAvailable            = -5
    79178};
    80179
     180/*---- callback class ----*/
     181
     182class DRSCallback
     183{
     184public:
     185   virtual void Progress(int value) = 0;
     186   virtual ~DRSCallback() {};
     187};
     188
     189/*------------------------*/
     190
    81191class DRSBoard;
    82192
    83 
    84193class ResponseCalibration {
    85  protected:
    86  
    87   class CalibrationData {
    88   public:
    89     class CalibrationDataChannel {
    90     public:
    91       unsigned char   fLimitGroup[kNumberOfBins];           //!
    92       float           fMin[kNumberOfBins];                  //!
    93       float           fRange[kNumberOfBins];                //!
    94       short           fOffset[kNumberOfBins];               //!
    95       short           fGain[kNumberOfBins];                 //!
    96       unsigned short  fOffsetADC[kNumberOfBins];            //!
    97       short          *fData[kNumberOfBins];                 //!
    98       unsigned char  *fLookUp[kNumberOfBins];               //!
    99       unsigned short  fLookUpOffset[kNumberOfBins];         //!
    100       unsigned char   fNumberOfLookUpPoints[kNumberOfBins]; //!
    101       float          *fTempData;                            //!
    102      
    103     private:
    104       CalibrationDataChannel(const CalibrationDataChannel &c);              // Not implemented
    105       CalibrationDataChannel &operator=(const CalibrationDataChannel &rhs); // Not implemented
    106      
    107     public:
    108       CalibrationDataChannel(int numberOfGridPoints)
    109         :fTempData(new float[numberOfGridPoints]) {
    110         int i;
    111         for (i = 0; i < kNumberOfBins; i++) {
    112           fData[i] = new short[numberOfGridPoints];
    113           fLookUp[i] = NULL;
    114         }
    115       }
    116       ~CalibrationDataChannel() {
    117         int i;
    118         delete fTempData;
    119         for (i = 0; i < kNumberOfBins; i++) {
    120           delete fData[i];
    121           delete fLookUp[i];
    122         }
    123       }
    124     };
    125    
    126     bool                    fRead;                                  //!
    127     CalibrationDataChannel *fChannel[kNumberOfCalibChannels];       //!
    128     unsigned char           fNumberOfGridPoints;                    //!
    129     int                     fHasOffsetCalibration;                  //!
    130     float                   fStartTemperature;                      //!
    131     float                   fEndTemperature;                        //!
    132     int                    *fBSplineOffsetLookUp[kNumberOfADCBins]; //!
    133     float                 **fBSplineLookUp[kNumberOfADCBins];       //!
    134     float                   fMin;                                   //!
    135     float                   fMax;                                   //!
    136     unsigned char           fNumberOfLimitGroups;                   //!
    137     static float            fIntRevers[2 * kBSplineOrder - 2];
    138    
    139   private:
    140     CalibrationData(const CalibrationData &c);              // Not implemented
    141     CalibrationData &operator=(const CalibrationData &rhs); // Not implemented
    142    
    143   public:
    144     CalibrationData(int numberOfGridPoints);
    145     ~CalibrationData();
    146     static int CalculateBSpline(int nGrid, float value, float *bsplines);
    147     void       PreCalculateBSpline();
    148     void       DeletePreCalculatedBSpline();
    149   };
    150  
    151   // General Fields
    152   DRSBoard        *fBoard;
    153  
    154   double           fPrecision;
    155  
    156   // Fields for creating the Calibration
    157   bool             fInitialized;
    158   bool             fRecorded;
    159   bool             fFitted;
    160   bool             fOffset;
    161   bool             fCalibrationValid[2];
    162  
    163   int              fNumberOfPointsLowVolt;
    164   int              fNumberOfPoints;
    165   int              fNumberOfMode2Bins;
    166   int              fNumberOfSamples;
    167   int              fNumberOfGridPoints;
    168   int              fNumberOfXConstPoints;
    169   int              fNumberOfXConstGridPoints;
    170   double           fTriggerFrequency;
    171   int              fShowStatistics;
    172   FILE            *fCalibFile;
    173  
    174   int              fCurrentLowVoltPoint;
    175   int              fCurrentPoint;
    176   int              fCurrentSample;
    177   int              fCurrentFitChannel;
    178   int              fCurrentFitBin;
    179  
    180   float           *fResponseX[kNumberOfCalibChannels][kNumberOfBins];
    181   float           *fResponseY;
    182   unsigned short **fWaveFormMode3[kNumberOfCalibChannels];
    183   unsigned short **fWaveFormMode2[kNumberOfCalibChannels];
    184   short          **fWaveFormOffset[kNumberOfCalibChannels];
    185   unsigned short **fWaveFormOffsetADC[kNumberOfCalibChannels]; // Is this used?
    186   unsigned short  *fSamples;
    187   int             *fSampleUsed;
    188  
    189   float           *fPntX[2];
    190   float           *fPntY[2];
    191   float           *fUValues[2];
    192   float           *fRes[kNumberOfBins];
    193   float           *fResX[kNumberOfBins];
    194  
    195   double          *fXXFit;
    196   double          *fYYFit;
    197   double          *fWWFit;
    198   double          *fYYFitRes;
    199   double          *fYYSave;
    200   double          *fXXSave;
    201  
    202   float          **fStatisticsApprox;
    203   float          **fStatisticsApproxExt;
    204  
    205   // Fields for applying the Calibration
    206   CalibrationData *fCalibrationData[kNumberOfChips];
    207  
    208  private:
    209   ResponseCalibration(const ResponseCalibration &c);              // Not implemented
    210   ResponseCalibration &operator=(const ResponseCalibration &rhs); // Not implemented
    211  
    212  public:
    213   ResponseCalibration(DRSBoard* board);
    214   ~ResponseCalibration();
    215  
    216   void   SetCalibrationParameters(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins,
    217                                   int numberOfSamples, int numberOfGridPoints, int numberOfXConstPoints,
    218                                   int numberOfXConstGridPoints, double triggerFrequency, int showStatistics = 0);
    219   void   ResetCalibration();
    220   bool   RecordCalibrationPoints(int chipNumber);
    221   bool   RecordCalibrationPointsV3(int chipNumber);
    222   bool   RecordCalibrationPointsV4(int chipNumber);
    223   bool   FitCalibrationPoints(int chipNumber);
    224   bool   FitCalibrationPointsV3(int chipNumber);
    225   bool   FitCalibrationPointsV4(int chipNumber);
    226   bool   OffsetCalibration(int chipNumber);
    227   double GetTemperature(unsigned int chipIndex);
    228  
    229   bool   WriteCalibration(unsigned int chipIndex);
    230   bool   WriteCalibrationV3(unsigned int chipIndex);
    231   bool   WriteCalibrationV4(unsigned int chipIndex);
    232   bool   ReadCalibration(unsigned int chipIndex);
    233   bool   ReadCalibrationV3(unsigned int chipIndex);
    234   bool   ReadCalibrationV4(unsigned int chipIndex);
    235   bool   Calibrate(unsigned int chipIndex, unsigned int channel, float *adcWaveform,
    236                    float *uWaveform, float threshold);
    237   bool   Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform,
    238                    int triggerCell, float threshold);
    239   bool   SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform,
    240                            unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel);
    241   bool   IsRead(int chipIndex) const { return fCalibrationValid[chipIndex]; }
    242   double GetPrecision() const { return fPrecision; };
    243  
    244   double GetOffsetAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fOffset[bin]; };
    245   double GetGainAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fGain[bin]; };
    246   double GetMeasPointXAt(int ip) const { return fXXSave[ip]; };
    247   double GetMeasPointYAt(int ip) const { return fYYSave[ip]; };
    248  
    249  protected:
    250   void   InitFields(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, int numberOfSamples,
    251                     int numberOfGridPoints, int numberOfXConstPoints, int numberOfXConstGridPoints,
    252                     double triggerFrequency, int showStatistics);
    253   void   DeleteFields();
    254   void   CalibrationTrigger(int mode, double voltage);
    255   void   CalibrationStart(double voltage);
    256  
    257   static float  GetValue(float *coefficients, float u, int n);
    258   static int    Approx(float *p, float *uu, int np, int nu, float *coef);
    259   static void   LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt);
    260   static int    LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n);
    261   static void   Housholder(int lpivot, int l1, int m, float **u, int iU1, int iU2, float *up, float **c, int iC1,
    262                            int iC2, int ice, int ncv);
    263  
    264   static int    MakeDir(const char *path);
    265   static void   Average(int method,float *samples,int numberOfSamples,float &mean,float &error,float sigmaBoundary);
     194protected:
     195
     196   class CalibrationData {
     197   public:
     198      class CalibrationDataChannel {
     199      public:
     200         unsigned char   fLimitGroup[kNumberOfBins];           //!
     201         float           fMin[kNumberOfBins];                  //!
     202         float           fRange[kNumberOfBins];                //!
     203         short           fOffset[kNumberOfBins];               //!
     204         short           fGain[kNumberOfBins];                 //!
     205         unsigned short  fOffsetADC[kNumberOfBins];            //!
     206         short          *fData[kNumberOfBins];                 //!
     207         unsigned char  *fLookUp[kNumberOfBins];               //!
     208         unsigned short  fLookUpOffset[kNumberOfBins];         //!
     209         unsigned char   fNumberOfLookUpPoints[kNumberOfBins]; //!
     210         float          *fTempData;                            //!
     211
     212      private:
     213         CalibrationDataChannel(const CalibrationDataChannel &c);              // not implemented
     214         CalibrationDataChannel &operator=(const CalibrationDataChannel &rhs); // not implemented
     215
     216      public:
     217         CalibrationDataChannel(int numberOfGridPoints)
     218         :fTempData(new float[numberOfGridPoints]) {
     219            int i;
     220            for (i = 0; i < kNumberOfBins; i++) {
     221               fData[i] = new short[numberOfGridPoints];
     222            }
     223            memset(fLimitGroup,           0, sizeof(fLimitGroup));
     224            memset(fMin,                  0, sizeof(fMin));
     225            memset(fRange,                0, sizeof(fRange));
     226            memset(fOffset,               0, sizeof(fOffset));
     227            memset(fGain,                 0, sizeof(fGain));
     228            memset(fOffsetADC,            0, sizeof(fOffsetADC));
     229            memset(fLookUp,               0, sizeof(fLookUp));
     230            memset(fLookUpOffset,         0, sizeof(fLookUpOffset));
     231            memset(fNumberOfLookUpPoints, 0, sizeof(fNumberOfLookUpPoints));
     232         }
     233         ~CalibrationDataChannel() {
     234            int i;
     235            delete fTempData;
     236            for (i = 0; i < kNumberOfBins; i++) {
     237               delete fData[i];
     238               delete fLookUp[i];
     239            }
     240         }
     241      };
     242
     243      bool                    fRead;                                  //!
     244      CalibrationDataChannel *fChannel[10];                           //!
     245      unsigned char           fNumberOfGridPoints;                    //!
     246      int                     fHasOffsetCalibration;                  //!
     247      float                   fStartTemperature;                      //!
     248      float                   fEndTemperature;                        //!
     249      int                    *fBSplineOffsetLookUp[kNumberOfADCBins]; //!
     250      float                 **fBSplineLookUp[kNumberOfADCBins];       //!
     251      float                   fMin;                                   //!
     252      float                   fMax;                                   //!
     253      unsigned char           fNumberOfLimitGroups;                   //!
     254      static float            fIntRevers[2 * kBSplineOrder - 2];
     255
     256   private:
     257      CalibrationData(const CalibrationData &c);              // not implemented
     258      CalibrationData &operator=(const CalibrationData &rhs); // not implemented
     259
     260   public:
     261      CalibrationData(int numberOfGridPoints);
     262      ~CalibrationData();
     263      static int CalculateBSpline(int nGrid, float value, float *bsplines);
     264      void       PreCalculateBSpline();
     265      void       DeletePreCalculatedBSpline();
     266   };
     267
     268   // General Fields
     269   DRSBoard        *fBoard;
     270
     271   double           fPrecision;
     272
     273   // Fields for creating the Calibration
     274   bool             fInitialized;
     275   bool             fRecorded;
     276   bool             fFitted;
     277   bool             fOffset;
     278   bool             fCalibrationValid[2];
     279
     280   int              fNumberOfPointsLowVolt;
     281   int              fNumberOfPoints;
     282   int              fNumberOfMode2Bins;
     283   int              fNumberOfSamples;
     284   int              fNumberOfGridPoints;
     285   int              fNumberOfXConstPoints;
     286   int              fNumberOfXConstGridPoints;
     287   double           fTriggerFrequency;
     288   int              fShowStatistics;
     289   FILE            *fCalibFile;
     290
     291   int              fCurrentLowVoltPoint;
     292   int              fCurrentPoint;
     293   int              fCurrentSample;
     294   int              fCurrentFitChannel;
     295   int              fCurrentFitBin;
     296
     297   float           *fResponseX[10][kNumberOfBins];
     298   float           *fResponseY;
     299   unsigned short **fWaveFormMode3[10];
     300   unsigned short **fWaveFormMode2[10];
     301   short          **fWaveFormOffset[10];
     302   unsigned short **fWaveFormOffsetADC[10];
     303   unsigned short  *fSamples;
     304   int             *fSampleUsed;
     305
     306   float           *fPntX[2];
     307   float           *fPntY[2];
     308   float           *fUValues[2];
     309   float           *fRes[kNumberOfBins];
     310   float           *fResX[kNumberOfBins];
     311
     312   double          *fXXFit;
     313   double          *fYYFit;
     314   double          *fWWFit;
     315   double          *fYYFitRes;
     316   double          *fYYSave;
     317   double          *fXXSave;
     318   double          fGainMin;
     319   double          fGainMax;
     320
     321   float          **fStatisticsApprox;
     322   float          **fStatisticsApproxExt;
     323
     324   // Fields for applying the Calibration
     325   CalibrationData *fCalibrationData[kNumberOfChipsMax];
     326
     327private:
     328         ResponseCalibration(const ResponseCalibration &c);              // not implemented
     329         ResponseCalibration &operator=(const ResponseCalibration &rhs); // not implemented
     330
     331public:
     332   ResponseCalibration(DRSBoard* board);
     333   ~ResponseCalibration();
     334
     335   void   SetCalibrationParameters(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins,
     336                                   int numberOfSamples, int numberOfGridPoints, int numberOfXConstPoints,
     337                                   int numberOfXConstGridPoints, double triggerFrequency, int showStatistics = 0);
     338   void   ResetCalibration();
     339   bool   RecordCalibrationPoints(int chipNumber);
     340   bool   RecordCalibrationPointsV3(int chipNumber);
     341   bool   RecordCalibrationPointsV4(int chipNumber);
     342   bool   FitCalibrationPoints(int chipNumber);
     343   bool   FitCalibrationPointsV3(int chipNumber);
     344   bool   FitCalibrationPointsV4(int chipNumber);
     345   bool   OffsetCalibration(int chipNumber);
     346   bool   OffsetCalibrationV3(int chipNumber);
     347   bool   OffsetCalibrationV4(int chipNumber);
     348   double GetTemperature(unsigned int chipIndex);
     349
     350   bool   WriteCalibration(unsigned int chipIndex);
     351   bool   WriteCalibrationV3(unsigned int chipIndex);
     352   bool   WriteCalibrationV4(unsigned int chipIndex);
     353   bool   ReadCalibration(unsigned int chipIndex);
     354   bool   ReadCalibrationV3(unsigned int chipIndex);
     355   bool   ReadCalibrationV4(unsigned int chipIndex);
     356   bool   Calibrate(unsigned int chipIndex, unsigned int channel, float *adcWaveform,
     357                    float *uWaveform, float threshold, bool offsetCalib);
     358   bool   Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform,
     359                    int triggerCell, float threshold, bool offsetCalib);
     360   bool   SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform,
     361                            unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel);
     362   bool   IsRead(int chipIndex) const { return fCalibrationValid[chipIndex]; }
     363   double GetPrecision() const { return fPrecision; };
     364
     365   double GetOffsetAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fOffset[bin]; };
     366   double GetGainAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fGain[bin]; };
     367   double GetMeasPointXAt(int ip) const { return fXXSave[ip]; };
     368   double GetMeasPointYAt(int ip) const { return fYYSave[ip]; };
     369
     370protected:
     371   void   InitFields(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, int numberOfSamples,
     372                     int numberOfGridPoints, int numberOfXConstPoints, int numberOfXConstGridPoints,
     373                     double triggerFrequency, int showStatistics);
     374   void   DeleteFields();
     375   void   CalibrationTrigger(int mode, double voltage);
     376   void   CalibrationStart(double voltage);
     377
     378   static float  GetValue(float *coefficients, float u, int n);
     379   static int    Approx(float *p, float *uu, int np, int nu, float *coef);
     380   static void   LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt);
     381   static int    LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n);
     382   static void   Housholder(int lpivot, int l1, int m, float **u, int iU1, int iU2, float *up, float **c, int iC1,
     383                            int iC2, int ice, int ncv);
     384
     385   static int    MakeDir(const char *path);
     386   static void   Average(int method,float *samples,int numberOfSamples,float &mean,float &error,float sigmaBoundary);
    266387};
    267388
    268389
    269 
    270390class DRSBoard {
    271  protected:
    272   class TimeData {
    273   public:
    274     class FrequencyData {
    275     public:
    276       int    fFrequency;
    277       double fBin[kNumberOfBins];
    278     };
    279    
    280     enum {
    281       kMaxNumberOfFrequencies = 4000
    282     };
    283     int            fChip;
    284     int            fNumberOfFrequencies;
    285     FrequencyData *fFrequency[kMaxNumberOfFrequencies];
    286    
    287   private:
    288     TimeData(const TimeData &c);              // Not implemented
    289     TimeData &operator=(const TimeData &rhs); // Not implemented
    290    
    291   public:
    292     TimeData()
     391protected:
     392   class TimeData {
     393   public:
     394      class FrequencyData {
     395      public:
     396         int    fFrequency;
     397         double fBin[kNumberOfBins];
     398      };
     399
     400      enum {
     401         kMaxNumberOfFrequencies = 4000
     402      };
     403      int            fChip;
     404      int            fNumberOfFrequencies;
     405      FrequencyData *fFrequency[kMaxNumberOfFrequencies];
     406
     407   private:
     408      TimeData(const TimeData &c);              // not implemented
     409      TimeData &operator=(const TimeData &rhs); // not implemented
     410
     411   public:
     412      TimeData()
    293413      :fChip(0)
    294414      ,fNumberOfFrequencies(0) {
    295     }
    296     ~TimeData() {
    297       int i;
    298       for (i = 0; i < fNumberOfFrequencies; i++) {
    299         delete fFrequency[i];
    300415      }
    301     }
    302   };
    303  
    304  public:
    305   // DAC channels (CMC Version 1 : DAC_COFSA,DAC_COFSB,DAC_DRA,DAC_DSA,DAC_TLEVEL,DAC_ACALIB,DAC_DSB,DAC_DRB)
    306   unsigned int         fDAC_COFSA;
    307   unsigned int         fDAC_COFSB;
    308   unsigned int         fDAC_DRA;
    309   unsigned int         fDAC_DSA;
    310   unsigned int         fDAC_TLEVEL;
    311   unsigned int         fDAC_ACALIB;
    312   unsigned int         fDAC_DSB;
    313   unsigned int         fDAC_DRB;
    314   // DAC channels (CMC Version 2+3 : DAC_COFS,DAC_DSA,DAC_DSB,DAC_TLEVEL,DAC_ADCOFS,DAC_CLKOFS,DAC_ACALIB)
    315   unsigned int         fDAC_COFS;
    316   unsigned int         fDAC_ADCOFS;
    317   unsigned int         fDAC_CLKOFS;
    318   // DAC channels (CMC Version 4 : DAC_ROFS_1,DAC_DSA,DAC_DSB,DAC_ROFS_2,DAC_ADCOFS,DAC_ACALIB,DAC_INOFS,DAC_BIAS)
    319   unsigned int         fDAC_ROFS_1;
    320   unsigned int         fDAC_ROFS_2;
    321   unsigned int         fDAC_INOFS;
    322   unsigned int         fDAC_BIAS;
    323    
    324  private:
     416      ~TimeData() {
     417         int i;
     418         for (i = 0; i < fNumberOfFrequencies; i++) {
     419            delete fFrequency[i];
     420         }
     421      }
     422   };
     423
     424public:
     425   // DAC channels (CMC Version 1 : DAC_COFSA,DAC_COFSB,DAC_DRA,DAC_DSA,DAC_TLEVEL,DAC_ACALIB,DAC_DSB,DAC_DRB)
     426   unsigned int         fDAC_COFSA;
     427   unsigned int         fDAC_COFSB;
     428   unsigned int         fDAC_DRA;
     429   unsigned int         fDAC_DSA;
     430   unsigned int         fDAC_TLEVEL;
     431   unsigned int         fDAC_ACALIB;
     432   unsigned int         fDAC_DSB;
     433   unsigned int         fDAC_DRB;
     434   // DAC channels (CMC Version 2+3 : DAC_COFS,DAC_DSA,DAC_DSB,DAC_TLEVEL,DAC_ADCOFS,DAC_CLKOFS,DAC_ACALIB)
     435   unsigned int         fDAC_COFS;
     436   unsigned int         fDAC_ADCOFS;
     437   unsigned int         fDAC_CLKOFS;
     438   // DAC channels (CMC Version 4 : DAC_ROFS_1,DAC_DSA,DAC_DSB,DAC_ROFS_2,DAC_ADCOFS,DAC_ACALIB,DAC_INOFS,DAC_BIAS)
     439   unsigned int         fDAC_ROFS_1;
     440   unsigned int         fDAC_ROFS_2;
     441   unsigned int         fDAC_INOFS;
     442   unsigned int         fDAC_BIAS;
     443   // DAC channels (USB EVAL1 (Version 5) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS)
     444   unsigned int         fDAC_CMOFS;
     445   unsigned int         fDAC_CALN;
     446   unsigned int         fDAC_CALP;
     447   unsigned int         fDAC_ONOFS;
     448   // DAC channels (DRS4 MEZZ1 (Version 6) : DAC_ONOFS,DAC_CMOFSP,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_CMOFSN,DAC_ROFS_1)
     449   unsigned int         fDAC_CMOFSP;
     450   unsigned int         fDAC_CMOFSN;
     451
     452protected:
     453   // Fields for DRS
     454   int                  fDRSType;
     455   int                  fBoardType;
     456   int                  fNumberOfChips;
     457   int                  fNumberOfChannels;
     458   int                  fRequiredFirmwareVersion;
     459   int                  fFirmwareVersion;
     460   int                  fBoardSerialNumber;
     461   unsigned int         fTransport;
     462   unsigned int         fCtrlBits;
     463   int                  fNumberOfReadoutChannels;
     464   int                  fReadoutChannelConfig;
     465   int                  fADCClkPhase;
     466   bool                 fADCClkInvert;
     467   double               fExternalClockFrequency;
     468#ifdef HAVE_USB
     469   MUSB_INTERFACE      *fUsbInterface;
     470#endif
     471#ifdef HAVE_VME
     472   MVME_INTERFACE      *fVmeInterface;
     473   mvme_addr_t          fBaseAddress;
     474#endif
    325475#ifdef CT_VME
    326476  VME_ErrorCode_t          ErrorCode;
     
    342492  int          FreeSegmentCMEM(int CMEM_SegIdentifier);
    343493#endif
    344 #ifdef STRUCK_VME
    345   mvme_addr_t          fBaseAddress;
    346   MVME_INTERFACE      *fVMEInterface;
    347 #endif
    348 
    349  protected:
    350   // Fields for DRS
    351   int                  fRequiredFirmwareVersion;
    352   int                  fFirmwareVersion;
    353   int                  fChipVersion;
    354   int                  fBoardVersion;
    355   int                  fCMCSerialNumber;
    356   unsigned int         fTransport;
    357   unsigned int         fCtrlBits;
    358   int                  fNumberOfReadoutChannels;
    359   double               fExternalClockFrequency;
    360 
    361   int                  fSlotNumber;
    362   double               fFrequency;
    363   int                  fDominoMode;
    364   int                  fReadoutMode;
    365   int                  fTriggerEnable;
    366   int                  fDelayedStart;
    367   int                  fTriggerCell; 
    368   unsigned char        fWaveforms[kNumberOfChips * kNumberOfChannels * 2 * kNumberOfBins];
    369  
    370   // Fields for Calibration
    371   int                  fMaxChips;
    372   char                 fCalibDirectory[1000];
    373  
    374   // Fields for Response Calibration
    375   ResponseCalibration *fResponseCalibration;
    376  
    377   // Fields for Time Calibration
    378   TimeData           **fTimeData;
    379   int                  fNumberOfTimeData;
    380  
    381   // General debugging flag
    382   int                  fDebug;
    383  
    384   // Fields for wave transfer
    385   bool                 fWaveTransferred[kNumberOfChips * kNumberOfChannels];
    386  
    387   // Waveform Rotation
    388   int                  fTriggerStartBin; // Start bin of the trigger
    389   bool                 kRotateWave;
    390 
    391  public:
    392   ~DRSBoard();
    393  
    394   void         SetCMCSerialNumber(unsigned int serialNumber) { fCMCSerialNumber = serialNumber; }
    395   int          GetCMCSerialNumber() const { return fCMCSerialNumber; }
    396   int          GetFirmwareVersion() const { return fFirmwareVersion; }
    397   int          GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; }
    398   int          GetChipVersion() const { return fChipVersion; }
    399   int          GetCMCVersion() const { return fBoardVersion; }
    400  
    401   // VME
    402   int          GetSlotNumber() const { return fSlotNumber; }
    403   int          Read(int type, void *data, unsigned int addr, int size);
    404   int          Write(int type, unsigned int addr, void *data, int size);
    405 
    406   void         RegisterTest(void);
    407   int          RAMTest(int flag);
    408   unsigned int GetCtrlReg(void);
    409   unsigned int GetStatusReg(void);
    410  
    411   void         SetLED(int state);
    412  
    413   void         SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels);
    414   void         SetNumberOfChannels(int nChannels);
    415   int          EnableTrigger(int mode);
    416   int          SetDelayedStart(int flag);
    417   int          IsBusy(void);
    418   int          IsNewFreq(unsigned char chipIndex);
    419   int          SetDAC(unsigned char channel, double value);
    420   int          ReadDAC(unsigned char channel, double *value);
    421   int          GetRegulationDAC(double *value);
    422  
    423   int          StartDomino();
    424   int          Reinit();
    425   int          Init();
    426  
    427   void         SetDebug(int debug) { fDebug = debug; }
    428  
    429   int          SetDominoMode(unsigned char mode);
    430  
    431   int          SetDominoActive(unsigned char mode);
    432   int          SetReadoutMode(unsigned char mode);
    433  
    434   int          SoftTrigger(void);
    435   int          ReadFrequency(unsigned char chipIndex, double *f);
    436   int          SetFrequency(double freq);
    437   double       VoltToFreq(double volt);
    438   double       FreqToVolt(double freq);
    439   double       GetFrequency() const { return fFrequency; }
    440  
    441   int          RegulateFrequency(double freq);
    442   int          SetExternalClockFrequency(double frequencyMHz);
    443   double       GetExternalClockFrequency();
    444  
    445   void         SetVoltageOffset(double offset1, double offset2);
    446 
    447 
    448   int          TestRead(unsigned int n, int type);
    449  
    450   int          TransferWaves(int numberOfChannels = kNumberOfChips * kNumberOfChannels);
    451   int          TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChips * kNumberOfChannels);
    452   int          TransferWaves(unsigned char *p, int firstChannel, int lastChannel);
    453   int          TransferWaves(int firstChannel, int lastChannel);
    454 
    455   int          DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
    456                           unsigned short *waveform);
    457   int          DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform);
    458 
    459   int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform,
    460                        bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
    461                        float threshold = 0);
    462   int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform,
    463                        bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
    464                        float threshold = 0);
    465   int          GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false,
    466                        int triggerCell = -1, bool adjustToClock = false, float threshold = 0);
    467   int          GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib = false,
    468                        int triggerCell = -1, bool adjustToClock = false, float threshold = 0);
    469   int          GetADCWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform);
    470   int          GetADCWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel,
    471                   unsigned short *waveform);
    472  
    473   void         RotateWave(int triggerCell, short *waveform); 
    474   void         RotateWave(int triggerCell, float *waveform); 
    475   void         SetRotation(bool r) {kRotateWave = r;}
    476 
    477   int          GetTime(unsigned int chipIndex, int frequencyMHz, float *time, int triggerCell);
    478   int          GetTriggerCell(unsigned int chipIndex);
    479   int          GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex);
    480   int          GetTriggerCell(float *waveform);
    481 
    482   void         TestDAC(int channel);
    483   void         MeasureSpeed();
    484   void         InteractSpeed();
    485   void         MonitorFrequency();
    486   int          EnableTcal(int flag);
    487   int          EnableAcal(int mode, double voltage);
    488   int          SetCalibVoltage(double value);
    489   int          SetCalibTiming(int t1, int t2);
    490   double       GetTemperature();
    491   int          GetTriggerBus();
    492   int          FlashEEPROM(unsigned short serial_cmc);
    493   bool         HasCorrectFirmware();
    494  
    495   bool         InitTimeCalibration(unsigned int chipIndex);
    496   void         SetCalibrationDirectory(const char *calibrationDirectoryPath);
    497   void         GetCalibrationDirectory(char *calibrationDirectoryPath);
    498  
    499   ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; }
    500  
    501   int          GetStoredTriggerCell() const { return fTriggerCell; }
    502   double       GetPrecision() const { return fResponseCalibration->GetPrecision(); }
    503   int          CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform,
    504                                  short *waveform, bool responseCalib, int triggerCell, bool adjustToClock,
    505                                  float threshold);
    506  
    507   static void  LinearRegression(double *x, double *y, int n, double *a, double *b);
    508  
    509  protected:
    510   void         ConstructBoard();
    511   void         ReadSerialNumber();
    512  
    513   TimeData    *GetTimeCalibration(unsigned int chipIndex, bool reinit = false); 
    514   int          GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period);
    515  
    516  public:
     494
     495   int                  fSlotNumber;
     496   double               fFrequency;
     497   double               fTCALFrequency;
     498   double               fRefClock;
     499   int                  fDominoMode;
     500   int                  fDominoActive;
     501   int                  fChannelConfig;
     502   int                  fWSRLoop;
     503   int                  fReadoutMode;
     504   int                  fTriggerEnable1;
     505   int                  fTriggerEnable2;
     506   int                  fTriggerSource;
     507   int                  fTriggerDelay;
     508   int                  fDelayedStart;
     509   int                  fTranspMode;
     510   unsigned short       fStopCell[4];
     511   double               fROFS;
     512   double               fRange;
     513   double               fCommonMode;
     514   int                  fAcalMode;
     515   int                  fbkAcalMode;
     516   double               fAcalVolt;
     517   double               fbkAcalVolt;
     518   int                  fTcalFreq;
     519   int                  fbkTcalFreq;
     520   int                  fTcalLevel;
     521   int                  fbkTcalLevel;
     522   int                  fTcalPhase;
     523   int                  fTcalSource;
     524
     525   unsigned char        fWaveforms[kNumberOfChipsMax * kNumberOfChannelsMax * 2 * kNumberOfBins];
     526
     527   // Fields for Calibration
     528   int                  fMaxChips;
     529   char                 fCalibDirectory[1000];
     530
     531   // Fields for Response Calibration old method
     532   ResponseCalibration *fResponseCalibration;
     533
     534   // Fields for Calibration new method
     535   bool                 fCellCalibrationValid;
     536   double               fCellCalibratedRange;
     537   unsigned short       fCellOffset[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins];
     538   unsigned short       fCellOffset2[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins];
     539   double               fCellGain[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins];
     540
     541   bool                 fTimingCalibrationValid;
     542   double               fTimingCalibratedFrequency;
     543   double               fCellT[kNumberOfChipsMax][kNumberOfBins];
     544   signed short         fCellDT[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins];
     545
     546   // Fields for Time Calibration
     547   TimeData           **fTimeData;
     548   int                  fNumberOfTimeData;
     549
     550   // General debugging flag
     551   int fDebug;
     552
     553   // Fields for wave transfer
     554   bool                 fWaveTransferred[kNumberOfChipsMax * kNumberOfChannelsMax];
     555
     556   // Waveform Rotation
     557   int                  fTriggerStartBin; // Start Bin of the trigger
     558
     559private:
     560   DRSBoard(const DRSBoard &c);              // not implemented
     561   DRSBoard &operator=(const DRSBoard &rhs); // not implemented
     562
     563public:
     564   // Public Methods
     565#ifdef HAVE_USB
     566   DRSBoard(MUSB_INTERFACE * musb_interface, int usb_slot);
     567#endif
     568#ifdef HAVE_VME
     569   DRSBoard(MVME_INTERFACE * mvme_interface, mvme_addr_t base_address, int slot_number);
     570
     571   MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; };
     572#endif
    517573#ifdef CT_VME
    518574  DRSBoard(int MasterMapping, unsigned int BaseAddress, unsigned int BoardAddress, int SlotNumber);
    519575#endif
    520 #ifdef STRUCK_VME
    521   DRSBoard(MVME_INTERFACE * MVME_Interface, mvme_addr_t BaseAddress, int SlotNumber);
    522   MVME_INTERFACE *GetVMEInterface() const { return fVMEInterface; };
    523 #endif
    524 
    525   void PrintBinary32(unsigned int i);
    526   long int GetMicroSeconds();
    527  
     576
     577   ~DRSBoard();
     578
     579   int          SetBoardSerialNumber(unsigned short serialNumber);
     580   int          GetBoardSerialNumber() const { return fBoardSerialNumber; }
     581   int          GetFirmwareVersion() const { return fFirmwareVersion; }
     582   int          GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; }
     583   int          GetDRSType() const { return fDRSType; }
     584   int          GetBoardType() const { return fBoardType; }
     585   int          GetNumberOfChips() const { return fNumberOfChips; }
     586   int          GetNumberOfChannels() const { return fNumberOfChannels; }
     587   int          GetSlotNumber() const { return fSlotNumber; }
     588   int          InitFPGA(void);
     589   int          Write(int type, unsigned int addr, void *data, int size);
     590   int          Read(int type, void *data, unsigned int addr, int size);
     591   int          GetTransport() const { return fTransport; }
     592   void         RegisterTest(void);
     593   int          RAMTest(int flag);
     594   int          ChipTest();
     595   unsigned int GetCtrlReg(void);
     596   unsigned short GetConfigReg(void);
     597   unsigned int GetStatusReg(void);
     598   void         SetLED(int state);
     599   void         SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels);
     600   void         SetADCClkPhase(int phase, bool invert);
     601   void         SetWarmup(unsigned int ticks);
     602   void         SetCooldown(unsigned int ticks);
     603   int          GetReadoutChannelConfig() { return fReadoutChannelConfig; }
     604   void         SetNumberOfChannels(int nChannels);
     605   int          EnableTrigger(int flag1, int flag2);
     606   int          GetTriggerEnable(int i) { return i?fTriggerEnable2:fTriggerEnable1; }
     607   int          SetDelayedTrigger(int flag);
     608   int          SetTriggerDelay(int delay);
     609   int          GetTriggerDelay() { return fTriggerDelay; }
     610   int          SetTriggerLevel(double value, bool negative);
     611   int          SetTriggerSource(int source);
     612   int          GetTriggerSource() { return fTriggerSource; }
     613   int          SetDelayedStart(int flag);
     614   int          SetTranspMode(int flag);
     615   int          SetStandbyMode(int flag);
     616   int          IsBusy(void);
     617   int          IsPLLLocked(void);
     618   int          IsLMKLocked(void);
     619   int          IsNewFreq(unsigned char chipIndex);
     620   int          SetDAC(unsigned char channel, double value);
     621   int          ReadDAC(unsigned char channel, double *value);
     622   int          GetRegulationDAC(double *value);
     623   int          StartDomino();
     624   int          StartClearCycle();
     625   int          FinishClearCycle();
     626   int          Reinit();
     627   int          Init();
     628   void         SetDebug(int debug) { fDebug = debug; }
     629   int          Debug() { return fDebug; }
     630   int          SetDominoMode(unsigned char mode);
     631   int          SetDominoActive(unsigned char mode);
     632   int          SetReadoutMode(unsigned char mode);
     633   int          SoftTrigger(void);
     634   int          ReadFrequency(unsigned char chipIndex, double *f);
     635   int          SetFrequency(double freq, bool wait);
     636   double       VoltToFreq(double volt);
     637   double       FreqToVolt(double freq);
     638   double       GetFrequency() const { return fFrequency; }
     639   int          RegulateFrequency(double freq);
     640   int          SetExternalClockFrequency(double frequencyMHz);
     641   double       GetExternalClockFrequency();
     642   void         SetVoltageOffset(double offset1, double offset2);
     643   int          SetInputRange(double center);
     644   double       GetInputRange(void) { return fRange; }
     645   double       GetCalibratedInputRange(void) { return fCellCalibratedRange; }
     646   double       GetCalibratedFrequency(void) { return fTimingCalibratedFrequency; }
     647   int          TransferWaves(int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax);
     648   int          TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax);
     649   int          TransferWaves(int firstChannel, int lastChannel);
     650   int          TransferWaves(unsigned char *p, int firstChannel, int lastChannel);
     651   int          DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel,
     652                           unsigned short *waveform);
     653   int          DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform);
     654   int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform,
     655                        bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
     656                        float threshold = 0, bool offsetCalib = true);
     657   int          GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform,
     658                        bool responseCalib = false, int triggerCell = -1, bool adjustToClock = false,
     659                        float threshold = 0, bool offsetCalib = true);
     660   int          GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false,
     661                        int triggerCell = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true);
     662   int          GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib,
     663                        int triggerCell = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true);
     664   int          GetWave(unsigned int chipIndex, unsigned char channel, float *waveform);
     665   int          GetRawWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform, bool adjustToClock = false);
     666   int          GetRawWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel,
     667                           unsigned short *waveform, bool adjustToClock = false);
     668   int          GetTime(unsigned int chipIndex, double freq, float *time, bool tcalibrated=true, bool rotated=true);
     669   int          GetTime(unsigned int chipIndex, float *time, bool tcalibrated=true, bool rotated=true);
     670   int          GetTriggerCell(unsigned int chipIndex);
     671   int          GetStopCell(unsigned int chipIndex);
     672   int          GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex);
     673   void         TestDAC(int channel);
     674   void         MeasureSpeed();
     675   void         InteractSpeed();
     676   void         MonitorFrequency();
     677   int          TestShift(int n);
     678   int          EnableAcal(int mode, double voltage);
     679   int          GetAcalMode() { return fAcalMode; }
     680   double       GetAcalVolt() { return fAcalVolt; }
     681   int          EnableTcal(int freq, int level=0, int phase=0);
     682   int          SelectClockSource(int source);
     683   int          SetRefclk(int source);
     684   int          GetTcalFreq() { return fTcalFreq; }
     685   int          GetTcalLevel() { return fTcalLevel; }
     686   int          GetTcalPhase() { return fTcalPhase; }
     687   int          GetTcalSource() { return fTcalSource; }
     688   int          SetCalibVoltage(double value);
     689   int          SetCalibTiming(int t1, int t2);
     690   double       GetTemperature();
     691   int          GetTriggerBus();
     692   int          ReadEEPROM(unsigned short page, void *buffer, int size);
     693   int          WriteEEPROM(unsigned short page, void *buffer, int size);
     694   bool         HasCorrectFirmware();
     695   int          ConfigureLMK(double sampFreq, bool freqChange, int calFreq, int calPhase);
     696
     697   bool         InitTimeCalibration(unsigned int chipIndex);
     698   void         SetCalibrationDirectory(const char *calibrationDirectoryPath);
     699   void         GetCalibrationDirectory(char *calibrationDirectoryPath);
     700
     701   ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; }
     702
     703   double       GetPrecision() const { return fResponseCalibration ? fResponseCalibration->GetPrecision() : 0.1; }
     704   int          CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform,
     705                                  short *waveform, bool responseCalib, int triggerCell, bool adjustToClock,
     706                                  float threshold, bool offsetCalib);
     707
     708   static void  LinearRegression(double *x, double *y, int n, double *a, double *b);
     709   
     710   void         ReadSingleWaveform(int nChips, int nChan,
     711                                  unsigned short wfu[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins], bool rotated);
     712   int          AverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated);
     713   int          RobustAverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated);
     714   int          CalibrateVolt(DRSCallback *pcb);
     715   int          AnalyzeWF(int nIter, float wf[kNumberOfBins], int tCell, double cellT[kNumberOfBins]);
     716   int          CalibrateTiming(DRSCallback *pcb);
     717   bool         IsCalibrationValid() { return fCellCalibrationValid; }
     718   bool         IsTimingCalibrationValid() { return fTimingCalibrationValid; }
     719   static void  RemoveSymmetricSpikes(short **wf, int nwf,
     720                                      short diffThreshold, int spikeWidth,
     721                                      short maxPeakToPeak, short spikeVoltage,
     722                                      int nTimeRegionThreshold);
     723protected:
     724   // Protected Methods
     725   void         ConstructBoard();
     726   void         ReadSerialNumber();
     727   void         ReadCalibration(void);
     728
     729   TimeData    *GetTimeCalibration(unsigned int chipIndex, bool reinit = false);
     730
     731   int          GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period);
    528732};
    529733
    530 
    531 
    532734class DRS {
    533  
    534  protected:
    535   enum {
    536     kMaxNumberOfBoards = 40
    537   };
    538  
    539  protected:
    540  
    541   DRSBoard        *fBoard[kMaxNumberOfBoards];
    542   int              fNumberOfBoards;
    543  
    544 #ifdef STRUCK_VME
    545   MVME_INTERFACE *fVMEInterface;
    546 #endif
    547  
    548  private:
    549   DRS(const DRS &c);              // Not implemented
    550   DRS &operator=(const DRS &rhs); // Not implemented
    551  
     735protected:
     736   // constants
     737   enum {
     738      kMaxNumberOfBoards = 40
     739   };
     740
     741protected:
     742   DRSBoard       *fBoard[kMaxNumberOfBoards];
     743   int             fNumberOfBoards;
     744   char            fError[256];
     745#ifdef HAVE_VME
     746   MVME_INTERFACE *fVmeInterface;
     747#endif
     748
     749private:
     750   DRS(const DRS &c);              // not implemented
     751   DRS &operator=(const DRS &rhs); // not implemented
     752
    552753#ifdef CT_VME
    553754  VME_MasterMap_t  MasterMap;
     
    564765#endif
    565766
    566   int First_VME_Slot;
    567   int Last_VME_Slot; 
    568  
    569  public:
    570   // Public Methods
    571   DRS();
    572   ~DRS();
    573  
    574   DRSBoard        *GetBoard(int i) { return fBoard[i]; }
    575   DRSBoard       **GetBoards() { return fBoard; }
    576   int              GetNumberOfBoards() const { return fNumberOfBoards; }
    577 
    578 #ifdef STRUCK_VME
    579    MVME_INTERFACE *GetVMEInterface() const { return fVMEInterface; };
    580 #endif
    581 
    582   void             InitialScan();
    583   void             SetFirstVMESlot(int s) { First_VME_Slot = s; }
    584   void             SetLastVMESlot(int s) { Last_VME_Slot = s; }
    585   int              GetFirstVMESlot() { return First_VME_Slot; }
    586   int              GetLastVMESlot() { return Last_VME_Slot; }
     767public:
     768   // Public Methods
     769   DRS();
     770   ~DRS();
     771
     772   DRSBoard        *GetBoard(int i) { return fBoard[i]; }
     773   DRSBoard       **GetBoards() { return fBoard; }
     774   int              GetNumberOfBoards() const { return fNumberOfBoards; }
     775   bool             GetError(char *str, int size);
     776#ifdef HAVE_VME
     777   MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; };
     778#endif
    587779};
    588780
    589 #endif   // DRS_H
     781#endif                          // DRS_H
  • drsdaq/HVFeedback.cc

    r175 r176  
    2929
    3030  m = DAQClass;
    31   //fNumberOfChannels = m->fNumberOfChannels;
    32   //fNumberOfChips = m->fNumberOfChips;
    33   fNumberOfChannels = 10;
    34   fNumberOfChips = 2; 
    35  
     31
     32  fNumberOfChannels = m->fNumberOfChannels;
     33  fNumberOfChips = m->fNumberOfChips; 
     34
    3635  PixMap = new PixelMap(PIXMAP_LOCATION, false);
    3736
     
    117116          for (k=0; k<fNumberOfChannels; k++) {
    118117                for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) {
    119           Integral += (m->WaveForm[i][j][k][(fLedSignalSample+q+m->TriggerCell[i][j])%kNumberOfBins] - m->WaveForm[i][j][k][(fLedBaselineSample+q+m->TriggerCell[i][j])%kNumberOfBins])*m->drs->GetBoard(i)->GetPrecision();
     118          Integral += (m->WaveForm[i][j][k][(fLedSignalSample+q+m->TriggerCell[i][j])%kNumberOfBins] - m->WaveForm[i][j][k][(fLedBaselineSample+q+m->TriggerCell[i][j])%kNumberOfBins])*m->GetBoard(i)->GetPrecision();
    120119                }
    121120        Integral /= 2*fIntHalfWidth+1;
     
    283282//
    284283void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) {
     284
    285285  if(Board<m->NumBoards && Chip<fNumberOfChips && Channel<fNumberOfChannels) {
    286286    Target[Board][Chip][Channel] = TargetVal;
  • drsdaq/History.txt

    r175 r176  
    585816/12/2009  Removed automatic gain adaption in feedback (caused spikes in the correction)
    59599/3/2010        Feedback now depended on DIM for communication with bias server.
    60                         Started migration to DRS4 (last tested revision as daqct3 for DRS2 is 161).
     60                        Started migration to DRS4 (last tested revision as daqct3 for DRS2 is 161). DRS class will not run anymore with DRS2 FPGA firmware.
    6161                       
Note: See TracChangeset for help on using the changeset viewer.