- Timestamp:
- 03/10/10 10:34:59 (15 years ago)
- Location:
- drsdaq
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq/DAQReadout.cc
r114 r176 26 26 {"status", &DAQReadout::cmd_status, false, "[daq|drs]", "Show DAQ/DRS status information"}, 27 27 {"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"}, 29 30 {"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)"}, 34 36 {"read", &DAQReadout::cmd_read, false, "<brd chip chan> [res]", "Read current data (and restart if DAQ not active)"}, 35 37 {"take", &DAQReadout::cmd_take, false, "<d|p|t> [n] [source]", "Start run (data, pedestal or test) with n events"}, … … 37 39 {"start", &DAQReadout::cmd_start, true, "", "Start DRS and DAQ without disk writing (feedback will be called)"}, 38 40 {"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)"},40 41 {"regtest", &DAQReadout::cmd_regtest, true, "", "DRS register test"}, 41 42 {"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"}, 42 45 {"led", &DAQReadout::cmd_led, true, "<on|off>", "Turn LED on or off"}, 43 46 {"config", &DAQReadout::cmd_config, false, "", "Print drsdaq configuration"}, … … 69 72 Socket = -1; 70 73 Exit = false; 71 CalibrationRead = false;72 74 NumEvents = 0; 73 75 NumEventsRequested = 0; … … 91 93 ConfigOK &= ReadCard("MaxLogLines", &fMaxLogLines, 'U', File); 92 94 ConfigOK &= ReadCard("RawDataPath", fRawDataPath, 's', File); 95 ConfigOK &= ReadCard("CalibDataPath", fCalibDataPath, 's', File); 93 96 ConfigOK &= ReadCard("FirstSample", &fFirstSample, 'I', File); 94 97 ConfigOK &= ReadCard("Samples", &fSamples, 'U', File); … … 96 99 ConfigOK &= ReadCard("MaxFileSizeMB", &fMaxFileSizeMB, 'I', File); 97 100 ConfigOK &= ReadCard("CCPort", &fCCPort, 'I', File); 98 ConfigOK &= ReadCard("FirstVMESlot", &fFirstVMESlot, 'I', File);99 ConfigOK &= ReadCard("LastVMESlot", &fLastVMESlot, 'I', File);100 101 ConfigOK &= ReadCard("HVFeedbackConfig", fHVFeedbackConfig, 's', File); 101 102 ConfigOK &= ReadCard("DefaultFrequency", &fDefaultFrequency , 'd', File); … … 109 110 } 110 111 111 // Truncate log file to given number of lines112 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 116 112 // Open log file and log configuration 117 113 if ((Logfile = fopen(fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", fLogFile); 118 114 PrintMessage(MsgToLog,"********** Logging started **********\n"); 119 115 PrintConfig(MsgToLog); 120 121 // Create DRS instance and perform initial scan122 drs = new DRS();123 drs->SetFirstVMESlot(fFirstVMESlot);124 drs->SetLastVMESlot(fLastVMESlot);125 drs->InitialScan();126 116 127 117 // Allocate headers and initialise to zero … … 132 122 133 123 // 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++) { 141 132 NumBoards++; 142 133 LastBoard++; 143 drs->GetBoard(i)->Init(); 144 drs->GetBoard(i)->SetRotation(false); 134 GetBoard(i)->Init(); 145 135 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 152 145 153 146 // Create instance of HV feedback (must be called after CMC board detection) … … 169 162 delete SlowDataClass; 170 163 delete RHeader; delete EHeader; 171 delete drs; delete HVFB; 164 delete HVFB; delete[] ACalibTemp; 165 delete[] ACalib; delete[] TCalib; 172 166 delete[] DRSFreq; delete[] BStruct; 173 167 delete[] WaveForm; delete[] TriggerCell; … … 232 226 void DAQReadout::cmd_take() { 233 227 228 // Check conditions if this is not a test run 234 229 if(!Match(Param[1],"test")) { 235 230 if (daq_state==active || NumBoards==0) { … … 237 232 return; 238 233 } 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 } 239 242 if (!IsDRSFreqSet()) { 240 243 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()) { 246 247 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 251 254 if (Match(Param[1],"data")) { 252 255 HWTrigger(1); … … 272 275 else snprintf(RHeader->Description,sizeof(RHeader->Description),"DUMMY"); 273 276 274 // Determine new run number using the file RUN_NUM_FILE277 // Determine new run number using the file given by RUN_NUM_FILE 275 278 FILE *RunNumFile = fopen(RUN_NUM_FILE,"r+"); 276 279 if(RunNumFile == NULL) { … … 318 321 } 319 322 323 // EEPROM test 324 void 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 320 342 // RAM test 321 343 void DAQReadout::cmd_ramtest() { 322 344 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); 325 347 } 326 348 } … … 329 351 void DAQReadout::cmd_regtest() { 330 352 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 359 void 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 } 354 365 355 366 // Stop DAQ … … 376 387 PrintUsage(); 377 388 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) { 380 393 PrintMessage("Error: Board number out of range\n"); 381 394 return; 382 395 } 383 if ( atoi(Param[3])<0 || atoi(Param[3])>=kNumberOfChannels) {396 if (Channel<0 || Channel>=GetBoard(Board)->GetNumberOfChannels()) { 384 397 PrintMessage("Error: Channel number out of range\n"); 385 398 return; 386 399 } 387 if ( atoi(Param[2])<0 || atoi(Param[2])>=kNumberOfChips) {400 if (Chip<0 || Chip>=GetBoard(Board)->GetNumberOfChips()) { 388 401 PrintMessage("Error: Chip number out of range\n"); 389 402 return; 390 403 } 391 392 if (daq_state !=active) {393 if (!CalibrationRead)ReadCalibration();404 405 if (daq_state != active) { 406 ReadCalibration(); 394 407 if(NParam==5) StopDRS(); 395 408 ReadCalibratedDRSData(); 396 409 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 } 401 423 PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==END=="); 402 424 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))); 403 427 } 404 428 405 429 // Set Domino mode 406 void DAQReadout::cmd_ mode() {430 void DAQReadout::cmd_dmode() { 407 431 if (Match(Param[1],"continuous")) SetDOMINOMode(1); 408 432 else if (Match(Param[1],"single")) SetDOMINOMode(0); … … 412 436 // Set Domino readout mode 413 437 void 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); 416 440 else PrintUsage(); 417 441 } … … 419 443 // Set Domino wave mode 420 444 void 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); 423 447 else PrintUsage(); 424 448 } 425 449 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 451 void 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 467 void 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 } 432 479 433 480 // Set trigger mode … … 447 494 else { 448 495 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])); 450 497 } 451 498 } … … 453 500 } 454 501 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 503 void DAQReadout::cmd_acalib() { 504 505 if (!IsDRSFreqSet()) { 506 PrintMessage("Set sampling frequency for all boards first\n"); 461 507 return; 462 508 } 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 552 void DAQReadout::cmd_tcalib() { 553 463 554 if (!IsDRSFreqSet()) { 464 PrintMessage("Set sampling frequency f irst\n");555 PrintMessage("Set sampling frequency for all boards first\n"); 465 556 return; 466 557 } 467 558 468 getcwd(str, sizeof(str));469 strcat(str,"/calib");470 471 559 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"); 496 613 } 497 614 … … 500 617 if (NParam>=2 && atof(Param[1])) { 501 618 SetDRSFrequency(atof(Param[1]), NParam==2 ? false : true); 502 CalibrationRead = false;503 619 } 504 620 else PrintUsage(); … … 509 625 if (Match(Param[1], "on") || Match(Param[1], "off")) 510 626 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); 512 628 else PrintUsage(); 513 629 } … … 528 644 " Disk space: %lu MByte\n" 529 645 " Socket state: %s\n" 530 " Total number of CMCboards: %d\n"531 " Active CMCboards: %d\n",646 " Total number of DRS boards: %d\n" 647 " Active DRS boards: %d\n", 532 648 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, 534 650 NumEventsRequested, fRawDataPath, 535 651 CheckDisk(fRawDataPath), Socket==-1 ? "disconnected":"connected", … … 545 661 for (int i=FirstBoard; i<=LastBoard; i++) { 546 662 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) 564 677 PrintMessage(" Domino wave running\n"); 565 if ( (drs->GetBoard(i))->GetStatusReg() & BIT_NEW_FREQ1)678 if (GetBoard(i)->GetStatusReg() & BIT_NEW_FREQ1) 566 679 PrintMessage(" New Freq1 ready\n"); 567 if ( (drs->GetBoard(i))->GetStatusReg() & BIT_NEW_FREQ2)680 if (GetBoard(i)->GetStatusReg() & BIT_NEW_FREQ2) 568 681 PrintMessage(" New Freq2 ready\n"); 569 682 570 PrintMessage(" Control reg.: 0 X%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) 572 685 PrintMessage(" AUTOSTART enabled\n"); 573 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_DMODE)686 if (GetBoard(i)->GetCtrlReg() & BIT_DMODE) 574 687 PrintMessage(" DMODE circular\n"); 575 688 else 576 689 PrintMessage(" DMODE single shot\n"); 577 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_LED)690 if (GetBoard(i)->GetCtrlReg() & BIT_LED) 578 691 PrintMessage(" LED\n"); 579 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_TCAL_EN)692 if (GetBoard(i)->GetCtrlReg() & BIT_TCAL_EN) 580 693 PrintMessage(" TCAL enabled\n"); 581 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_ZERO_SUPP)582 PrintMessage(" ZERO_SUPPenabled\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) 584 697 PrintMessage(" FREQ_AUTO_ADJ enabled\n"); 585 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_ENABLE_TRIGGER)698 if (GetBoard(i)->GetCtrlReg() & BIT_ENABLE_TRIGGER1) 586 699 PrintMessage(" ENABLE_TRIGGER\n"); 587 if ( (drs->GetBoard(i))->GetCtrlReg() & BIT_LONG_START_PULSE)700 if (GetBoard(i)->GetCtrlReg() & BIT_LONG_START_PULSE) 588 701 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) 592 703 PrintMessage(" ACAL enabled\n"); 593 PrintMessage(" Trigger bus: 0 X%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); 596 707 PrintMessage(" Frequency0: %1.4lf GHz\n", freq); 597 (drs->GetBoard(i))->ReadFrequency(1, &freq);708 GetBoard(i)->ReadFrequency(1, &freq); 598 709 PrintMessage(" Frequency1: %1.4lf GHz\n", freq); 599 710 } … … 609 720 if (Match(Param[1],"all")) { 610 721 FirstBoard = 0; 611 LastBoard = drs->GetNumberOfBoards()-1;722 LastBoard = GetNumberOfBoards()-1; 612 723 } 613 724 else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NumBoards) { … … 621 732 } 622 733 else PrintMessage("Cannot address board(s), out of range.\n"); 623 CalibrationRead = false;624 734 } 625 735 … … 677 787 else if(NParam!=5) PrintUsage(); 678 788 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++) 681 791 if ((atoi(Param[1])==i || Match(Param[1],"all")) && 682 792 (atoi(Param[2])==j || Match(Param[2],"all")) && … … 703 813 // Start domino wave 704 814 void 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(); 706 816 } 707 817 708 818 // Stop domino wave 709 819 void DAQReadout::StopDRS() { 710 for (int i=FirstBoard; i<=LastBoard; i++) drs->GetBoard(i)->SoftTrigger();711 } 712 713 // Transfer datato memory820 for (int i=FirstBoard; i<=LastBoard; i++) GetBoard(i)->SoftTrigger(); 821 } 822 823 // Transfer amplitude-calibrated waveforms to memory 714 824 void DAQReadout::ReadCalibratedDRSData() { 715 825 716 826 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 } 723 834 } 724 835 } … … 728 839 bool DAQReadout::ReadCalibration() { 729 840 730 char dir[MAX_COM_SIZE];731 732 getcwd(dir, sizeof(dir));733 strcat(dir,"/calib");734 841 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; 741 855 } 742 }743 CalibrationRead = true;856 } 857 } // Loop over boards 744 858 return true; 745 859 } … … 758 872 void DAQReadout::SetDOMINOMode(int mode) { 759 873 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 881 void 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 890 void 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 899 void DAQReadout::HWTrigger(int mode) { 900 760 901 if (NumBoards) 761 902 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); 807 904 PrintMessage("Hardware trigger of board %d %s\n",i,mode==1 ? "enabled":"disabled"); 808 905 } … … 813 910 void DAQReadout::SetDRSFrequency(double freq, bool Regulation) { 814 911 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 818 914 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, ¤tfreq); 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); 829 926 } 830 927 } … … 834 931 835 932 for (int i=FirstBoard; i<=LastBoard; i++) 836 if (( drs->GetBoard(i))->IsBusy()) return true;933 if ((GetBoard(i))->IsBusy()) return true; 837 934 return false; 838 935 } … … 842 939 843 940 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); 846 943 return false; 847 944 } … … 906 1003 907 1004 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(); 910 1007 RHeader->NBytes = sizeof(short); 911 1008 … … 919 1016 920 1017 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(); 923 1020 BStruct[i].NomFreq = DRSFreq[i]; 924 BStruct[i].ScaleFactor = drs->GetBoard(i)->GetPrecision();1021 BStruct[i].ScaleFactor = GetBoard(i)->GetPrecision(); 925 1022 } 926 1023 … … 990 1087 991 1088 // 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); 994 1091 Size += DataPart[Count-1].iov_len; 995 1092 … … 997 1094 for (int i=FirstBoard; (i<=LastBoard + (NumBoards==0)); i++) { 998 1095 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; 1000 1099 for (unsigned int l=0; l<RHeader->NChannels; l++) { 1001 1100 DataPart[Count].iov_base = &WaveForm[i][k][l][Start]; … … 1031 1130 "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n" 1032 1131 "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n" 1033 "FirstVMESlot: %d\t\tLastVMESlot: %d\n"1132 "CalibDataPath: %s\n" 1034 1133 "SlowDataPath: %s\tHVFeedbackConfig: %s\n", 1035 1134 fLogFile,fMaxLogLines,fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB, 1036 fMaxFileSizeMB,fCCPort,f FirstVMESlot,fLastVMESlot,fSlowDataPath,fHVFeedbackConfig);1135 fMaxFileSizeMB,fCCPort,fCalibDataPath,fSlowDataPath,fHVFeedbackConfig); 1037 1136 } 1038 1137 … … 1041 1140 PrintMessage("Usage: %s %s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters); 1042 1141 } 1043 1142 1143 // Print progress (used in DRS class) 1144 void DAQReadout::Progress(int Progress) { 1145 PrintMessage(MsgToConsole, "\rProgress: %d%% ", Progress); 1146 fflush(stdout); 1147 }; 1148 1044 1149 // Print message to selected target 1045 1150 void DAQReadout::PrintMessage(int Target, const char *Format, ...) { … … 1230 1335 else { 1231 1336 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++) 1233 1338 *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000); 1234 1339 } … … 1266 1371 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); 1267 1372 if(m->SlowDataClass->ErrorCode != 0) { 1268 m->PrintMessage("Error , could not write DAQdata 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)); 1269 1374 } 1270 1375 -
drsdaq/DAQReadout.h
r114 r176 7 7 #include <time.h> 8 8 #include <errno.h> 9 #include <unistd.h> 9 10 #include <sys/socket.h> 10 11 #include <pthread.h> … … 18 19 #include "HVFeedback.h" 19 20 20 #define RUN_NUM_FILE "/ ct3data/LastRunNumber"21 #define RUN_NUM_FILE "/home/ogrimm/Data/LastRunNumber" 21 22 22 23 #define MAX_PATH 256 // also used for filename length … … 31 32 enum runtype_enum {data, pedestal, reserved, test}; 32 33 33 class DAQReadout {34 class DAQReadout : public DRS, public DRSCallback { 34 35 time_t StartTime; 35 36 … … 40 41 FILE *Logfile; 41 42 void PrintUsage(); 42 bool CalibrationRead;43 43 44 44 public: … … 46 46 EventHeader* EHeader; 47 47 48 DRS *drs; 49 50 short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins]; 51 int (*TriggerCell)[kNumberOfChips]; 48 short (*WaveForm)[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; 49 int (*TriggerCell)[kNumberOfChipsMax]; 52 50 53 51 pthread_mutex_t control_mutex; … … 59 57 char fLogFile[MAX_PATH]; 60 58 char fSlowDataPath[MAX_PATH]; 59 char fCalibDataPath[MAX_PATH]; 61 60 unsigned int fMaxLogLines; 62 61 char fRawDataPath[MAX_PATH]; … … 66 65 unsigned int fSamples; 67 66 int fCCPort; 68 int fLastVMESlot;69 int fFirstVMESlot;70 67 char fHVFeedbackConfig[MAX_PATH]; 71 68 double fDefaultFrequency; … … 79 76 int LastBoard; 80 77 float *DRSFreq; // DRS sampling frequency [GHz] 78 bool *ACalib; 79 double *ACalibTemp; 80 bool *TCalib; 81 81 82 BoardStructure *BStruct; 82 83 state_enum daq_state; … … 97 98 ~DAQReadout(); 98 99 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(); 111 114 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(); 115 118 116 119 void CommandControl(char*); … … 136 139 bool UpdateRunHeader(unsigned int, bool); 137 140 bool WriteEvent(); 141 142 void Progress(int); 138 143 }; 139 144 -
drsdaq/DRS/DRS.cc
r132 r176 1 2 /********************************************************************\ 3 4 Name: DRS.cc 5 1 /******************************************************************** 2 3 Name: DRS.cpp 6 4 Created by: Stefan Ritt, Matthias Schneebeli 7 5 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 $ 16 9 17 10 \********************************************************************/ 18 11 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" 26 21 27 22 #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 30 24 #endif 31 25 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> 33 inline 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> 32 44 int drs_kbhit() 33 45 { 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 } 51 static inline int getch() 52 { 53 return getchar(); 54 } 55 #endif 56 57 #include <DRS.h> 58 59 #ifdef _MSC_VER 60 extern "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 -----*/ 70 const int REQUIRED_FIRMWARE_VERSION_DRS2 = 5268; 71 const int REQUIRED_FIRMWARE_VERSION_DRS3 = 6981; 72 const 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 */ 68 106 #define GEVPC_BASE_ADDR 0x00000000 69 107 #define GEVPC_WINSIZE 0x800000 … … 71 109 #define PMC1_OFFSET 0x00000 72 110 #define PMC2_OFFSET 0x80000 73 #define PMC_CTRL_OFFSET 0x00000 // All registers 32 bit!111 #define PMC_CTRL_OFFSET 0x00000 /* all registers 32 bit */ 74 112 #define PMC_STATUS_OFFSET 0x10000 75 113 #define PMC_FIFO_OFFSET 0x20000 76 114 #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 /*------------------------------------------------------------------*/ 117 138 118 139 using namespace std; 119 140 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) 143 unsigned char static *usb2_buffer = NULL; 124 144 #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 148 DRS::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 139 171 #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; 163 173 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 } 170 179 // 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; 175 181 MasterMap.address_modifier = VME_A32; 176 182 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 177 190 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); 268 201 #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; 370 209 #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 378 216 #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); 382 218 #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 399 233 #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); 402 242 #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); 405 253 #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 352 DRS::~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 447 370 #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"); 450 373 #endif 451 374 } … … 453 376 /*------------------------------------------------------------------*/ 454 377 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 378 bool 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 389 DRSBoard::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 463 DRSBoard::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 470 530 #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 533 DRSBoard::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 { 527 591 // Allocate contiguous memory for BLT 528 592 AllocateSegmentCMEM(MEM_SEGMENT,&CMEM_SegIdentifier); 529 if (DEBUG)530 printf("Memory segment %d (board #%d) allocated\n",CMEM_SegIdentifier,fCMCSerialNumber);531 532 593 AssignPhysicalSegAddressCMEM(CMEM_SegIdentifier, &PCIAddress); 533 594 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 } 536 597 #endif 537 598 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 601 DRSBoard::~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 626 void 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 745 void 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 819 void 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 962 bool DRSBoard::HasCorrectFirmware() 963 { 964 /* check for required firmware version */ 965 return (fFirmwareVersion >= fRequiredFirmwareVersion); 966 } 967 968 /*------------------------------------------------------------------*/ 969 970 int 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 999 int 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; 568 1005 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; 571 1010 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))); 610 1016 } 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); 615 1031 } 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); 690 1034 return 0; 691 1035 } 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; 732 1037 #endif 733 1038 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; 883 1223 } 884 1224 … … 887 1227 int DRSBoard::Read(int type, void *data, unsigned int addr, int size) 888 1228 { 889 890 // Generic read function 891 1229 // Generic read function 1230 892 1231 #ifdef CT_VME 893 894 1232 if (size > MEM_SEGMENT) size = MEM_SEGMENT; 895 1233 … … 898 1236 else if (type == T_RAM) addr += PMC_RAM_OFFSET; 899 1237 else if (type == T_FIFO) addr += PMC_FIFO_OFFSET; 900 1238 else return 0; 1239 901 1240 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)); 903 1242 } 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)); 905 1244 } 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)); 907 1246 } else { 908 1247 909 // Assign fields forBLT1248 // Assign fields and perform BLT 910 1249 BLT_List.list_of_items[0].vmebus_address = fBaseAddress + fBoardAddress + PMC_RAM_OFFSET; 911 1250 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; 913 1252 BLT_List.list_of_items[0].control_word = VME_DMA_D64R | VME_A32; 914 1253 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); 921 1255 922 1256 // Copy contiguous block of memory starting from VirtualAddress 923 memcpy(data, (void *) VirtualAddress ,size);1257 memcpy(data, (void *) VirtualAddress, size); 924 1258 } 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); 1693 1262 return 0; 1694 1263 } 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 1452 void 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 1464 void 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 1556 void DRSBoard::SetNumberOfChannels(int nChannels) 1557 { 1558 SetChannelConfig(0, nChannels - 1, 12); 1559 } 1560 1561 /*------------------------------------------------------------------*/ 1562 1563 void 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 1589 void 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 1608 void 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 1623 int 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 1642 int 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 1660 int 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 1678 int 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 1690 int 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 1704 int 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 1861 int 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 1890 int 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 1909 int 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 1928 int 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 1940 int 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 1962 int 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 1977 int 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 1997 int 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 2028 int 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 2048 int 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 2064 int 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 2080 int 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 2096 int 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 2107 int 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 2120 int 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 2133 int 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 2145 int 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 2185 double 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 2198 double 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 2211 int 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 2332 int 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 2483 int 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 2535 void 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 2580 int 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 2675 int 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 2806 void 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 2820 int 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 2845 int DRSBoard::SetExternalClockFrequency(double frequencyMHz) 2846 { 2847 // Set the frequency of the external clock 2848 fExternalClockFrequency = frequencyMHz; 2849 return 0; 2850 } 2851 2852 /*------------------------------------------------------------------*/ 2853 2854 double DRSBoard::GetExternalClockFrequency() 2855 { 2856 // Return the frequency of the external clock 2857 return fExternalClockFrequency; 2858 } 2859 2860 /*------------------------------------------------------------------*/ 2861 2862 int DRSBoard::TransferWaves(int numberOfChannels) 2863 { 2864 return TransferWaves(fWaveforms, numberOfChannels); 2865 } 2866 2867 /*------------------------------------------------------------------*/ 2868 2869 int DRSBoard::TransferWaves(unsigned char *p, int numberOfChannels) 2870 { 2871 return TransferWaves(p, 0, numberOfChannels - 1); 2872 } 2873 2874 /*------------------------------------------------------------------*/ 2875 2876 int 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 2890 int 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 } 1695 2950 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; 1722 2952 } 1723 2953 … … 1726 2956 int DRSBoard::DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform) 1727 2957 { 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 2963 int 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 3049 int DRSBoard::GetWave(unsigned int chipIndex, unsigned char channel, float *waveform) 3050 { 3051 return GetWave(chipIndex, channel, waveform, true, fStopCell[chipIndex], false, 0, true); 1772 3052 } 1773 3053 … … 1775 3055 1776 3056 int 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 3065 int 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 3089 int 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 3118 int 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 3133 int 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 3141 int 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; 1898 3159 } 1899 3160 … … 1902 3163 int DRSBoard::CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform, 1903 3164 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; 1929 3279 } 1930 3280 … … 1933 3283 int DRSBoard::GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period) 1934 3284 { 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]; 1949 3288 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; 1953 3303 } 1954 3304 … … 1957 3307 int DRSBoard::GetTriggerCell(unsigned int chipIndex) 1958 3308 { 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 3317 int 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 3361 int DRSBoard::GetStopCell(unsigned int chipIndex) 3362 { 3363 return fStopCell[chipIndex]; 2021 3364 } 2022 3365 … … 2025 3368 void DRSBoard::TestDAC(int channel) 2026 3369 { 2027 // Test DAC2028 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); 2044 3387 } 2045 3388 … … 2048 3391 void DRSBoard::MeasureSpeed() 2049 3392 { 2050 // Measure domino sampling speed2051 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 } 2080 3423 } 2081 3424 … … 2084 3427 void DRSBoard::InteractSpeed() 2085 3428 { 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 3459 void 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 { 2100 3472 Sleep(1000); 2101 3473 2102 3474 status = ReadFrequency(0, &freq); 2103 3475 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 3500 int 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; 2153 3528 } 2154 3529 … … 2157 3532 unsigned int DRSBoard::GetCtrlReg() 2158 3533 { 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 3542 unsigned short DRSBoard::GetConfigReg() 3543 { 3544 unsigned short status; 3545 3546 Read(T_CTRL, &status, REG_CONFIG, 2); 3547 return status; 2163 3548 } 2164 3549 … … 2167 3552 unsigned int DRSBoard::GetStatusReg() 2168 3553 { 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 3562 int 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 3593 int 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 3611 int 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; 2188 3622 } 2189 3623 … … 2192 3626 int DRSBoard::EnableAcal(int mode, double voltage) 2193 3627 { 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; 2246 3688 } 2247 3689 … … 2250 3692 int DRSBoard::SetCalibTiming(int t_enable, int t_cal) 2251 3693 { 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; 2265 3707 } 2266 3708 … … 2269 3711 int DRSBoard::SetCalibVoltage(double value) 2270 3712 { 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 3726 int 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 3747 int DRSBoard::FinishClearCycle() 3748 { 3749 while (IsBusy()); 3750 3751 /* restore old values */ 3752 EnableAcal(fbkAcalMode, fbkAcalVolt); 3753 3754 return 1; 2274 3755 } 2275 3756 … … 2278 3759 double DRSBoard::GetTemperature() 2279 3760 { 2280 // Read Out Temperature Sensor2281 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; 2291 3772 } 2292 3773 … … 2295 3776 int DRSBoard::GetTriggerBus() 2296 3777 { 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 3786 int 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 3839 int 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 3867 int 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 3901 int 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 3937 int 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; 2370 3979 } 2371 3980 … … 2374 3983 bool DRSBoard::InitTimeCalibration(unsigned int chipIndex) 2375 3984 { 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 3990 DRSBoard::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]; 2435 4045 } 2436 4046 … … 2439 4049 void DRSBoard::SetCalibrationDirectory(const char *calibrationDirectoryPath) 2440 4050 { 2441 strncpy(fCalibDirectory, calibrationDirectoryPath, strlen(calibrationDirectoryPath));2442 fCalibDirectory[strlen(calibrationDirectoryPath)] = 0;4051 strncpy(fCalibDirectory, calibrationDirectoryPath, strlen(calibrationDirectoryPath)); 4052 fCalibDirectory[strlen(calibrationDirectoryPath)] = 0; 2443 4053 }; 2444 4054 … … 2447 4057 void DRSBoard::GetCalibrationDirectory(char *calibrationDirectoryPath) 2448 4058 { 2449 strncpy(calibrationDirectoryPath, fCalibDirectory, strlen(fCalibDirectory));2450 calibrationDirectoryPath[strlen(fCalibDirectory)] = 0;4059 strncpy(calibrationDirectoryPath, fCalibDirectory, strlen(fCalibDirectory)); 4060 calibrationDirectoryPath[strlen(fCalibDirectory)] = 0; 2451 4061 }; 2452 4062 … … 2455 4065 void DRSBoard::LinearRegression(double *x, double *y, int n, double *a, double *b) 2456 4066 { 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 4084 void 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 4112 static unsigned short wfh[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins][WFH_SIZE]; 4113 static 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 }; 4128 static unsigned short swf[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; 4129 static unsigned short htmp[WFH_SIZE]; 4130 static float center[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; 4131 static int icenter[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; 4132 4133 int 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 4176 int 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 4307 int 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 4317 static 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 4322 int DRSBoard::CalibrateVolt(DRSCallback *pcb) 4323 { 4324 int i, j, nChan, timingChan=0, chip, config, p, clkon, refclk, trg1, trg2, n_stuck; 4325 double f, r; 4326 unsigned 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 4615 int DRSBoard::AnalyzeWF(int nIter, float wf[kNumberOfBins], int tCell, double cellT[kNumberOfBins]) 4616 { 4617 int i, i1, i2, j, k, nzx, zeroXing[1000], edge, n_correct; 4618 double 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 4753 int DRSBoard::CalibrateTiming(DRSCallback *pcb) 4754 { 4755 int index, status, tCell, i, c, chip, mode, nIter, clkon, phase, refclk, trg1, trg2; 4756 double f, range, t1[4], t2[4]; 4757 unsigned short buf[1024*4]; 4758 float 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 4933 void 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 } 2470 5134 } 2471 5135 … … 2478 5142 int showStatistics) 2479 5143 { 2480 DeleteFields();2481 InitFields(numberOfPointsLowVolt, numberOfPoints, numberOfMode2Bins, numberOfSamples, numberOfGridPoints,2482 5144 DeleteFields(); 5145 InitFields(numberOfPointsLowVolt, numberOfPoints, numberOfMode2Bins, numberOfSamples, numberOfGridPoints, 5146 numberOfXConstPoints, numberOfXConstGridPoints, triggerFrequency, showStatistics); 2483 5147 } 2484 5148 … … 2487 5151 void ResponseCalibration::ResetCalibration() 2488 5152 { 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; 2500 5164 }; 2501 5165 … … 2504 5168 bool ResponseCalibration::WriteCalibration(unsigned int chipIndex) 2505 5169 { 2506 if (!fOffset)2507 return false;2508 if (fBoard->GetChipVersion() == 3)2509 return WriteCalibrationV4(chipIndex);2510 else2511 return WriteCalibrationV3(chipIndex);5170 if (!fOffset) 5171 return false; 5172 if (fBoard->GetDRSType() == 3) 5173 return WriteCalibrationV4(chipIndex); 5174 else 5175 return WriteCalibrationV3(chipIndex); 2512 5176 } 2513 5177 … … 2516 5180 bool ResponseCalibration::WriteCalibrationV3(unsigned int chipIndex) 2517 5181 { 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 File2529 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 File2543 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 2560 }2561 for (k = 0; k < data->fNumberOfGridPoints; k++) {2562 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; 2572 5236 } 2573 5237 … … 2576 5240 bool ResponseCalibration::WriteCalibrationV4(unsigned int chipIndex) 2577 5241 { 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; 2614 5277 } 2615 5278 … … 2618 5281 void ResponseCalibration::CalibrationTrigger(int mode, double voltage) 2619 5282 { 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 } 2626 5289 } 2627 5290 … … 2630 5293 void ResponseCalibration::CalibrationStart(double voltage) 2631 5294 { 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(); 2638 5301 } 2639 5302 … … 2642 5305 bool ResponseCalibration::RecordCalibrationPoints(int chipNumber) 2643 5306 { 2644 if (!fInitialized)2645 return true;2646 if (fBoard->GetChipVersion() == 3)2647 return RecordCalibrationPointsV4(chipNumber);2648 else2649 return RecordCalibrationPointsV3(chipNumber);5307 if (!fInitialized) 5308 return true; 5309 if (fBoard->GetDRSType() == 3) 5310 return RecordCalibrationPointsV4(chipNumber); 5311 else 5312 return RecordCalibrationPointsV3(chipNumber); 2650 5313 } 2651 5314 … … 2654 5317 bool ResponseCalibration::RecordCalibrationPointsV3(int chipNumber) 2655 5318 { 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, 2664 5326 0.277, 0.294, 0.310, 2665 5327 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, … … 2667 5329 0.772, 0.842, 0.916, 2668 5330 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; 2751 5415 } 2752 5416 … … 2755 5419 bool ResponseCalibration::RecordCalibrationPointsV4(int chipNumber) 2756 5420 { 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 2783 5480 #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); 2785 5496 #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 5510 bool 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 5522 bool 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 5708 bool 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 5792 unsigned 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; 2829 5804 #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; 3105 5806 } 3106 5807 … … 3109 5810 bool ResponseCalibration::OffsetCalibration(int chipNumber) 3110 5811 { 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 5822 bool 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 5883 bool 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; 3168 5936 } 3169 5937 … … 3175 5943 int showStatistics) 3176 5944 { 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 } 3238 6006 } 3239 6007 … … 3242 6010 void ResponseCalibration::DeleteFields() 3243 6011 { 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 3258 if (fWaveFormMode2[ii] != NULL)3259 3260 if (fWaveFormOffset[ii] != NULL)3261 3262 if (fWaveFormOffsetADC[ii] != NULL)3263 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]; 3297 6065 } 3298 6066 … … 3301 6069 double ResponseCalibration::GetTemperature(unsigned int chipIndex) 3302 6070 { 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; 3308 6076 } 3309 6077 … … 3311 6079 3312 6080 bool 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; 3355 6149 } 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 } else3373 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 6173 bool 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; 3403 6197 } 3404 6198 … … 3408 6202 bool ResponseCalibration::ReadCalibration(unsigned int chipIndex) 3409 6203 { 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); 3414 6206 } 3415 6207 … … 3418 6210 bool ResponseCalibration::ReadCalibrationV3(unsigned int chipIndex) 3419 6211 { 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) { 3478 6237 printf("Error while reading response calibration file '%s'\n", fileName); 3479 printf(" at ' Min'.\n");6238 printf(" at 'NumberOfGridPoints'.\n"); 3480 6239 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) { 3485 6253 printf("Error while reading response calibration file '%s'\n", fileName); 3486 printf(" at ' Max'.\n");6254 printf(" at 'StartTemperature'.\n"); 3487 6255 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) { 3492 6261 printf("Error while reading response calibration file '%s'\n", fileName); 3493 printf(" at ' NumberOfLimitGroups'.\n");6262 printf(" at 'EndTemperature'.\n"); 3494 6263 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); 3553 6269 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; 3576 6368 } 3577 6369 … … 3580 6372 bool ResponseCalibration::ReadCalibrationV4(unsigned int chipIndex) 3581 6373 { 3582 int k, l, num;3583 char fileName[2000];3584 FILE *fileHandle;3585 char calibDir[1000];3586 3587 // Read Response Calibration3588 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 channel3613 for (k = 0; k < kNumberOfCalibChannels; k++) {3614 chn = data->fChannel[k];3615 for (l = 0; l < kNumberOfBins; l++) {3616 // Offset3617 num = fread(&chn->fOffset[l], 2, 1, fileHandle);3618 if (num != 1) {3619 3620 3621 3622 }3623 if (fBoard->GetChipVersion() == 3) {3624 3625 3626 3627 3628 3629 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; 3637 6429 } 3638 6430 … … 3641 6433 float ResponseCalibration::GetValue(float *coefficients, float u, int n) 3642 6434 { 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; 3652 6444 } 3653 6445 … … 3656 6448 int ResponseCalibration::Approx(float *p, float *uu, int np, int nu, float *coef) 3657 6449 { 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; 3688 6485 LeastSquaresAccumulation(matrix, kBSplineOrder, &ip, &ir, mt, iu - kBSplineOrder + 1); 3689 6486 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 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++) 3698 6495 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; 3705 6497 } 3706 6498 … … 3709 6501 void ResponseCalibration::LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt) 3710 6502 { 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 3720 3721 3722 }3723 for (i = 0; i < jt - (*ir); i++) {3724 3725 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 3734 3735 3736 3737 3738 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 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 } 3757 6549 } 3758 6550 … … 3761 6553 int ResponseCalibration::LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n) 3762 6554 { 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 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; 3791 6583 } 3792 6584 … … 3796 6588 float **c, int iC1, int iC2, int ice, int ncv) 3797 6589 { 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 transformation3808 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 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 } 3846 6638 } 3847 6639 … … 3850 6642 int ResponseCalibration::MakeDir(const char *path) 3851 6643 { 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; 3856 6653 } 3857 6654 … … 3859 6656 3860 6657 ResponseCalibration::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; 3906 6705 } 3907 6706 … … 3910 6709 ResponseCalibration::~ResponseCalibration() 3911 6710 { 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(); 3914 6717 } 3915 6718 … … 3918 6721 float ResponseCalibration::CalibrationData::fIntRevers[2 * kBSplineOrder - 2]; 3919 6722 ResponseCalibration::CalibrationData::CalibrationData(int numberOfGridPoints) 3920 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 } 3937 6740 }; 3938 6741 … … 3941 6744 void ResponseCalibration::CalibrationData::PreCalculateBSpline() 3942 6745 { 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 3957 }3958 if (i - xmin > xrange) {3959 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 } 3965 6768 } 3966 6769 … … 3969 6772 void ResponseCalibration::CalibrationData::DeletePreCalculatedBSpline() 3970 6773 { 3971 int i, j;3972 for (i = 0; i < kNumberOfADCBins; i++) {3973 if (fBSplineLookUp[i]!=NULL) {3974 for (j = 0; j < fNumberOfLimitGroups; j++)3975 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 } 3980 6783 } 3981 6784 … … 3984 6787 ResponseCalibration::CalibrationData::~CalibrationData() 3985 6788 { 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 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 } 3999 6802 }; 4000 6803 … … 4003 6806 int ResponseCalibration::CalibrationData::CalculateBSpline(int nGrid, float value, float *bsplines) 4004 6807 { 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 6851 void 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) { 4075 6862 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 } 4092 6894 4093 6895 -
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 ********************************************************************/ 2 7 #ifndef DRS_H 3 8 #define DRS_H 4 5 9 #include <stdio.h> 6 #include <math.h>7 10 #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 19 25 20 26 // Concurrent Technologies VME single board computer … … 23 29 #include "vme_rcc/vme_rcc.h" // VME access 24 30 #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 38 116 #define BIT_AUTOSTART (1<<16) 39 #define BIT_DMODE (1<<17) // 0: single shot, 1: circular117 #define BIT_DMODE (1<<17) // (*DRS2*) 0: single shot, 1: circular 40 118 #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 56 148 #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) 57 155 58 156 enum 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, 70 169 }; 71 170 72 171 enum DRSErrorCodes { 73 kSuccess = 0,74 kInvalidTriggerSignal = -1,75 kWrongChannelOrChip = -2,76 kInvalidTransport = -3,77 kZeroSuppression = -4,78 kWaveNotAvailable = -5172 kSuccess = 0, 173 kInvalidTriggerSignal = -1, 174 kWrongChannelOrChip = -2, 175 kInvalidTransport = -3, 176 kZeroSuppression = -4, 177 kWaveNotAvailable = -5 79 178 }; 80 179 180 /*---- callback class ----*/ 181 182 class DRSCallback 183 { 184 public: 185 virtual void Progress(int value) = 0; 186 virtual ~DRSCallback() {}; 187 }; 188 189 /*------------------------*/ 190 81 191 class DRSBoard; 82 192 83 84 193 class 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); 194 protected: 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 327 private: 328 ResponseCalibration(const ResponseCalibration &c); // not implemented 329 ResponseCalibration &operator=(const ResponseCalibration &rhs); // not implemented 330 331 public: 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 370 protected: 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); 266 387 }; 267 388 268 389 269 270 390 class DRSBoard { 271 272 class TimeData {273 public:274 class FrequencyData {275 public:276 int fFrequency;277 double fBin[kNumberOfBins];278 };279 280 enum {281 kMaxNumberOfFrequencies = 4000282 };283 int fChip;284 int fNumberOfFrequencies;285 FrequencyData *fFrequency[kMaxNumberOfFrequencies];286 287 private:288 TimeData(const TimeData &c); // Not implemented289 TimeData &operator=(const TimeData &rhs); // Not implemented290 291 public:292 TimeData()391 protected: 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() 293 413 :fChip(0) 294 414 ,fNumberOfFrequencies(0) { 295 }296 ~TimeData() {297 int i;298 for (i = 0; i < fNumberOfFrequencies; i++) {299 delete fFrequency[i];300 415 } 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 424 public: 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 452 protected: 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 325 475 #ifdef CT_VME 326 476 VME_ErrorCode_t ErrorCode; … … 342 492 int FreeSegmentCMEM(int CMEM_SegIdentifier); 343 493 #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 559 private: 560 DRSBoard(const DRSBoard &c); // not implemented 561 DRSBoard &operator=(const DRSBoard &rhs); // not implemented 562 563 public: 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 517 573 #ifdef CT_VME 518 574 DRSBoard(int MasterMapping, unsigned int BaseAddress, unsigned int BoardAddress, int SlotNumber); 519 575 #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); 723 protected: 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); 528 732 }; 529 733 530 531 532 734 class 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 735 protected: 736 // constants 737 enum { 738 kMaxNumberOfBoards = 40 739 }; 740 741 protected: 742 DRSBoard *fBoard[kMaxNumberOfBoards]; 743 int fNumberOfBoards; 744 char fError[256]; 745 #ifdef HAVE_VME 746 MVME_INTERFACE *fVmeInterface; 747 #endif 748 749 private: 750 DRS(const DRS &c); // not implemented 751 DRS &operator=(const DRS &rhs); // not implemented 752 552 753 #ifdef CT_VME 553 754 VME_MasterMap_t MasterMap; … … 564 765 #endif 565 766 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; } 767 public: 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 587 779 }; 588 780 589 #endif // DRS_H781 #endif // DRS_H -
drsdaq/HVFeedback.cc
r175 r176 29 29 30 30 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 36 35 PixMap = new PixelMap(PIXMAP_LOCATION, false); 37 36 … … 117 116 for (k=0; k<fNumberOfChannels; k++) { 118 117 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(); 120 119 } 121 120 Integral /= 2*fIntHalfWidth+1; … … 283 282 // 284 283 void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) { 284 285 285 if(Board<m->NumBoards && Chip<fNumberOfChips && Channel<fNumberOfChannels) { 286 286 Target[Board][Chip][Channel] = TargetVal; -
drsdaq/History.txt
r175 r176 58 58 16/12/2009 Removed automatic gain adaption in feedback (caused spikes in the correction) 59 59 9/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. 61 61
Note:
See TracChangeset
for help on using the changeset viewer.