Subversion Repositories f9daq

Rev

Rev 197 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /********************************************************************\
  2.  
  3.   Name:         drscl.cpp
  4.   Created by:   Stefan Ritt
  5.  
  6.   Contents:     Command line interface to DRS chip via USB and VME
  7.  
  8.   $Id: drscl.cpp 21435 2014-07-30 13:02:31Z ritt $
  9.  
  10. \********************************************************************/
  11.  
  12. #include <math.h>
  13.  
  14. #ifdef _MSC_VER
  15.  
  16. #include <windows.h>
  17. #include <conio.h>
  18. #include <io.h>
  19. #include <direct.h>
  20.  
  21. #define DIR_SEPARATOR '\\'
  22.  
  23. #elif defined(OS_LINUX) || defined(OS_DARWIN)
  24.  
  25. #define O_BINARY 0
  26.  
  27. #include <unistd.h>
  28. #include <ctype.h>
  29. #include <sys/ioctl.h>
  30. #include <errno.h>
  31.  
  32. #define DIR_SEPARATOR '/'
  33.  
  34. #endif
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <fcntl.h>
  40. #include <time.h>
  41. #include <sys/stat.h>
  42. #include <assert.h>
  43.  
  44. #include "strlcpy.h"
  45. #include "DRS.h"
  46. #ifdef HAVE_VME
  47. #include "ace.h"
  48. #endif
  49.  
  50. const char *drscl_svn_revision = "$Id: drscl.cpp 21435 2014-07-30 13:02:31Z ritt $";
  51.  
  52. void print_help();
  53. void clear_screen();
  54. int match(const char *str, const char *cmd);
  55. void cmd_loop();
  56.  
  57. #if defined(OS_LINUX) || defined(OS_DARWIN)
  58. #define getch() getchar()
  59. #define Sleep(x) usleep(x*1000)
  60. #endif
  61.  
  62. #ifdef _MSC_VER
  63. #include <conio.h>
  64. #define drs_kbhit() kbhit()
  65. #endif
  66.  
  67. void print_help()
  68. {
  69.    puts("Available commands:\n");
  70.    puts("active <0|1>                Set domino active mode on (1) or off (0)");
  71.    puts("board <i>|<i1> <i2>|all     Address individual board/range/all boards");
  72.    puts("calib [dir]                 Response Calibration. Use dir=\"area\" for MEG");
  73.    puts("chn [n]                     Set number of channels: 8, 4, 2, 1");
  74.    puts("ct                          Chip Test");
  75.    puts("del <0|1>                   Switch delayed start on/off");
  76.    puts("dir                         Show CF directory");
  77.    puts("dmode <0|1>                 Set Domino mode 0=single, 1=cont.");
  78.    puts("et                          EEPROM test");
  79.    puts("exit                        Exit program");
  80.    puts("freq <ghz> [0|1]            Set frequency of board [without/with] regulation");
  81.    puts("info                        Show information about board");
  82.    puts("init                        Initialize board");
  83.    puts("led <0|1>                   Turn LED on (1) or off (0)");
  84.    puts("lock [0|1]                  Display lock status [without/with] restart");
  85.    puts("multi [0|1]                 Turn multi-buffer mode on/off");
  86.    puts("offset <voltage>            Set offset voltage");
  87.    puts("phase <value> [0|1]         Set ADC clock phase and inversion");
  88.    puts("quit                        Exit program");
  89.    puts("ram                         Test speed to FPGA RAM");
  90.    puts("range <center>              Change input range to <center>+=0.5V");
  91.    puts("read <chn> [0|1] [file]     Read waveform to [file], chn=0..19 [with] calibration");
  92.    puts("refclk [0|1]                Use FPGA ref. clk (0) or ext. P2 ref. clk (1)");
  93.    puts("reg                         Register test");
  94.    puts("serial <number>             Set serial number of board");
  95.    puts("scan                        Scan for boards");
  96.    puts("standby <0|1>               Turn standby mode on (1) or off (0)");
  97.    puts("start                       Start domino wave");
  98.    puts("stop                        Issue soft trigger");
  99.    puts("tcout [file] [idx_offset]   Print time calibration of DRS4, or write it onto [file]");
  100.    puts("tcs <0|1>                   Timing calibration signal on (1) or off (0)");
  101.    puts("tcalib [freq]               Timing Calibration");
  102.    puts("tlevel <voltage>            Set trigger level in Volts");
  103.    puts("trans <0|1>                 Set transparent mode on (1) or off (0)");
  104.    puts("trig <0|1>                  Hardware trigger on (1) or off (0)");
  105.    puts("upload <file>               Upload ACE file to CF");
  106.    puts("volt off|<voltage>          Turn calibration voltage on/off");
  107.  
  108.    puts("");
  109. }
  110.  
  111. /*------------------------------------------------------------------*/
  112.  
  113. void clear_screen()
  114. {
  115. #ifdef _MSC_VER
  116.  
  117.    HANDLE hConsole;
  118.    COORD coordScreen = { 0, 0 };        /* here's where we'll home the cursor */
  119.    BOOL bSuccess;
  120.    DWORD cCharsWritten;
  121.    CONSOLE_SCREEN_BUFFER_INFO csbi;     /* to get buffer info */
  122.    DWORD dwConSize;             /* number of character cells in the current buffer */
  123.  
  124.    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  125.  
  126.    /* get the number of character cells in the current buffer */
  127.    bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
  128.    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
  129.  
  130.    /* fill the entire screen with blanks */
  131.    bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten);
  132.  
  133.    /* put the cursor at (0, 0) */
  134.    bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
  135.    return;
  136.  
  137. #else
  138.    printf("\033[2J");
  139. #endif
  140. }
  141.  
  142. /*------------------------------------------------------------------*/
  143.  
  144. int match(const char *str, const char *cmd)
  145. {
  146.    int i;
  147.  
  148.    if (str[0] == '\r' || str[0] == '\n')
  149.       return 0;
  150.  
  151.    for (i = 0; i < (int) strlen(str); i++) {
  152.       if (toupper(str[i]) != toupper(cmd[i]) && str[i] != '\r' && str[i] != '\n')
  153.          return 0;
  154.    }
  155.  
  156.    return 1;
  157. }
  158.  
  159. /*------------------------------------------------------------------*/
  160.  
  161. class ProgressBar : public DRSCallback
  162. {
  163. public:
  164.    void Progress(int prog);
  165. };
  166.  
  167. void ProgressBar::Progress(int prog)
  168. {
  169.    if (prog == 0)
  170.       printf("[--------------------------------------------------]\r");
  171.    printf("[");
  172.    for (int i=0 ; i<prog/2 ; i++)
  173.       printf("=");
  174.    printf("\r");
  175.    fflush(stdout);
  176. }
  177.  
  178. /*------------------------------------------------------------------*/
  179.  
  180. void cmd_loop()
  181. {
  182.    int i, j, idx, i_start, i_end, nparam, calib, status, debug, cascading,
  183.       ext_refclk;
  184.    char str[256], dir[256], line[256], file_name[256], param[10][100], *pc;
  185.    double freq, triggerfreq, range;
  186.    FILE *f = NULL;
  187.    DRS *drs;
  188.    DRSBoard *b;
  189. #ifdef HAVE_VME
  190.    ACE ace;
  191. #endif
  192.    static char bar[] = {'\\', '|', '/', '-'};
  193.  
  194.    /* do initial scan */
  195.    drs = new DRS();
  196.    if (drs->GetError(str, sizeof(str)))
  197.       printf("%s", str);
  198.  
  199.    for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  200.       b = drs->GetBoard(i);
  201. #ifdef HAVE_VME
  202.       if (b->GetTransport() != 1)
  203.          printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n",
  204.             b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion());
  205. #else
  206.       printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n",
  207.          b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion());
  208. #endif
  209.    }
  210.  
  211.    if (drs->GetNumberOfBoards()) {
  212.       i_start = 0;
  213.       i_end = 1;
  214.       b = drs->GetBoard(0);
  215.    }
  216.    else {
  217.       printf("No DRS Boards found\n");
  218.       i_start = i_end = 0;
  219.       b = NULL;
  220.    }
  221.  
  222.    puts("");
  223.  
  224.    do {
  225.       /* print prompt */
  226.       if (i_start == i_end-1)
  227.          printf("B%d> ", i_start);
  228.       else if (i_start == 0 && i_end == 0)
  229.          printf("> ");
  230.       else
  231.          printf("B%d-%d> ", i_start, i_end-1);
  232.       memset(line, 0, sizeof(line));
  233.       fgets(line, sizeof(line), stdin);
  234.       /* strip \r\n */
  235.       while (strpbrk(line,"\n\r"))
  236.          *strpbrk(line,"\n\r") = 0;
  237.  
  238.       /* analyze line */
  239.       nparam = 0;
  240.       pc = line;
  241.       while (*pc == ' ')
  242.          pc++;
  243.  
  244.       memset(param, 0, sizeof(param));
  245.       do {
  246.          if (*pc == '"') {
  247.             pc++;
  248.             for (i = 0; *pc && *pc != '"'; i++)
  249.                param[nparam][i] = *pc++;
  250.             if (*pc)
  251.                pc++;
  252.          } else if (*pc == '\'') {
  253.             pc++;
  254.             for (i = 0; *pc && *pc != '\''; i++)
  255.                param[nparam][i] = *pc++;
  256.             if (*pc)
  257.                pc++;
  258.          } else if (*pc == '`') {
  259.             pc++;
  260.             for (i = 0; *pc && *pc != '`'; i++)
  261.                param[nparam][i] = *pc++;
  262.             if (*pc)
  263.                pc++;
  264.          } else
  265.             for (i = 0; *pc && *pc != ' '; i++)
  266.                param[nparam][i] = *pc++;
  267.          param[nparam][i] = 0;
  268.          while (*pc == ' ' || *pc == '\r' || *pc == '\n')
  269.             pc++;
  270.          nparam++;
  271.       } while (*pc);
  272.  
  273.       if (param[0][0] == 0) {
  274.       }
  275.  
  276.       /* help ---------- */
  277.       else if ((param[0][0] == 'h' && param[0][1] == 'e') || param[0][0] == '?')
  278.          print_help();
  279.  
  280.       /* scan ---------- */
  281.       else if (match(param[0], "scan")) {
  282.          j = 0;
  283.  
  284.          do {
  285.             delete drs;
  286.             drs = new DRS();
  287.  
  288.             for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  289.                b = drs->GetBoard(i);
  290. #ifdef HAVE_VME
  291.                if (b->GetTransport() != 1)
  292.                   printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n",
  293.                      b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion());
  294. #else
  295.                printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n",
  296.                   b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion());
  297. #endif
  298.             }
  299.            
  300.             if (drs_kbhit())
  301.                break;
  302.  
  303.             if (param[1][0] == 'r') {
  304.                printf("%c\r", bar[j]);
  305.                fflush(stdout);
  306.                j = (j+1) % 4;
  307.                Sleep(1000);
  308.             }
  309.  
  310.          } while (param[1][0] == 'r');
  311.  
  312.          while (drs_kbhit())
  313.             getch();
  314.  
  315.          if (drs->GetNumberOfBoards()) {
  316.             i_start = 0;
  317.             i_end = 1;
  318.             b = drs->GetBoard(0);
  319.          } else {
  320.             printf("No DRS Boards found\n");
  321.             i_start = i_end = 0;
  322.             b = NULL;
  323.          }
  324.       }
  325.  
  326.       /* address board ---------- */
  327.       else if (match(param[0], "board")) {
  328.          if (param[1][0] == 'a') {
  329.             i_start = 0;
  330.             i_end = drs->GetNumberOfBoards();
  331.             b = drs->GetBoard(0);
  332.          } else if (param[2][0] && atoi(param[2]) > 0 && atoi(param[2]) < drs->GetNumberOfBoards()) {
  333.             i_start = atoi(param[1]);
  334.             i_end = atoi(param[2]) + 1;
  335.             b = drs->GetBoard(i_start);
  336.          } else if (atoi(param[1]) >= 0 && atoi(param[1]) < drs->GetNumberOfBoards()) {
  337.             i_start = atoi(param[1]);
  338.             i_end = i_start + 1;
  339.             b = drs->GetBoard(i_start);
  340.          } else
  341.             printf("Board #%d does not exist\n", atoi(param[1]));
  342.       }
  343.  
  344.       /* info ---------- */
  345.       else if (match(param[0], "info")) {
  346.          for (idx=i_start ; idx<i_end ; idx++) {
  347.             b = drs->GetBoard(idx);
  348.             printf("==============================\n");
  349.             printf("Mezz. Board index:    %d\n", idx);
  350. #ifdef HAVE_VME
  351.             if (b->GetTransport() == TR_VME) {
  352.                printf("Slot:                 %d", (b->GetSlotNumber() >> 1)+2);
  353.                if ((b->GetSlotNumber() & 1) == 0)
  354.                   printf(" upper\n");
  355.                else
  356.                   printf(" lower\n");
  357.             }
  358. #endif
  359.             printf("DRS type:             DRS%d\n", b->GetDRSType());
  360.             printf("Board type:           %d\n", b->GetBoardType());
  361.             printf("Serial number:        %04d\n", b->GetBoardSerialNumber());
  362.             printf("Firmware revision:    %d\n", b->GetFirmwareVersion());
  363.             printf("Temperature:          %1.1lf C\n", b->GetTemperature());
  364.             if (b->GetDRSType() == 4) {
  365.                printf("Input range:          %1.2lgV...%1.2lgV\n",
  366.                       b->GetInputRange()-0.5, b->GetInputRange()+0.5);
  367.                printf("Calibrated range:     %1.2lgV...%1.2lgV\n", b->GetCalibratedInputRange()-0.5,
  368.                   b->GetCalibratedInputRange()+0.5);
  369.                printf("Calibrated frequency: %1.3lf GHz\n", b->GetCalibratedFrequency());
  370.  
  371.                if (b->GetTransport() == TR_VME) {
  372.                   printf("Multi Buffer WP:      %d\n", b->GetMultiBufferWP());
  373.                   printf("Multi Buffer RP:      %d\n", b->GetMultiBufferRP());
  374.                }
  375.             }
  376.            
  377.             printf("Status reg.:          %08X\n", b->GetStatusReg());
  378.             if (b->GetStatusReg() & BIT_RUNNING)
  379.                puts("  Domino wave running");
  380.             if (b->GetDRSType() == 4) {
  381.                if (b->GetBoardType() == 5) {
  382.                   if (b->GetStatusReg() & BIT_PLL_LOCKED0)
  383.                      puts("  PLL locked");
  384.                } else if (b->GetBoardType() == 6) {
  385.                   i = 0;
  386.                   if (b->GetStatusReg() & BIT_PLL_LOCKED0) i++;
  387.                   if (b->GetStatusReg() & BIT_PLL_LOCKED1) i++;
  388.                   if (b->GetStatusReg() & BIT_PLL_LOCKED2) i++;
  389.                   if (b->GetStatusReg() & BIT_PLL_LOCKED3) i++;
  390.                   if (i == 4)
  391.                      puts("  All PLLs locked");
  392.                   else if (i == 0)
  393.                      puts("  No PLL locked");
  394.                   else
  395.                      printf("  %d PLLs locked\n", i);
  396.                   if (b->GetStatusReg() & BIT_LMK_LOCKED)
  397.                      puts("  LMK PLL locked");
  398.                }
  399.             } else {
  400.                if (b->GetStatusReg() & BIT_NEW_FREQ1)
  401.                   puts("  New Freq1 ready");
  402.                if (b->GetStatusReg() & BIT_NEW_FREQ2)
  403.                   puts("  New Freq2 ready");
  404.             }
  405.            
  406.             printf("Control reg.:         %08X\n", b->GetCtrlReg());
  407.             if (b->GetCtrlReg() & BIT_MULTI_BUFFER)
  408.                puts("  Multi-buffering enabled");
  409.             if (b->GetDRSType() == 4) {
  410.                if (b->GetConfigReg() & BIT_CONFIG_DMODE)
  411.                   puts("  DMODE circular");
  412.                else
  413.                   puts("  DMODE single shot");
  414.             } else {
  415.                if (b->GetCtrlReg() & BIT_DMODE)
  416.                   puts("  DMODE circular");
  417.                else
  418.                   puts("  DMODE single shot");
  419.             }
  420.             if (b->GetCtrlReg() & BIT_LED)
  421.                puts("  LED");
  422.             if (b->GetCtrlReg() & BIT_TCAL_EN)
  423.                puts("  TCAL enabled");
  424.             if (b->GetDRSType() == 4) {
  425.                if (b->GetCtrlReg() & BIT_TRANSP_MODE)
  426.                   puts("  TRANSP_MODE enabled");
  427.             } else {
  428.                if (b->GetCtrlReg() & BIT_FREQ_AUTO_ADJ)
  429.                   puts("  FREQ_AUTO_ADJ enabled");
  430.             }
  431.             if (b->GetCtrlReg() & BIT_ENABLE_TRIGGER1)
  432.                puts("  Hardware trigger enabled");
  433.             if (b->GetDRSType() == 4) {
  434.                if (b->GetCtrlReg() & BIT_READOUT_MODE)
  435.                   puts("  Readout from stop");
  436.                if (b->GetCtrlReg() & BIT_ENABLE_TRIGGER2)
  437.                   puts("  Internal trigger enabled");
  438.             } else {
  439.                if (b->GetCtrlReg() & BIT_LONG_START_PULSE)
  440.                   puts("  LONG_START_PULSE");
  441.             }
  442.             if (b->GetCtrlReg() & BIT_DELAYED_START)
  443.                puts("  DELAYED_START");
  444.             if (b->GetCtrlReg() & BIT_ACAL_EN)
  445.                puts("  ACAL enabled");
  446.             if (b->GetDRSType() < 4)
  447.                if (b->GetCtrlReg() & BIT_TRIGGER_DELAYED)
  448.                   puts("  DELAYED_TRIGGER selected");
  449.             if (b->GetBoardType() != 5)
  450.                printf("Trigger bus:          %08X\n", b->GetTriggerBus());
  451.             if (b->GetDRSType() == 4) {
  452.                if (b->GetRefclk() == 1) {
  453.                   if (b->IsPLLLocked() && b->IsLMKLocked()) {
  454.                      b->ReadFrequency(0, &freq);
  455.                      printf("Frequency:            %1.3lf GHz\n", freq);
  456.                   } else {
  457.                      if (!b->IsPLLLocked())
  458.                         printf("Frequency:            PLL not locked\n");
  459.                      else
  460.                         printf("Frequency:            LMK chip not locked\n");
  461.                   }
  462.                } else {
  463.                   if (b->IsPLLLocked()) {
  464.                      b->ReadFrequency(0, &freq);
  465.                      printf("Frequency:            %1.3lf GHz\n", freq);
  466.                   } else {
  467.                      printf("Frequency:            PLL not locked\n");
  468.                   }
  469.                }
  470.             } else {
  471.                if (b->IsBusy()) {
  472.                   b->ReadFrequency(0, &freq);
  473.                   printf("Frequency0:           %1.4lf GHz\n", freq);
  474.                   b->ReadFrequency(1, &freq);
  475.                   printf("Frequency1:           %1.4lf GHz\n", freq);
  476.                } else
  477.                   puts("Domino wave stopped");
  478.             }
  479.          }
  480.       }
  481.  
  482.       /* init ---------- */
  483.       else if (match(param[0], "init")) {
  484.          for (i=i_start ; i<i_end ; i++) {
  485.             b = drs->GetBoard(i);
  486.             b->Init();
  487.          }
  488.       }
  489.  
  490.       /* set led ---------- */
  491.       else if (match(param[0], "led")) {
  492.          for (i=i_start ; i<i_end ; i++) {
  493.             b = drs->GetBoard(i);
  494.             if (atoi(param[1]))
  495.                b->SetLED(1);
  496.             else
  497.                b->SetLED(0);
  498.          }
  499.       }
  500.  
  501.       /* set multi buffer mode ---------- */
  502.       else if (match(param[0], "multi")) {
  503.          for (i=i_start ; i<i_end ; i++) {
  504.             b = drs->GetBoard(i);
  505.             if (atoi(param[1]))
  506.                b->SetMultiBuffer(1);
  507.             else
  508.                b->SetMultiBuffer(0);
  509.          }
  510.       }
  511.  
  512.       /* lock status ---------- */
  513.       else if (match(param[0], "lock")) {
  514.          int slot, found, restart;
  515.  
  516.          restart = atoi(param[1]);
  517.  
  518.          // select external reference clock
  519.          for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  520.             b = drs->GetBoard(i);
  521.             b->SetRefclk(1);
  522.             b->SetFrequency(b->GetNominalFrequency(), true);
  523.          }
  524.  
  525.          // loop until keyboard hit
  526.          do {
  527.             clear_screen();
  528.             printf("                1 1 1 1 1 1 1 1 1 1 2 2\n");
  529.             printf("2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n\n");
  530.  
  531.             // upper slots
  532.             for (slot = 2 ; slot<22 ; slot++) {
  533.                found = 0;
  534.                for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  535.                   b = drs->GetBoard(i);
  536.                   if ((b->GetSlotNumber() & 1) == 0 && (b->GetSlotNumber() >> 1)+2 == slot) {
  537.                      found = 1;
  538.                      if (b->IsLMKLocked())
  539.                         printf("O ");
  540.                      else
  541.                         printf("- ");
  542.                   }
  543.                }
  544.                if (!found)
  545.                   printf("  ");
  546.             }
  547.             printf("\n");
  548.  
  549.             // lower slots
  550.             for (slot = 2 ; slot<22 ; slot++) {
  551.                found = 0;
  552.                for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  553.                   b = drs->GetBoard(i);
  554.                   if ((b->GetSlotNumber() & 1) == 1 && (b->GetSlotNumber() >> 1)+2 == slot) {
  555.                      found = 1;
  556.                      if (b->IsLMKLocked())
  557.                         printf("O ");
  558.                      else
  559.                         printf("- ");
  560.                   }
  561.                }
  562.                if (!found)
  563.                   printf("  ");
  564.             }
  565.             printf("\n");
  566.  
  567.             if (restart) {
  568.                for (i=0 ; i<drs->GetNumberOfBoards() ; i++) {
  569.                   b = drs->GetBoard(i);
  570.                   b->SetFrequency(b->GetNominalFrequency(), true);
  571.                }
  572.             }
  573.  
  574.             Sleep(300);
  575.  
  576.          } while (!drs_kbhit());
  577.          puts("");
  578.          while (drs_kbhit())
  579.             getch();
  580.       }
  581.  
  582.       /* start domino wave ---------- */
  583.       else if (match(param[0], "start")) {
  584.          for (i=i_start ; i<i_end ; i++) {
  585.             b = drs->GetBoard(i);
  586.             b->StartDomino();
  587.             b->ReadFrequency(0, &freq);
  588.             for (j=0 ; j<10 ; j++)
  589.                if (b->GetDRSType() != 4 || b->IsPLLLocked())
  590.                   break;
  591.             if (j == 10)
  592.                printf("Domino wave started but PLL did not lock!\n");
  593.             else
  594.                printf("Domino wave started at %1.3lf GHz\n", freq);
  595.          }
  596.       }
  597.  
  598.       /* issue soft trigger ---------- */
  599.       else if (match(param[0], "stop")) {
  600.          for (i=i_start ; i<i_end ; i++) {
  601.             b = drs->GetBoard(i);
  602.             b->SoftTrigger();
  603.          }
  604.       }
  605.  
  606.       /* set serial ---------- */
  607.       else if (match(param[0], "serial")) {
  608.          for (i=i_start ; i<i_end ; i++) {
  609.             b = drs->GetBoard(i);
  610.             if (param[1][0] == 0) {
  611.                printf("Serial number: ");
  612.                fgets(str, sizeof(str), stdin);
  613.             } else
  614.                strlcpy(str, param[1], sizeof(str));
  615.  
  616.             if (!b->SetBoardSerialNumber(atoi(str)))
  617.                printf("Board EEPROM is write protected\n");
  618.             else
  619.                printf("Serial number successfully changed\n");
  620.          }
  621.       }
  622.  
  623.       /* eeprom test ---------- */
  624.       else if (match(param[0], "et")) {
  625.          unsigned short buf[16384];
  626.          unsigned short rbuf[16384];
  627.          int n_error;
  628.  
  629.          do {
  630.             for (i=0 ; i<16384 ; i++)
  631.                buf[i] = rand();
  632.             b->WriteEEPROM(1, buf, sizeof(buf));
  633.             memset(rbuf, 0, sizeof(rbuf));
  634.             b->Write(T_RAM, 0, rbuf, sizeof(rbuf));
  635.             b->ReadEEPROM(1, rbuf, sizeof(rbuf));
  636.             for (i=n_error=0 ; i<16384 ; i++)
  637.                if (buf[i] != rbuf[i]) {
  638.                   printf("%04X %04X - %04X\n", i, buf[i], rbuf[i]);
  639.                   n_error++;
  640.                }
  641.  
  642.             printf("32 kb written, %d errors\n", n_error);
  643.          } while (!drs_kbhit());
  644.  
  645.          while (drs_kbhit())
  646.             getch();
  647.       }
  648.  
  649.       /* set frequency ---------- */
  650.       else if (match(param[0], "freq")) {
  651.          for (i=i_start ; i<i_end ; i++) {
  652.             b = drs->GetBoard(i);
  653.             if (param[1][0] == 0) {
  654.                printf("Frequency: ");
  655.                fgets(str, sizeof(str), stdin);
  656.             } else
  657.                strlcpy(str, param[1], sizeof(str));
  658.  
  659.             b->SetDebug(1);
  660.  
  661.             if (param[2][0] && atoi(param[2]))
  662.                b->RegulateFrequency(atof(str));
  663.             else
  664.                b->SetFrequency(atof(str), true);
  665.          }
  666.       }
  667.  
  668.       /* set calibration voltage ---------- */
  669.       else if (match(param[0], "volt")) {
  670.          for (i=i_start ; i<i_end ; i++) {
  671.             b = drs->GetBoard(i);
  672.             if (param[1][0] == 0) {
  673.                printf("Voltage or \"off\": ");
  674.                fgets(str, sizeof(str), stdin);
  675.             } else
  676.                strlcpy(str, param[1], sizeof(str));
  677.  
  678.             if (str[0] == 'o') {
  679.                b->EnableAcal(0, 0);
  680.                puts("Calibration voltage turned off");
  681.             } else {
  682.                b->EnableAcal(1, atof(str));
  683.                printf("Voltage set to %1.3lf Volt\n", atof(str));
  684.             }
  685.          }
  686.       }
  687.  
  688.       /* set channel configuration ---------- */
  689.       else if (match(param[0], "chn")) {
  690.          for (i=i_start ; i<i_end ; i++) {
  691.             b = drs->GetBoard(i);
  692.             if (param[1][0] == 0) {
  693.                printf("Number of channels (8,4,2,1): ");
  694.                fgets(str, sizeof(str), stdin);
  695.             } else
  696.                strlcpy(str, param[1], sizeof(str));
  697.  
  698.             if (b->SetChannelConfig(0, 8, atoi(str)))
  699.                printf("DRS4 configured for %d channels\n", atoi(str));
  700.          }
  701.       }
  702.  
  703.       /* set trigger level ---------- */
  704.       else if (match(param[0], "tlevel")) {
  705.          for (i=i_start ; i<i_end ; i++) {
  706.             b = drs->GetBoard(i);
  707.             if (param[1][0] == 0) {
  708.                printf("Voltage: ");
  709.                fgets(str, sizeof(str), stdin);
  710.             } else
  711.                strlcpy(str, param[1], sizeof(str));
  712.  
  713.             b->SetTriggerLevel(atof(str));
  714.             printf("Trigger level set to %1.3lf Volt\n", atof(str));
  715.          }
  716.       }
  717.  
  718.       /* trigger on/off ---------- */
  719.       else if (match(param[0], "trig")) {
  720.          for (i=i_start ; i<i_end ; i++) {
  721.             b = drs->GetBoard(i);
  722.             b->EnableTrigger(atoi(param[1]), 0);
  723.             if (atoi(param[1]) == 1) {
  724.                puts("Hardware fast trigger is on");
  725.             } else if (atoi(param[1]) == 2) {
  726.                puts("Hardware slow trigger is on");
  727.             } else {
  728.                puts("Hardware trigger is off");
  729.             }
  730.          }
  731.       }
  732.  
  733.       /* timing calibration signal on/off ---------- */
  734.       else if (match(param[0], "tcs")) {
  735.          for (i=i_start ; i<i_end ; i++) {
  736.             b = drs->GetBoard(i);
  737.             b->EnableTcal(atoi(param[1]), 0, 0);
  738.             b->SelectClockSource(0);
  739.             if (atoi(param[1]))
  740.                puts("Timing calibration signal is on");
  741.             else
  742.                puts("Timing calibration signal is off");
  743.          }
  744.       }
  745.  
  746.       /* timing calibration signal on/off ---------- */
  747.       else if (match(param[0], "refclk")) {
  748.          for (i=i_start ; i<i_end ; i++) {
  749.             b = drs->GetBoard(i);
  750.             b->SetRefclk(atoi(param[1]));
  751.             // re-set frequency since LMK configuration needs to be changed
  752.             b->SetFrequency(b->GetNominalFrequency(), true);
  753.             if (atoi(param[1]))
  754.                puts("Refclock set to external through P2");
  755.             else
  756.                puts("Refclock set to internal (FPGA)");
  757.          }
  758.       }
  759.  
  760.       /* domino mode 0/1 ---------- */
  761.       else if (match(param[0], "dmode")) {
  762.          for (i=i_start ; i<i_end ; i++) {
  763.             b = drs->GetBoard(i);
  764.             if (atoi(param[1]) == 1) {
  765.                b->SetDominoMode(1);
  766.                puts("Domino mode switched to cyclic");
  767.             } else {
  768.                b->SetDominoMode(0);
  769.                puts("Domino mode switched to single shot");
  770.             }
  771.          }
  772.       }
  773.  
  774.       /* active mode 0/1 ---------- */
  775.       else if (match(param[0], "active")) {
  776.          for (i=i_start ; i<i_end ; i++) {
  777.             b = drs->GetBoard(i);
  778.             if (atoi(param[1]) == 1) {
  779.                b->SetDominoActive(1);
  780.                puts("Domino wave active during readout");
  781.             } else {
  782.                b->SetDominoMode(0);
  783.                puts("Domino wave stopped during readout");
  784.             }
  785.          }
  786.       }
  787.  
  788.       /* delayed start on/off ---------- */
  789.       else if (match(param[0], "del")) {
  790.          for (i=i_start ; i<i_end ; i++) {
  791.             b = drs->GetBoard(i);
  792.             if (b->GetDRSType() == 4)
  793.                puts("Delayed start not possible for DRS4");
  794.             else {
  795.                if (atoi(param[1]) == 1) {
  796.                   b->SetDelayedStart(1);
  797.                   puts("Delayed start is on");
  798.                } else {
  799.                   b->SetDelayedStart(0);
  800.                   puts("Delayed start is off");
  801.                }
  802.             }
  803.          }
  804.       }
  805.  
  806.       /* transparent mode on/off ---------- */
  807.       else if (match(param[0], "trans")) {
  808.          for (i=i_start ; i<i_end ; i++) {
  809.             b = drs->GetBoard(i);
  810.             if (b->GetDRSType() != 4)
  811.                puts("Transparen mode only possible for DRS4");
  812.             else {
  813.                if (atoi(param[1]) == 1) {
  814.                   b->SetTranspMode(1);
  815.                   puts("Transparent mode is on");
  816.                } else {
  817.                   b->SetTranspMode(0);
  818.                   puts("Transparent mode is off");
  819.                }
  820.             }
  821.          }
  822.       }
  823.  
  824.       /* standby mode on/off ---------- */
  825.       else if (match(param[0], "standby")) {
  826.          for (i=i_start ; i<i_end ; i++) {
  827.             b = drs->GetBoard(i);
  828.             if (b->GetDRSType() != 4)
  829.                puts("Standby mode only possible for DRS4");
  830.             else {
  831.                if (atoi(param[1]) == 1) {
  832.                   b->SetStandbyMode(1);
  833.                   puts("Standby mode is on");
  834.                } else {
  835.                   b->SetStandbyMode(0);
  836.                   puts("Standby mode is off");
  837.                }
  838.             }
  839.          }
  840.       }
  841.  
  842.       /* offset ---------- */
  843.       else if (match(param[0], "offset")) {
  844.          for (i=i_start ; i<i_end ; i++) {
  845.             b = drs->GetBoard(i);
  846.             b->SetVoltageOffset(atof(param[1]), atof(param[2]));
  847.          }
  848.       }
  849.  
  850.       /* phase ---------- */
  851.       else if (match(param[0], "phase")) {
  852.          for (i=i_start ; i<i_end ; i++) {
  853.             b = drs->GetBoard(i);
  854.             b->SetADCClkPhase(atoi(param[1]), atoi(param[2]) > 0);
  855.          }
  856.       }
  857.  
  858.       /* directory ---------- */
  859.       else if (match(param[0], "dir")) {
  860.  
  861. #ifdef HAVE_VME
  862. #ifdef CF_VIA_USB
  863.          {
  864.             if (param[2][0])
  865.                i = atoi(param[2]);
  866.             else
  867.                i = 1;
  868.             printf("Physical drive %d:\n", i);
  869.  
  870.             if (ace_init(NULL, i, &ace) != ACE_SUCCESS) {
  871.                printf("Cannot access ACE on physical drive %d\n", i);
  872.             } else {
  873. #else
  874.          for (i=i_start ; i<i_end ; i++) {
  875.  
  876.             /* do only once per VME board */
  877.             if (i_end - i_start > 1 && (i % 2) == 1)
  878.                continue;
  879.  
  880.             b = drs->GetBoard(i);
  881.  
  882.             printf("VME slot %2d:   ", (b->GetSlotNumber() >> 1) + 2);
  883.  
  884.             if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) {
  885.                printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2);
  886.             } else {
  887. #endif
  888.             ace_dir(&ace);
  889.             }
  890.          }
  891. #else
  892.          printf("No VME support compiled into drscl\n");
  893. #endif // HAVE_VME
  894.       }
  895.  
  896.       /* upload ---------- */
  897.       else if (match(param[0], "upload")) {
  898.  
  899. #ifdef HAVE_VME
  900. #ifdef CF_VIA_USB
  901.          {
  902.             if (param[2][0])
  903.                i = atoi(param[2]);
  904.             else
  905.                i = 1;
  906.             printf("Physical drive %d:\n", i);
  907.  
  908.             if (ace_init(NULL, i, &ace) != ACE_SUCCESS) {
  909.                printf("Cannot access ACE on physical drive %d\n", i);
  910.             } else {
  911. #else
  912.  
  913.             /* use SVN file as default */
  914.             if (param[1][0] == 0) {
  915. #ifdef _MSC_VER
  916.                if (b->GetDRSType() == 4)
  917.                   strcpy(str, "c:\\meg\\online\\VPC\\drs4\\2vp30\\cflash\\drs4\\rev0\\rev0.ace");
  918.                else if (b->GetDRSType() == 3)
  919.                   strcpy(str, "c:\\meg\\online\\VPC\\drs3\\2vp30\\cflash\\drs3\\rev0\\rev0.ace");
  920.                else
  921.                   strcpy(str, "c:\\meg\\online\\VPC\\drs2\\2vp30\\cflash\\drs2\\rev0\\rev0.ace");
  922. #else
  923.                if (b->GetDRSType() == 4)
  924.                   strcpy(str, "/home/meg/meg/online/VPC/drs4/2vp30/cflash/drs4/rev0/rev0.ace");
  925.                else if (b->GetDRSType() == 3)
  926.                   strcpy(str, "/home/meg/meg/online/VPC/drs3/2vp30/cflash/drs3/rev0/rev0.ace");
  927.                else
  928.                   strcpy(str, "/home/meg/meg/online/VPC/drs2/2vp30/cflash/drs2/rev0/rev0.ace");
  929. #endif
  930.                printf("Enter filename or hit return for \n%s\n", str);
  931.                fgets(line, sizeof(line), stdin);
  932.                if (line[0] == '\r' || line[0] == '\n')
  933.                   strcpy(file_name, str);
  934.                else
  935.                   strcpy(file_name, line);
  936.                strcpy(param[1], str);
  937.             } else
  938.                strcpy(file_name, param[1]);
  939.  
  940.          for (i=i_start ; i<i_end ; i++) {
  941.  
  942.             /* do only once per VME board */
  943.             if (i_end - i_start > 1 && (i % 2) == 1)
  944.                continue;
  945.  
  946.             b = drs->GetBoard(i);
  947.  
  948.             if (b->GetTransport() == TR_USB) {
  949.                printf("Cannot upload to USB board.\n");
  950.             } else {
  951.                printf("VME slot %d:\n", (b->GetSlotNumber() >> 1)+2);
  952.                if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) {
  953.                   printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2);
  954.                } else {
  955. #endif
  956.                   status = ace_upload(&ace, file_name);
  957.                }
  958.             }
  959.          }
  960.          printf("\nPlease issue a power cycle to activate new firmware\n");
  961. #else
  962.          printf("No VME support compiled into drscl\n");
  963. #endif // HAVE_VME
  964.       }
  965.  
  966.       /* download ---------- */
  967.       else if (match(param[0], "download")) {
  968.  
  969. #ifdef HAVE_VME
  970.          b = drs->GetBoard(i_start);
  971.  
  972.          if (b->GetTransport() == TR_USB) {
  973.             printf("Cannot upload to USB board.\n");
  974.          } else {
  975.             printf("VME slot %d:\n", (b->GetSlotNumber() >> 1)+2);
  976.             if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) {
  977.                printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2);
  978.             } else {
  979.                strcpy(str, "rev0.ace");
  980.                if (param[1][0] == 0) {
  981.                   printf("Enter filename or hit return for \n%s\n", str);
  982.                   fgets(line, sizeof(line), stdin);
  983.                   if (line[0] == '\r' || line[0] == '\n')
  984.                      strcpy(file_name, str);
  985.                   else
  986.                      strcpy(file_name, line);
  987.                   strcpy(param[1], str);
  988.                } else
  989.                   strcpy(file_name, param[1]);
  990.  
  991.                if (strchr(file_name, '\r'))
  992.                   *strchr(file_name, '\r') = 0;
  993.                if (strchr(file_name, '\n'))
  994.                   *strchr(file_name, '\n') = 0;
  995.  
  996.                status = ace_download(&ace, file_name);
  997.                }
  998.          }
  999. #else
  1000.          printf("No VME support compiled into drscl\n");
  1001. #endif // HAVE_VME
  1002.       }
  1003.  
  1004.       /* calibration ---------- */
  1005.       else if (match(param[0], "calib")) {
  1006.          debug = strcmp(param[1], "debug") == 0 || strcmp(param[2], "debug") == 0 || strcmp(param[3], "debug") == 0;
  1007.          if (param[1][0]) {
  1008.             strlcpy(dir, param[1], sizeof(str));
  1009.          } else
  1010.             getcwd(dir, sizeof(dir));
  1011.  
  1012.          while (dir[strlen(dir)-1] == '\n' || dir[strlen(dir)-1] == '\r')
  1013.            dir[strlen(dir)-1] = 0;
  1014.  
  1015.          b = drs->GetBoard(i_start);
  1016.  
  1017.          printf("\n           Enter calibration frequency [GHz]: ");
  1018.          fgets(line, sizeof(line), stdin);
  1019.          freq = atof(line);
  1020.  
  1021.          if (b->GetDRSType() == 2) {
  1022.             printf("   Enter the expected trigger frequency [Hz]: ");
  1023.             fgets(line, sizeof(line), stdin);
  1024.             triggerfreq = atof(line);
  1025.          } else
  1026.             triggerfreq = 0;
  1027.  
  1028.          ext_refclk = 0;
  1029.          if (b->GetBoardType() == 6) {
  1030.             printf("Use [e]xternal or [i]nternal reference clock: ");
  1031.             fgets(line, sizeof(line), stdin);
  1032.             ext_refclk = line[0] == 'e';
  1033.          }
  1034.  
  1035.          if (b->GetDRSType() == 4) {
  1036.             printf("                             Enter range [V]: ");
  1037.             fgets(line, sizeof(line), stdin);
  1038.             range = atof(line);
  1039.  
  1040.             printf("        Enter mode [1]024 or [2]048 bin mode: ");
  1041.             fgets(line, sizeof(line), stdin);
  1042.             cascading = atoi(line);
  1043.          } else {
  1044.             range = 0;
  1045.             cascading = 0;
  1046.          }
  1047.  
  1048.          if (b->GetDRSType() == 4) {
  1049.             printf("\nPlease make sure that no input signal are present then hit any key\r");
  1050.             fflush(stdout);
  1051.             while (!drs_kbhit());
  1052.             printf("                                                                  \r");
  1053.             while (drs_kbhit())
  1054.                getchar();
  1055.          }
  1056.  
  1057.          for (i=i_start ; i<i_end ; i++) {
  1058.             b = drs->GetBoard(i);
  1059.             if (b->GetTransport() == TR_VME)
  1060.                printf("Creating Calibration of Board in VME slot %2d %s, serial #%04d\n",  
  1061.                        (b->GetSlotNumber() >> 1)+2, ((b->GetSlotNumber() & 1) == 0) ? "upper" : "lower",
  1062.                         b->GetBoardSerialNumber());
  1063.             else
  1064.                printf("Creating Calibration of Board on USB, serial #%04d\n",  
  1065.                         b->GetBoardSerialNumber());
  1066.             if (b->GetDRSType() == 4) {
  1067.                ProgressBar p;
  1068.                if (b->GetTransport() == TR_VME) {
  1069.                   if (cascading == 2)
  1070.                      b->SetChannelConfig(7, 8, 4);  // 7 means read all 9 channels per chip
  1071.                   else
  1072.                      b->SetChannelConfig(7, 8, 8);
  1073.                } else {
  1074.                   if (cascading == 2)
  1075.                      b->SetChannelConfig(0, 8, 4);
  1076.                   else
  1077.                      b->SetChannelConfig(0, 8, 8);
  1078.                }
  1079.  
  1080.                b->SetRefclk(ext_refclk);
  1081.                b->SetFrequency(freq, true);
  1082.                b->SetInputRange(range);
  1083.                b->CalibrateVolt(&p);
  1084.             } else {
  1085.                b->SetDebug(debug);
  1086.                b->Init();
  1087.                b->SetFrequency(freq, true);
  1088.                b->SoftTrigger();
  1089.  
  1090.                if (b->GetDRSType() == 3)
  1091.                   b->GetResponseCalibration()->SetCalibrationParameters(1,11,0,20,0,0,0,0,0);
  1092.                else
  1093.                   b->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,triggerfreq,0);
  1094.                if (!strcmp(dir,"lab"))
  1095.                   b->SetCalibrationDirectory("C:/experiment/calibrations");
  1096.                else if (!strcmp(dir,"area"))
  1097.                   b->SetCalibrationDirectory("/home/meg/meg/online/calibrations");
  1098.                else
  1099.                   b->SetCalibrationDirectory(dir);
  1100.                for (j=0;j<2;j++) {
  1101.                   b->GetResponseCalibration()->ResetCalibration();
  1102.                   while (!b->GetResponseCalibration()->RecordCalibrationPoints(j)) {}
  1103.                   while (!b->GetResponseCalibration()->FitCalibrationPoints(j)) {}
  1104.                   while (!b->GetResponseCalibration()->OffsetCalibration(j)) {}
  1105.                   if (!b->GetResponseCalibration()->WriteCalibration(j))
  1106.                      break;
  1107.                }
  1108.             }
  1109.          }
  1110.       }
  1111.        
  1112.       /* timing calibration ---------- */
  1113.       else if (match(param[0], "tcalib")) {
  1114.          
  1115.          freq = 0;
  1116.          if (param[1][0])
  1117.             freq = atof(param[1]);
  1118.  
  1119.          if (freq == 0) {
  1120.             printf("Enter calibration frequency [GHz]: ");
  1121.             fgets(line, sizeof(line), stdin);
  1122.             freq = atof(line);
  1123.          }
  1124.          
  1125.          for (i=i_start ; i<i_end ; i++) {
  1126.             b = drs->GetBoard(i);
  1127.             if (b->GetDRSType() < 4)
  1128.                printf("Timing calibration not possivle for DRS2 or DRS3\n");
  1129.             else if (b->GetFirmwareVersion() < 13279)
  1130.                printf("Firmware revision 13279 or later required for timing calibration\n");
  1131.             else if (b->GetDRSType() == 4) {
  1132.                printf("Creating Timing Calibration of Board #%d\n", b->GetBoardSerialNumber());
  1133.                ProgressBar p;
  1134.                b->SetFrequency(freq, true);
  1135.                status = b->CalibrateTiming(&p);
  1136.                if (!status)
  1137.                   printf("Error performing timing calibration, please check waveforms\n");
  1138.                printf("\n");
  1139.             }
  1140.          }
  1141.       }
  1142.  
  1143.       /* tcout ---------- */
  1144.       else if (match(param[0], "tcout")) {
  1145.          float time[1024];
  1146.          int chip;
  1147.          int k;
  1148.          int idx = 0;
  1149.          int first_board = i_start;
  1150.          int last_board = i_end;
  1151.  
  1152.          file_name[0] = 0;
  1153.          strcpy(file_name, param[1]);
  1154.          if (file_name[0]) {
  1155.             f = fopen(file_name, "wt");
  1156.             if (f == NULL) {
  1157.                printf("Cannot open file \"%s\"\n", file_name);
  1158.             } else {
  1159.                first_board = 0;
  1160.                last_board = drs->GetNumberOfBoards();
  1161.             }
  1162.             idx += atoi(param[2]);
  1163.          } else
  1164.             f = NULL;
  1165.  
  1166.          if (f) {
  1167.             fprintf(f, "-- Replace %%%% with correct id\n");
  1168.          }
  1169.          for (i=first_board ; i<last_board ; i++) {
  1170.             b = drs->GetBoard(i);
  1171.             if (b->GetDRSType() >= 4) {
  1172.                for (chip = 0; chip < b->GetNumberOfChips(); chip++) {
  1173.                   b->GetTime(chip, 0, b->GetTriggerCell(0), time, true, false);
  1174.                   if (f) {
  1175.                      fprintf(f, "INSERT INTO MEGDRSTimeCalibration VALUES(%%%%,%d,%d", idx,
  1176.                             static_cast<int>(b->GetNominalFrequency() * 10 + 0.5) * 100);
  1177.                      for (j=0 ; j<1024 ; j++)
  1178.                         fprintf(f, ",%g", time[j] * 1e-9);
  1179.                      fprintf(f, ",%d,%d", b->GetBoardSerialNumber(), chip);
  1180.                      fprintf(f, ",%g);\n", 1 / (b->GetNominalFrequency() * 1e9) * 1024);
  1181.                      idx++;
  1182.                   } else {
  1183.                      printf("Board %d\n", b->GetBoardSerialNumber());
  1184.                      for (j=0 ; j<128 ; j++) {
  1185.                         printf("%4d: ", j*8);
  1186.                         for (k=0 ; k<7 ; k++)
  1187.                            printf("%6.1lf ", time[j*8+k]);
  1188.                         printf("%6.1lf\n", time[j*8+k]);
  1189.                      }
  1190.                      printf("n");
  1191.                   }
  1192.                }
  1193.             } else {
  1194.                // DRS2 or DRS3
  1195.                idx += 2;
  1196.             }
  1197.          }
  1198.          if (f) {
  1199.             fclose(f);
  1200.             printf("Data successfully written to \"%s\"\n", file_name);
  1201.          }
  1202.       }
  1203.  
  1204.       /* read */  
  1205.       else if (match(param[0], "read")) {
  1206.          float waveform[2048];
  1207.          short swaveform[2048];
  1208.          calib = 0;
  1209.  
  1210.          file_name[0] = 0;
  1211.          if (param[1][0]) {
  1212.             idx = atoi(param[1]);
  1213.             calib = atoi(param[2]);
  1214.             if (strlen(param[2]) > 2)
  1215.                strcpy(file_name, param[2]);
  1216.             else
  1217.                strcpy(file_name, param[3]);
  1218.          } else {
  1219.             printf("Enter channel number (0..19): ");
  1220.             fgets(line, sizeof(line), stdin);
  1221.             idx = atoi(line);
  1222.          }
  1223.  
  1224.          if (idx<0 || idx>19)
  1225.             printf("Channel number must be between 0 and 19\n");
  1226.          else {
  1227.             b = drs->GetBoard(i_start);
  1228.             if (!b->IsEventAvailable())
  1229.                printf("Error: Domino wave is running, please issue a \"stop\" first\n");
  1230.             else {
  1231.                if (calib == 1) {
  1232.                   if (b->GetDRSType() == 4) {
  1233.                      if (!b->IsVoltageCalibrationValid()) {
  1234.                         printf("Calibration not valid for board #%d\n", b->GetBoardSerialNumber());
  1235.                         calib = 0;
  1236.                      }
  1237.  
  1238.                   } else {
  1239. #ifdef _MSC_VER
  1240.                      b->SetCalibrationDirectory("C:/experiment/calibrations");
  1241. #else
  1242.                      b->SetCalibrationDirectory("/home/meg/meg/online/calibrations");
  1243. #endif
  1244.                      if (!b->GetResponseCalibration()->IsRead(0))
  1245.                         if (!b->GetResponseCalibration()->ReadCalibration(0))
  1246.                            calib = 0;
  1247.                      if (!b->GetResponseCalibration()->IsRead(1))
  1248.                         if (!b->GetResponseCalibration()->ReadCalibration(1))
  1249.                            calib = 0;
  1250.                   }
  1251.                }
  1252.  
  1253.                status = b->TransferWaves(idx, idx);
  1254.                if (file_name[0]) {
  1255.                   f = fopen(file_name, "wt");
  1256.                   if (f == NULL)
  1257.                      printf("Cannot open file \"%s\"\n", file_name);
  1258.                } else
  1259.                   f = NULL;
  1260.  
  1261.                if (calib) {
  1262.                   status = b->GetWave(idx/b->GetNumberOfChannels(), idx%b->GetNumberOfChannels(), waveform,
  1263.                                       true, b->GetTriggerCell(idx/b->GetNumberOfChannels()), b->GetStopWSR(idx/b->GetNumberOfChannels()));
  1264.                   if (status == 0) {
  1265.                      if (f)
  1266.                         for (i=0 ; i<b->GetChannelDepth() ; i++)
  1267.                            fprintf(f, "%6.1lf\n", waveform[i]);
  1268.                      else {
  1269.                         for (i=0 ; i<b->GetChannelDepth()/8 ; i++) {
  1270.                            printf("%4d: ", i*8);
  1271.                            for (j=0 ; j<7 ; j++)
  1272.                               printf("%6.1lf ", waveform[i*8+j]);
  1273.                            printf("%6.1lf\n", waveform[i*8+j]);
  1274.                         }
  1275.                      }
  1276.                   }
  1277.                } else {
  1278.                   status = b->GetWave(idx/b->GetNumberOfChannels(), idx%b->GetNumberOfChannels(), swaveform, 0, 0);
  1279.                   if (status == 0) {
  1280.                      if (f)
  1281.                         for (i=0 ; i<b->GetChannelDepth() ; i++)
  1282.                            fprintf(f, "%4d\n", swaveform[i]);
  1283.                      else {
  1284.                         for (i=0 ; i<b->GetChannelDepth()/16 ; i++) {
  1285.                            for (j=0 ; j<15 ; j++)
  1286.                               printf("%4d ", swaveform[i*16+j] >> 4);
  1287.                            printf("%4d\n", swaveform[i*16+j] >> 4);
  1288.                         }
  1289.                      }
  1290.                   }
  1291.                }
  1292.             }
  1293.          }
  1294.  
  1295.          if (f) {
  1296.             fclose(f);
  1297.             printf("Data successfully written to \"%s\"\n", file_name);
  1298.          }
  1299.       }
  1300.  
  1301.       /* register test ---------- */
  1302.       else if (match(param[0], "reg")) {
  1303.          b->RegisterTest();
  1304.       }
  1305.  
  1306.       /* RAM test */
  1307.       else if (match(param[0], "ram")) {
  1308.          if (param[1][0] == 0)
  1309.             b->RAMTest(3);
  1310.          else
  1311.             b->RAMTest(atoi(param[1]));
  1312.       }
  1313.      
  1314.       /* Change input range */
  1315.       else if (match(param[0], "range")) {
  1316.          for (i=i_start ; i<i_end ; i++) {
  1317.             b = drs->GetBoard(i);
  1318.             if (param[1][0] == 0) {
  1319.                printf("Input range: ");
  1320.                fgets(str, sizeof(str), stdin);
  1321.             } else
  1322.                strlcpy(str, param[1], sizeof(str));
  1323.  
  1324.             b->SetInputRange(atof(str));
  1325.             printf("Range set to %1.2lg V ... %1.2lg V\n", atof(str)-0.5, atof(str)+0.5);
  1326.          }
  1327.       }
  1328.  
  1329.       /* Chip Test */
  1330.       else if (match(param[0], "ct")) {
  1331.          if (drs->GetNumberOfBoards() == 0)
  1332.             puts("No DRS board found");
  1333.          else {
  1334.             puts("Press 'q' to quit, any other key to repeat test.\n");
  1335.             do {
  1336.                if (b->ChipTest())
  1337.                   puts("Chip test successfully finished");
  1338.                else
  1339.                   puts("\007Chip Error!");
  1340.  
  1341.                b->SetStandbyMode(1);
  1342.                for (i=0 ; i<8 ; i++)
  1343.                   b->SetDAC(i, 0);
  1344.                i = getch();
  1345.                b->SetStandbyMode(0);
  1346.             } while (i != 'q');
  1347.          }
  1348.       }
  1349.      
  1350.       /* calib0 for speed vs. temperature calibration */
  1351.       else if (match(param[0], "c0")) {
  1352.          
  1353.          double volt, freq;
  1354.          
  1355.          b->Init();
  1356.          b->SetFrequency(5, true);
  1357.          b->EnableAcal(0, 0);
  1358.          b->SetDominoMode(1);
  1359.  
  1360.          for (volt=2.5 ; volt > 0 ; volt -= 0.05) {
  1361.             printf("%4.1lf - %5.3lf ", b->GetTemperature(), volt);
  1362.             b->SetDAC(1, volt);
  1363.             b->SetDAC(2, volt);
  1364.             Sleep(100);
  1365.             b->ReadFrequency(0, &freq);
  1366.  
  1367.             printf("%5.3lf\n", freq);
  1368.  
  1369.             if (drs_kbhit())
  1370.                break;
  1371.          }
  1372.  
  1373.          while (drs_kbhit())
  1374.             getch();
  1375.  
  1376.          b->Init(); // reset voltage offset
  1377.       }
  1378.  
  1379.       /* calib1 */
  1380.       else if (match(param[0], "c1")) {
  1381.          
  1382.          short swaveform[1024];
  1383.          double volt;
  1384.          double av[1024];
  1385.          int k;
  1386.          
  1387.          b->Init();
  1388.          b->SetFrequency(5, true);
  1389.          b->SetDominoMode(1);
  1390.          b->SetDominoActive(1);
  1391.          b->SetReadoutMode(1);
  1392.  
  1393.          for (volt=-0.5 ; volt <= 0.5001 ; volt += 0.02) {
  1394.             printf("%4.1lf - %6.0lf ", b->GetTemperature(), 1000*volt);
  1395.             b->EnableAcal(1, volt);
  1396.             b->StartDomino();
  1397.             Sleep(100);
  1398.            
  1399.             memset(av, 0, sizeof(av));
  1400.  
  1401.             for (j=0 ; j<100 ; j++) {
  1402.                for (i=0 ; i<10 ; i++)
  1403.                   b->IsBusy();
  1404.                b->SoftTrigger();
  1405.                while (b->IsBusy());
  1406.                b->StartDomino();
  1407.                b->TransferWaves(b->GetNumberOfChannels()*b->GetNumberOfChips());
  1408.                i = b->GetTriggerCell(0);
  1409.                b->GetWave(0, 0, swaveform, false, i, 1);
  1410.  
  1411.                for (k=0 ; k<1024 ; k++)
  1412.                   av[k] += swaveform[k];
  1413.  
  1414.                if (drs_kbhit())
  1415.                   break;
  1416.             }
  1417.  
  1418.             for (k=0 ; k<1024 ; k++)
  1419.                av[k] /= j;
  1420.  
  1421.             for (k=0 ; k<5 ; k++)
  1422.                printf("%10.2lf ", 1000*(av[k]/65536-0.5));
  1423.             printf("\n");
  1424.  
  1425.             if (drs_kbhit())
  1426.                break;
  1427.          }
  1428.          // keep chip "warm"
  1429.          b->StartDomino();
  1430.       }
  1431.  
  1432.       /* test0 */
  1433.       else if (match(param[0], "t0")) {
  1434.          b->Init();
  1435.          b->SetDominoMode(1);
  1436.          b->SetDominoActive(1);
  1437.          b->SetReadoutMode(1);
  1438.          b->SetFrequency(0.8, true);
  1439.          b->EnableTrigger(1, 0);
  1440.          b->SetTriggerLevel(1);
  1441.          b->SetChannelConfig(0, 8, 4);
  1442.  
  1443.          do {
  1444.             b->StartDomino();
  1445.             while (b->IsBusy())
  1446.                if (drs_kbhit())
  1447.                   break;
  1448.  
  1449.             b->TransferWaves();
  1450.  
  1451.             if (b->GetBoardType() == 5) {
  1452.                printf("%04d(0x%03X) - %3d\n", b->GetTriggerCell(0), b->GetTriggerCell(0),
  1453.                   b->GetStopWSR(0));
  1454.             } else {
  1455.                printf("%04d %04d %04d %04d - %3d %3d %3d\n",
  1456.                   b->GetTriggerCell(0),
  1457.                   b->GetTriggerCell(1),
  1458.                   b->GetTriggerCell(2),
  1459.                   b->GetTriggerCell(3),
  1460.                   b->GetTriggerCell(1)-b->GetTriggerCell(0),
  1461.                   b->GetTriggerCell(2)-b->GetTriggerCell(0),
  1462.                   b->GetTriggerCell(3)-b->GetTriggerCell(0));
  1463.             }
  1464.             Sleep(300);
  1465.          } while (!drs_kbhit());
  1466.  
  1467.          while (drs_kbhit())
  1468.             getch();
  1469.       }
  1470.  
  1471.       /* test1 simple start/stop loop */
  1472.       else if (match(param[0], "t1")) {
  1473.          time_t t1, t2;
  1474.          
  1475.          b->SetDebug(1);
  1476.          b->Init();
  1477.          b->SetFrequency(5, true);
  1478.          b->SetDominoMode(1);
  1479.          b->SetReadoutMode(0);
  1480.          b->SetTranspMode(0);
  1481.          b->SetDominoActive(1);
  1482.          b->EnableAcal(1, 0.5);
  1483.          b->EnableTcal(1);
  1484.          time(&t1);
  1485.          do {
  1486.             time(&t2);
  1487.          } while (t1 == t2);
  1488.          i=0;
  1489.          t1 = t2;
  1490.          do {
  1491.             b->StartDomino();
  1492.             b->SoftTrigger();
  1493.             b->TransferWaves();
  1494.             i++;
  1495.             time(&t2);
  1496.             if (t2 > t1) {
  1497.                printf("%d events/sec\n", i);
  1498.                i = 0;
  1499.                t1 = t2;
  1500.             }
  1501.          } while (!drs_kbhit());
  1502.  
  1503.          while (drs_kbhit())
  1504.             getch();
  1505.       }
  1506.  
  1507.       /* test2 readout from stop position */
  1508.       else if (match(param[0], "t2")) {
  1509.          short sw[1024];
  1510.          double volt = 0.5;
  1511.  
  1512.          b->Init();
  1513.          b->SetNumberOfChannels(10);
  1514.          b->SetChannelConfig(0, 9, 12);
  1515.          b->SetFrequency(2, true);
  1516.          b->EnableTcal(1);
  1517.          b->SetReadoutMode(0);
  1518.          b->SetDominoActive(0);
  1519.          b->SetDominoMode(1);
  1520.          b->SetCalibTiming(0, 0);
  1521.          b->StartDomino();
  1522.          b->EnableAcal(1, 0.5);
  1523.          if (!b->GetResponseCalibration()->IsRead(0))
  1524.             if (!b->GetResponseCalibration()->ReadCalibration(0))
  1525.                printf("cannot read calibration\n");
  1526.  
  1527.          do {
  1528.             //volt += 0.25;
  1529.             if (volt > 1)
  1530.                volt = 0;
  1531.             b->SoftTrigger();
  1532.             while (b->IsBusy());
  1533.             b->StartDomino();
  1534.             b->EnableAcal(1, volt);
  1535.             b->TransferWaves();
  1536.  
  1537.             b->GetWave(0, 1, sw, 0, 0);
  1538.             printf("%d ", sw[100]);
  1539.             b->GetWave(0, 1, sw, 1, 0);
  1540.             printf("%1.4lf\n", sw[100]/4096.0);
  1541.          } while (!drs_kbhit());
  1542.          while (drs_kbhit()) getch();
  1543.       }
  1544.  
  1545.       /* DAC Loop */
  1546.       else if (match(param[0], "t3")) {
  1547.          double volt;
  1548.          do {
  1549.             for (volt=2.5 ; volt > 0 ; volt -= 0.05) {
  1550.                
  1551.                printf("%4.1lf - %5.3lf\n", b->GetTemperature(), volt);
  1552.                b->SetDAC(0, volt);
  1553.                b->SetDAC(1, 2.5-volt);
  1554.                Sleep(100);
  1555.                if (drs_kbhit())
  1556.                   break;
  1557.             }
  1558.          } while (!drs_kbhit());
  1559.  
  1560.          while (drs_kbhit())
  1561.             getch();
  1562.       }
  1563.  
  1564.       /* noise measurement */
  1565.       else if (match(param[0], "t4")) {
  1566.          int i, n;
  1567.          short sw[1024];
  1568.          double ofs[1024], sx, sxx, avg, stdev, enob;
  1569.  
  1570.          b->Init();
  1571.          b->SetFrequency(2, true);
  1572.          b->EnableTcal(0);
  1573.          b->SetDominoMode(1);
  1574.          b->StartDomino();
  1575.          b->EnableAcal(1, 0.5);
  1576.          Sleep(100);
  1577.          b->SoftTrigger();
  1578.          while (b->IsBusy());
  1579.          b->StartDomino();
  1580.          Sleep(100);
  1581.          memset(ofs, 0, sizeof(ofs));
  1582.  
  1583.          for (i=0 ; i<10 ; i++) {
  1584.             b->SoftTrigger();
  1585.             while (b->IsBusy());
  1586.             b->StartDomino();
  1587.             b->TransferWaves(1);
  1588.             b->GetWave(0, 0, sw, 0, 0);
  1589.             sx = sxx = 0;
  1590.             for (n=0 ; n<1024 ; n++) {
  1591.                ofs[n] += sw[n];
  1592.             }
  1593.          }
  1594.  
  1595.          for (n=0 ; n<1024 ; n++)
  1596.             ofs[n] /= i;
  1597.  
  1598.          for (i=0 ; i<10 ; i++) {
  1599.             b->SoftTrigger();
  1600.             while (b->IsBusy());
  1601.             b->StartDomino();
  1602.             b->TransferWaves(1);
  1603.             b->GetWave(0, 0, sw, 0, 0);
  1604.  
  1605.             sx = sxx = 0;
  1606.             for (n=10 ; n<1014 ; n++) {
  1607.                sx += (sw[n]-ofs[n])/4096.0;
  1608.                sxx += (sw[n]-ofs[n])/4096.0*(sw[n]-ofs[n])/4096.0;
  1609.             }
  1610.  
  1611.             if (i>5)
  1612.                Sleep(5000);
  1613.  
  1614.             avg = sx / n;
  1615.             stdev = sqrt((sxx-sx*sx/n)/(n-1));
  1616.             enob = log(1/stdev)/log(2.);
  1617.             printf("avg=%1.4lf sd=%1.4lf ENOB=%1.1lf\n", avg, stdev, enob);
  1618.          };
  1619.       }
  1620.  
  1621.       /* exit/quit ---------- */
  1622.       else if (match(param[0], "exit") || match(param[0], "quit"))
  1623.          break;
  1624.  
  1625.       else {
  1626.          if (strchr(param[0], '\r'))
  1627.             *strchr(param[0], '\r') = 0;
  1628.          if (strchr(param[0], '\n'))
  1629.             *strchr(param[0], '\n') = 0;
  1630.          printf("Unknon command \"%s\"\n", param[0]);
  1631.       }
  1632.  
  1633.    } while (1);
  1634.  
  1635.    delete drs;
  1636. }
  1637.  
  1638. /*------------------------------------------------------------------*/
  1639.  
  1640. int main()
  1641. {
  1642.    printf("DRS command line tool, Revision %d\n", atoi(drscl_svn_revision+15));
  1643.    printf("Type 'help' for a list of available commands.\n\n");
  1644.  
  1645.    cmd_loop();
  1646.    return 1;
  1647. }
  1648.