/********************************************************************\ Name: drscl.cpp Created by: Stefan Ritt Contents: Command line interface to DRS chip via USB and VME $Id: drscl.cpp 21435 2014-07-30 13:02:31Z ritt $ \********************************************************************/ #include #ifdef _MSC_VER #include #include #include #include #define DIR_SEPARATOR '\\' #elif defined(OS_LINUX) || defined(OS_DARWIN) #define O_BINARY 0 #include #include #include #include #define DIR_SEPARATOR '/' #endif #include #include #include #include #include #include #include #include "strlcpy.h" #include "DRS.h" #ifdef HAVE_VME #include "ace.h" #endif const char *drscl_svn_revision = "$Id: drscl.cpp 21435 2014-07-30 13:02:31Z ritt $"; void lusb(void); void print_help(); void clear_screen(); int match(const char *str, const char *cmd); void cmd_loop(); #if defined(OS_LINUX) || defined(OS_DARWIN) #define getch() getchar() #define Sleep(x) usleep(x*1000) #endif #ifdef _MSC_VER #include #define drs_kbhit() kbhit() #endif void print_help() { puts("Available commands:\n"); puts("active <0|1> Set domino active mode on (1) or off (0)"); puts("board | |all Address individual board/range/all boards"); puts("calib [dir] Response Calibration. Use dir=\"area\" for MEG"); puts("chn [n] Set number of channels: 8, 4, 2, 1"); puts("ct [histo] Chip Test [show histo]"); puts("del <0|1> Switch delayed start on/off"); puts("dir Show CF directory"); puts("dmode <0|1> Set Domino mode 0=single, 1=cont."); puts("et EEPROM test"); puts("exit Exit program"); puts("freq [0|1] Set frequency of board [without/with] regulation"); puts("info Show information about board"); puts("init Initialize board"); puts("led <0|1> Turn LED on (1) or off (0)"); puts("lock [0|1] Display lock status [without/with] restart"); puts("multi [0|1] Turn multi-buffer mode on/off"); puts("offset Set offset voltage"); puts("phase [0|1] Set ADC clock phase and inversion"); puts("quit Exit program"); puts("ram Test speed to FPGA RAM"); puts("range
Change input range to
+=0.5V"); puts("read [0|1] [file] Read waveform to [file], chn=0..19 [with] calibration"); puts("refclk [0|1] Use FPGA ref. clk (0) or ext. P2 ref. clk (1)"); puts("reg Register test"); puts("serial Set serial number of board"); puts("scan Scan for boards"); puts("standby <0|1> Turn standby mode on (1) or off (0)"); puts("start Start domino wave"); puts("stop Issue soft trigger"); puts("tcout [file] [idx_offset] Print time calibration of DRS4, or write it onto [file]"); puts("tcs <0|1> Timing calibration signal on (1) or off (0)"); puts("tcalib [freq] Timing Calibration"); puts("tlevel Set trigger level in Volts"); puts("trans <0|1> Set transparent mode on (1) or off (0)"); puts("trig <0|1> Hardware trigger on (1) or off (0)"); puts("upload Upload ACE file to CF"); puts("volt off| Turn calibration voltage on/off"); puts(""); } /*------------------------------------------------------------------*/ void clear_screen() { #ifdef _MSC_VER HANDLE hConsole; COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */ BOOL bSuccess; DWORD cCharsWritten; CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ DWORD dwConSize; /* number of character cells in the current buffer */ hConsole = GetStdHandle(STD_OUTPUT_HANDLE); /* get the number of character cells in the current buffer */ bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi); dwConSize = csbi.dwSize.X * csbi.dwSize.Y; /* fill the entire screen with blanks */ bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten); /* put the cursor at (0, 0) */ bSuccess = SetConsoleCursorPosition(hConsole, coordScreen); return; #else printf("\033[2J"); #endif } /*------------------------------------------------------------------*/ int match(const char *str, const char *cmd) { int i; if (str[0] == '\r' || str[0] == '\n') return 0; for (i = 0; i < (int) strlen(str); i++) { if (toupper(str[i]) != toupper(cmd[i]) && str[i] != '\r' && str[i] != '\n') return 0; } return 1; } /*------------------------------------------------------------------*/ class ProgressBar : public DRSCallback { public: void Progress(int prog); }; void ProgressBar::Progress(int prog) { if (prog == 0) printf("[--------------------------------------------------]\r"); printf("["); for (int i=0 ; iGetError(str, sizeof(str))) printf("%s", str); for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); #ifdef HAVE_VME if (b->GetTransport() != 1) printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n", b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion()); #else printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n", b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion()); #endif } if (drs->GetNumberOfBoards()) { i_start = 0; i_end = 1; b = drs->GetBoard(0); } else { printf("No DRS Boards found\n"); i_start = i_end = 0; b = NULL; } puts(""); do { /* print prompt */ if (i_start == i_end-1) printf("B%d> ", i_start); else if (i_start == 0 && i_end == 0) printf("> "); else printf("B%d-%d> ", i_start, i_end-1); memset(line, 0, sizeof(line)); fgets(line, sizeof(line), stdin); /* strip \r\n */ while (strpbrk(line,"\n\r")) *strpbrk(line,"\n\r") = 0; /* analyze line */ nparam = 0; pc = line; while (*pc == ' ') pc++; memset(param, 0, sizeof(param)); do { if (*pc == '"') { pc++; for (i = 0; *pc && *pc != '"'; i++) param[nparam][i] = *pc++; if (*pc) pc++; } else if (*pc == '\'') { pc++; for (i = 0; *pc && *pc != '\''; i++) param[nparam][i] = *pc++; if (*pc) pc++; } else if (*pc == '`') { pc++; for (i = 0; *pc && *pc != '`'; i++) param[nparam][i] = *pc++; if (*pc) pc++; } else for (i = 0; *pc && *pc != ' '; i++) param[nparam][i] = *pc++; param[nparam][i] = 0; while (*pc == ' ' || *pc == '\r' || *pc == '\n') pc++; nparam++; } while (*pc); if (param[0][0] == 0) { } /* help ---------- */ else if ((param[0][0] == 'h' && param[0][1] == 'e') || param[0][0] == '?') print_help(); /* scan ---------- */ else if (match(param[0], "scan")) { j = 0; do { delete drs; drs = new DRS(); for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); #ifdef HAVE_VME if (b->GetTransport() != 1) printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n", b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion()); #else printf("Found DRS%d board %2d on USB, serial #%04d, firmware revision %5d\n", b->GetDRSType(), i, b->GetBoardSerialNumber(), b->GetFirmwareVersion()); #endif } if (drs_kbhit()) break; if (param[1][0] == 'r') { printf("%c\r", bar[j]); fflush(stdout); j = (j+1) % 4; Sleep(1000); } } while (param[1][0] == 'r'); while (drs_kbhit()) getch(); if (drs->GetNumberOfBoards()) { i_start = 0; i_end = 1; b = drs->GetBoard(0); } else { printf("No DRS Boards found\n"); i_start = i_end = 0; b = NULL; } } /* address board ---------- */ else if (match(param[0], "board")) { if (param[1][0] == 'a') { i_start = 0; i_end = drs->GetNumberOfBoards(); b = drs->GetBoard(0); } else if (param[2][0] && atoi(param[2]) > 0 && atoi(param[2]) < drs->GetNumberOfBoards()) { i_start = atoi(param[1]); i_end = atoi(param[2]) + 1; b = drs->GetBoard(i_start); } else if (atoi(param[1]) >= 0 && atoi(param[1]) < drs->GetNumberOfBoards()) { i_start = atoi(param[1]); i_end = i_start + 1; b = drs->GetBoard(i_start); } else printf("Board #%d does not exist\n", atoi(param[1])); } /* info ---------- */ else if (match(param[0], "info")) { for (idx=i_start ; idxGetBoard(idx); printf("==============================\n"); printf("Mezz. Board index: %d\n", idx); #ifdef HAVE_VME if (b->GetTransport() == TR_VME) { printf("Slot: %d", (b->GetSlotNumber() >> 1)+2); if ((b->GetSlotNumber() & 1) == 0) printf(" upper\n"); else printf(" lower\n"); } #endif printf("DRS type: DRS%d\n", b->GetDRSType()); printf("Board type: %d\n", b->GetBoardType()); printf("Serial number: %04d\n", b->GetBoardSerialNumber()); printf("Firmware revision: %d\n", b->GetFirmwareVersion()); printf("Temperature: %1.1lf C\n", b->GetTemperature()); if (b->GetDRSType() == 4) { printf("Input range: %1.2lgV...%1.2lgV\n", b->GetInputRange()-0.5, b->GetInputRange()+0.5); printf("Calibrated range: %1.2lgV...%1.2lgV\n", b->GetCalibratedInputRange()-0.5, b->GetCalibratedInputRange()+0.5); printf("Calibrated frequency: %1.3lf GHz\n", b->GetCalibratedFrequency()); if (b->GetTransport() == TR_VME) { printf("Multi Buffer WP: %d\n", b->GetMultiBufferWP()); printf("Multi Buffer RP: %d\n", b->GetMultiBufferRP()); } } printf("Status reg.: %08X\n", b->GetStatusReg()); if (b->GetStatusReg() & BIT_RUNNING) puts(" Domino wave running"); if (b->GetDRSType() == 4) { if (b->GetBoardType() == 5) { if (b->GetStatusReg() & BIT_PLL_LOCKED0) puts(" PLL locked"); } else if (b->GetBoardType() == 6) { i = 0; if (b->GetStatusReg() & BIT_PLL_LOCKED0) i++; if (b->GetStatusReg() & BIT_PLL_LOCKED1) i++; if (b->GetStatusReg() & BIT_PLL_LOCKED2) i++; if (b->GetStatusReg() & BIT_PLL_LOCKED3) i++; if (i == 4) puts(" All PLLs locked"); else if (i == 0) puts(" No PLL locked"); else printf(" %d PLLs locked\n", i); if (b->GetStatusReg() & BIT_LMK_LOCKED) puts(" LMK PLL locked"); } } else { if (b->GetStatusReg() & BIT_NEW_FREQ1) puts(" New Freq1 ready"); if (b->GetStatusReg() & BIT_NEW_FREQ2) puts(" New Freq2 ready"); } printf("Control reg.: %08X\n", b->GetCtrlReg()); if (b->GetCtrlReg() & BIT_MULTI_BUFFER) puts(" Multi-buffering enabled"); if (b->GetDRSType() == 4) { if (b->GetConfigReg() & BIT_CONFIG_DMODE) puts(" DMODE circular"); else puts(" DMODE single shot"); } else { if (b->GetCtrlReg() & BIT_DMODE) puts(" DMODE circular"); else puts(" DMODE single shot"); } if (b->GetCtrlReg() & BIT_LED) puts(" LED"); if (b->GetCtrlReg() & BIT_TCAL_EN) puts(" TCAL enabled"); if (b->GetDRSType() == 4) { if (b->GetCtrlReg() & BIT_TRANSP_MODE) puts(" TRANSP_MODE enabled"); } else { if (b->GetCtrlReg() & BIT_FREQ_AUTO_ADJ) puts(" FREQ_AUTO_ADJ enabled"); } if (b->GetCtrlReg() & BIT_ENABLE_TRIGGER1) puts(" Hardware trigger enabled"); if (b->GetDRSType() == 4) { if (b->GetCtrlReg() & BIT_READOUT_MODE) puts(" Readout from stop"); if (b->GetCtrlReg() & BIT_ENABLE_TRIGGER2) puts(" Internal trigger enabled"); } else { if (b->GetCtrlReg() & BIT_LONG_START_PULSE) puts(" LONG_START_PULSE"); } if (b->GetCtrlReg() & BIT_DELAYED_START) puts(" DELAYED_START"); if (b->GetCtrlReg() & BIT_ACAL_EN) puts(" ACAL enabled"); if (b->GetDRSType() < 4) if (b->GetCtrlReg() & BIT_TRIGGER_DELAYED) puts(" DELAYED_TRIGGER selected"); if (b->GetBoardType() != 5) printf("Trigger bus: %08X\n", b->GetTriggerBus()); if (b->GetDRSType() == 4) { if (b->GetRefclk() == 1) { if (b->IsPLLLocked() && b->IsLMKLocked()) { b->ReadFrequency(0, &freq); printf("Frequency: %1.3lf GHz\n", freq); } else { if (!b->IsPLLLocked()) printf("Frequency: PLL not locked\n"); else printf("Frequency: LMK chip not locked\n"); } } else { if (b->IsPLLLocked()) { b->ReadFrequency(0, &freq); printf("Frequency: %1.3lf GHz\n", freq); } else { printf("Frequency: PLL not locked\n"); } } } else { if (b->IsBusy()) { b->ReadFrequency(0, &freq); printf("Frequency0: %1.4lf GHz\n", freq); b->ReadFrequency(1, &freq); printf("Frequency1: %1.4lf GHz\n", freq); } else puts("Domino wave stopped"); } } } /* init ---------- */ else if (match(param[0], "init")) { for (i=i_start ; iGetBoard(i); b->Init(); } } /* set led ---------- */ else if (match(param[0], "led")) { for (i=i_start ; iGetBoard(i); if (atoi(param[1])) b->SetLED(1); else b->SetLED(0); } } /* set multi buffer mode ---------- */ else if (match(param[0], "multi")) { for (i=i_start ; iGetBoard(i); if (atoi(param[1])) b->SetMultiBuffer(1); else b->SetMultiBuffer(0); } } /* lock status ---------- */ else if (match(param[0], "lock")) { int slot, found, restart; restart = atoi(param[1]); // select external reference clock for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); b->SetRefclk(1); b->SetFrequency(b->GetNominalFrequency(), true); } // loop until keyboard hit do { clear_screen(); printf(" 1 1 1 1 1 1 1 1 1 1 2 2\n"); printf("2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n\n"); // upper slots for (slot = 2 ; slot<22 ; slot++) { found = 0; for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); if ((b->GetSlotNumber() & 1) == 0 && (b->GetSlotNumber() >> 1)+2 == slot) { found = 1; if (b->IsLMKLocked()) printf("O "); else printf("- "); } } if (!found) printf(" "); } printf("\n"); // lower slots for (slot = 2 ; slot<22 ; slot++) { found = 0; for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); if ((b->GetSlotNumber() & 1) == 1 && (b->GetSlotNumber() >> 1)+2 == slot) { found = 1; if (b->IsLMKLocked()) printf("O "); else printf("- "); } } if (!found) printf(" "); } printf("\n"); if (restart) { for (i=0 ; iGetNumberOfBoards() ; i++) { b = drs->GetBoard(i); b->SetFrequency(b->GetNominalFrequency(), true); } } Sleep(300); } while (!drs_kbhit()); puts(""); while (drs_kbhit()) getch(); } /* start domino wave ---------- */ else if (match(param[0], "start")) { for (i=i_start ; iGetBoard(i); b->StartDomino(); b->ReadFrequency(0, &freq); for (j=0 ; j<10 ; j++) if (b->GetDRSType() != 4 || b->IsPLLLocked()) break; if (j == 10) printf("Domino wave started but PLL did not lock!\n"); else printf("Domino wave started at %1.3lf GHz\n", freq); } } /* issue soft trigger ---------- */ else if (match(param[0], "stop")) { for (i=i_start ; iGetBoard(i); b->SoftTrigger(); } } /* set serial ---------- */ else if (match(param[0], "serial")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Serial number: "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); if (!b->SetBoardSerialNumber(atoi(str))) printf("Board EEPROM is write protected\n"); else printf("Serial number successfully changed\n"); } } /* eeprom test ---------- */ else if (match(param[0], "et")) { unsigned short buf[16384]; unsigned short rbuf[16384]; int n_error; do { for (i=0 ; i<16384 ; i++) buf[i] = rand(); b->WriteEEPROM(1, buf, sizeof(buf)); memset(rbuf, 0, sizeof(rbuf)); b->Write(T_RAM, 0, rbuf, sizeof(rbuf)); b->ReadEEPROM(1, rbuf, sizeof(rbuf)); for (i=n_error=0 ; i<16384 ; i++) if (buf[i] != rbuf[i]) { printf("%04X %04X - %04X\n", i, buf[i], rbuf[i]); n_error++; } printf("32 kb written, %d errors\n", n_error); } while (!drs_kbhit()); while (drs_kbhit()) getch(); } /* set frequency ---------- */ else if (match(param[0], "freq")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Frequency: "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); b->SetDebug(1); if (param[2][0] && atoi(param[2])) b->RegulateFrequency(atof(str)); else b->SetFrequency(atof(str), true); } } /* set calibration voltage ---------- */ else if (match(param[0], "volt")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Voltage or \"off\": "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); if (str[0] == 'o') { b->EnableAcal(0, 0); puts("Calibration voltage turned off"); } else { b->EnableAcal(1, atof(str)); printf("Voltage set to %1.3lf Volt\n", atof(str)); } } } /* set channel configuration ---------- */ else if (match(param[0], "chn")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Number of channels (8,4,2,1): "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); if (b->SetChannelConfig(0, 8, atoi(str))) printf("DRS4 configured for %d channels\n", atoi(str)); } } /* set trigger level ---------- */ else if (match(param[0], "tlevel")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Voltage: "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); b->SetTriggerLevel(atof(str)); printf("Trigger level set to %1.3lf Volt\n", atof(str)); } } /* trigger on/off ---------- */ else if (match(param[0], "trig")) { for (i=i_start ; iGetBoard(i); b->EnableTrigger(atoi(param[1]), 0); if (atoi(param[1]) == 1) { puts("Hardware fast trigger is on"); } else if (atoi(param[1]) == 2) { puts("Hardware slow trigger is on"); } else { puts("Hardware trigger is off"); } } } /* timing calibration signal on/off ---------- */ else if (match(param[0], "tcs")) { for (i=i_start ; iGetBoard(i); b->EnableTcal(atoi(param[1]), 0, 0); b->SelectClockSource(0); if (atoi(param[1])) puts("Timing calibration signal is on"); else puts("Timing calibration signal is off"); } } /* timing calibration signal on/off ---------- */ else if (match(param[0], "refclk")) { for (i=i_start ; iGetBoard(i); b->SetRefclk(atoi(param[1])); // re-set frequency since LMK configuration needs to be changed b->SetFrequency(b->GetNominalFrequency(), true); if (atoi(param[1])) puts("Refclock set to external through P2"); else puts("Refclock set to internal (FPGA)"); } } /* domino mode 0/1 ---------- */ else if (match(param[0], "dmode")) { for (i=i_start ; iGetBoard(i); if (atoi(param[1]) == 1) { b->SetDominoMode(1); puts("Domino mode switched to cyclic"); } else { b->SetDominoMode(0); puts("Domino mode switched to single shot"); } } } /* active mode 0/1 ---------- */ else if (match(param[0], "active")) { for (i=i_start ; iGetBoard(i); if (atoi(param[1]) == 1) { b->SetDominoActive(1); puts("Domino wave active during readout"); } else { b->SetDominoMode(0); puts("Domino wave stopped during readout"); } } } /* delayed start on/off ---------- */ else if (match(param[0], "del")) { for (i=i_start ; iGetBoard(i); if (b->GetDRSType() == 4) puts("Delayed start not possible for DRS4"); else { if (atoi(param[1]) == 1) { b->SetDelayedStart(1); puts("Delayed start is on"); } else { b->SetDelayedStart(0); puts("Delayed start is off"); } } } } /* transparent mode on/off ---------- */ else if (match(param[0], "trans")) { for (i=i_start ; iGetBoard(i); if (b->GetDRSType() != 4) puts("Transparen mode only possible for DRS4"); else { if (atoi(param[1]) == 1) { b->SetTranspMode(1); puts("Transparent mode is on"); } else { b->SetTranspMode(0); puts("Transparent mode is off"); } } } } /* standby mode on/off ---------- */ else if (match(param[0], "standby")) { for (i=i_start ; iGetBoard(i); if (b->GetDRSType() != 4) puts("Standby mode only possible for DRS4"); else { if (atoi(param[1]) == 1) { b->SetStandbyMode(1); puts("Standby mode is on"); } else { b->SetStandbyMode(0); puts("Standby mode is off"); } } } } /* offset ---------- */ else if (match(param[0], "offset")) { for (i=i_start ; iGetBoard(i); b->SetVoltageOffset(atof(param[1]), atof(param[2])); } } /* phase ---------- */ else if (match(param[0], "phase")) { for (i=i_start ; iGetBoard(i); b->SetADCClkPhase(atoi(param[1]), atoi(param[2]) > 0); } } /* directory ---------- */ else if (match(param[0], "dir")) { #ifdef HAVE_VME #ifdef CF_VIA_USB { if (param[2][0]) i = atoi(param[2]); else i = 1; printf("Physical drive %d:\n", i); if (ace_init(NULL, i, &ace) != ACE_SUCCESS) { printf("Cannot access ACE on physical drive %d\n", i); } else { #else for (i=i_start ; i 1 && (i % 2) == 1) continue; b = drs->GetBoard(i); printf("VME slot %2d: ", (b->GetSlotNumber() >> 1) + 2); if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) { printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2); } else { #endif ace_dir(&ace); } } #else printf("No VME support compiled into drscl\n"); #endif // HAVE_VME } /* upload ---------- */ else if (match(param[0], "upload")) { #ifdef HAVE_VME #ifdef CF_VIA_USB { if (param[2][0]) i = atoi(param[2]); else i = 1; printf("Physical drive %d:\n", i); if (ace_init(NULL, i, &ace) != ACE_SUCCESS) { printf("Cannot access ACE on physical drive %d\n", i); } else { #else /* use SVN file as default */ if (param[1][0] == 0) { #ifdef _MSC_VER if (b->GetDRSType() == 4) strcpy(str, "c:\\meg\\online\\VPC\\drs4\\2vp30\\cflash\\drs4\\rev0\\rev0.ace"); else if (b->GetDRSType() == 3) strcpy(str, "c:\\meg\\online\\VPC\\drs3\\2vp30\\cflash\\drs3\\rev0\\rev0.ace"); else strcpy(str, "c:\\meg\\online\\VPC\\drs2\\2vp30\\cflash\\drs2\\rev0\\rev0.ace"); #else if (b->GetDRSType() == 4) strcpy(str, "/home/meg/meg/online/VPC/drs4/2vp30/cflash/drs4/rev0/rev0.ace"); else if (b->GetDRSType() == 3) strcpy(str, "/home/meg/meg/online/VPC/drs3/2vp30/cflash/drs3/rev0/rev0.ace"); else strcpy(str, "/home/meg/meg/online/VPC/drs2/2vp30/cflash/drs2/rev0/rev0.ace"); #endif printf("Enter filename or hit return for \n%s\n", str); fgets(line, sizeof(line), stdin); if (line[0] == '\r' || line[0] == '\n') strcpy(file_name, str); else strcpy(file_name, line); strcpy(param[1], str); } else strcpy(file_name, param[1]); for (i=i_start ; i 1 && (i % 2) == 1) continue; b = drs->GetBoard(i); if (b->GetTransport() == TR_USB) { printf("Cannot upload to USB board.\n"); } else { printf("VME slot %d:\n", (b->GetSlotNumber() >> 1)+2); if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) { printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2); } else { #endif status = ace_upload(&ace, file_name); } } } printf("\nPlease issue a power cycle to activate new firmware\n"); #else printf("No VME support compiled into drscl\n"); #endif // HAVE_VME } /* download ---------- */ else if (match(param[0], "download")) { #ifdef HAVE_VME b = drs->GetBoard(i_start); if (b->GetTransport() == TR_USB) { printf("Cannot upload to USB board.\n"); } else { printf("VME slot %d:\n", (b->GetSlotNumber() >> 1)+2); if (ace_init(b->GetVMEInterface(), (b->GetSlotNumber() >> 1)+2, &ace) != ACE_SUCCESS) { printf("Cannot access ACE in slot %d\n", (b->GetSlotNumber() >> 1)+2); } else { strcpy(str, "rev0.ace"); if (param[1][0] == 0) { printf("Enter filename or hit return for \n%s\n", str); fgets(line, sizeof(line), stdin); if (line[0] == '\r' || line[0] == '\n') strcpy(file_name, str); else strcpy(file_name, line); strcpy(param[1], str); } else strcpy(file_name, param[1]); if (strchr(file_name, '\r')) *strchr(file_name, '\r') = 0; if (strchr(file_name, '\n')) *strchr(file_name, '\n') = 0; status = ace_download(&ace, file_name); } } #else printf("No VME support compiled into drscl\n"); #endif // HAVE_VME } /* calibration ---------- */ else if (match(param[0], "calib")) { debug = strcmp(param[1], "debug") == 0 || strcmp(param[2], "debug") == 0 || strcmp(param[3], "debug") == 0; if (param[1][0]) { strlcpy(dir, param[1], sizeof(str)); } else getcwd(dir, sizeof(dir)); while (dir[strlen(dir)-1] == '\n' || dir[strlen(dir)-1] == '\r') dir[strlen(dir)-1] = 0; b = drs->GetBoard(i_start); printf("\n Enter calibration frequency [GHz]: "); fgets(line, sizeof(line), stdin); freq = atof(line); if (b->GetDRSType() == 2) { printf(" Enter the expected trigger frequency [Hz]: "); fgets(line, sizeof(line), stdin); triggerfreq = atof(line); } else triggerfreq = 0; ext_refclk = 0; if (b->GetBoardType() == 6) { printf("Use [e]xternal or [i]nternal reference clock: "); fgets(line, sizeof(line), stdin); ext_refclk = line[0] == 'e'; } if (b->GetDRSType() == 4) { printf(" Enter range [V]: "); fgets(line, sizeof(line), stdin); range = atof(line); printf(" Enter mode [1]024 or [2]048 bin mode: "); fgets(line, sizeof(line), stdin); cascading = atoi(line); } else { range = 0; cascading = 0; } if (b->GetDRSType() == 4) { printf("\nPlease make sure that no input signal are present then hit any key\r"); fflush(stdout); while (!drs_kbhit()); printf(" \r"); while (drs_kbhit()) getchar(); } for (i=i_start ; iGetBoard(i); if (b->GetTransport() == TR_VME) printf("Creating Calibration of Board in VME slot %2d %s, serial #%04d\n", (b->GetSlotNumber() >> 1)+2, ((b->GetSlotNumber() & 1) == 0) ? "upper" : "lower", b->GetBoardSerialNumber()); else printf("Creating Calibration of Board on USB, serial #%04d\n", b->GetBoardSerialNumber()); if (b->GetDRSType() == 4) { ProgressBar p; if (b->GetTransport() == TR_VME) { if (cascading == 2) b->SetChannelConfig(7, 8, 4); // 7 means read all 9 channels per chip else b->SetChannelConfig(7, 8, 8); } else { if (cascading == 2) b->SetChannelConfig(0, 8, 4); else b->SetChannelConfig(0, 8, 8); } b->SetRefclk(ext_refclk); b->SetFrequency(freq, true); b->SetInputRange(range); b->CalibrateVolt(&p); } else { b->SetDebug(debug); b->Init(); b->SetFrequency(freq, true); b->SoftTrigger(); if (b->GetDRSType() == 3) b->GetResponseCalibration()->SetCalibrationParameters(1,11,0,20,0,0,0,0,0); else b->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,triggerfreq,0); if (!strcmp(dir,"lab")) b->SetCalibrationDirectory("C:/experiment/calibrations"); else if (!strcmp(dir,"area")) b->SetCalibrationDirectory("/home/meg/meg/online/calibrations"); else b->SetCalibrationDirectory(dir); for (j=0;j<2;j++) { b->GetResponseCalibration()->ResetCalibration(); while (!b->GetResponseCalibration()->RecordCalibrationPoints(j)) {} while (!b->GetResponseCalibration()->FitCalibrationPoints(j)) {} while (!b->GetResponseCalibration()->OffsetCalibration(j)) {} if (!b->GetResponseCalibration()->WriteCalibration(j)) break; } } } } /* timing calibration ---------- */ else if (match(param[0], "tcalib")) { freq = 0; if (param[1][0]) freq = atof(param[1]); if (freq == 0) { printf("Enter calibration frequency [GHz]: "); fgets(line, sizeof(line), stdin); freq = atof(line); } for (i=i_start ; iGetBoard(i); if (b->GetDRSType() < 4) printf("Timing calibration not possivle for DRS2 or DRS3\n"); else if (b->GetFirmwareVersion() < 13279) printf("Firmware revision 13279 or later required for timing calibration\n"); else if (b->GetDRSType() == 4) { printf("Creating Timing Calibration of Board #%d\n", b->GetBoardSerialNumber()); ProgressBar p; b->SetFrequency(freq, true); status = b->CalibrateTiming(&p); if (!status) printf("Error performing timing calibration, please check waveforms\n"); printf("\n"); } } } /* tcout ---------- */ else if (match(param[0], "tcout")) { float time[1024]; int chip; int k; int idx = 0; int first_board = i_start; int last_board = i_end; file_name[0] = 0; strcpy(file_name, param[1]); if (file_name[0]) { f = fopen(file_name, "wt"); if (f == NULL) { printf("Cannot open file \"%s\"\n", file_name); } else { first_board = 0; last_board = drs->GetNumberOfBoards(); } idx += atoi(param[2]); } else f = NULL; if (f) { fprintf(f, "-- Replace %%%% with correct id\n"); } for (i=first_board ; iGetBoard(i); if (b->GetDRSType() >= 4) { for (chip = 0; chip < b->GetNumberOfChips(); chip++) { b->GetTime(chip, 0, b->GetTriggerCell(0), time, true, false); if (f) { fprintf(f, "INSERT INTO MEGDRSTimeCalibration VALUES(%%%%,%d,%d", idx, static_cast(b->GetNominalFrequency() * 10 + 0.5) * 100); for (j=0 ; j<1024 ; j++) fprintf(f, ",%g", time[j] * 1e-9); fprintf(f, ",%d,%d", b->GetBoardSerialNumber(), chip); fprintf(f, ",%g);\n", 1 / (b->GetNominalFrequency() * 1e9) * 1024); idx++; } else { printf("Board %d\n", b->GetBoardSerialNumber()); for (j=0 ; j<128 ; j++) { printf("%4d: ", j*8); for (k=0 ; k<7 ; k++) printf("%6.1lf ", time[j*8+k]); printf("%6.1lf\n", time[j*8+k]); } printf("n"); } } } else { // DRS2 or DRS3 idx += 2; } } if (f) { fclose(f); printf("Data successfully written to \"%s\"\n", file_name); } } /* read */ else if (match(param[0], "read")) { float waveform[2048]; short swaveform[2048]; calib = 0; file_name[0] = 0; if (param[1][0]) { idx = atoi(param[1]); calib = atoi(param[2]); if (strlen(param[2]) > 2) strcpy(file_name, param[2]); else strcpy(file_name, param[3]); } else { printf("Enter channel number (0..19): "); fgets(line, sizeof(line), stdin); idx = atoi(line); } if (idx<0 || idx>19) printf("Channel number must be between 0 and 19\n"); else { b = drs->GetBoard(i_start); if (!b->IsEventAvailable()) printf("Error: Domino wave is running, please issue a \"stop\" first\n"); else { if (calib == 1) { if (b->GetDRSType() == 4) { if (!b->IsVoltageCalibrationValid()) { printf("Calibration not valid for board #%d\n", b->GetBoardSerialNumber()); calib = 0; } } else { #ifdef _MSC_VER b->SetCalibrationDirectory("C:/experiment/calibrations"); #else b->SetCalibrationDirectory("/home/meg/meg/online/calibrations"); #endif if (!b->GetResponseCalibration()->IsRead(0)) if (!b->GetResponseCalibration()->ReadCalibration(0)) calib = 0; if (!b->GetResponseCalibration()->IsRead(1)) if (!b->GetResponseCalibration()->ReadCalibration(1)) calib = 0; } } status = b->TransferWaves(idx, idx); if (file_name[0]) { f = fopen(file_name, "wt"); if (f == NULL) printf("Cannot open file \"%s\"\n", file_name); } else f = NULL; if (calib) { status = b->GetWave(idx/b->GetNumberOfChannels(), idx%b->GetNumberOfChannels(), waveform, true, b->GetTriggerCell(idx/b->GetNumberOfChannels()), b->GetStopWSR(idx/b->GetNumberOfChannels())); if (status == 0) { if (f) for (i=0 ; iGetChannelDepth() ; i++) fprintf(f, "%6.1lf\n", waveform[i]); else { for (i=0 ; iGetChannelDepth()/8 ; i++) { printf("%4d: ", i*8); for (j=0 ; j<7 ; j++) printf("%6.1lf ", waveform[i*8+j]); printf("%6.1lf\n", waveform[i*8+j]); } } } } else { status = b->GetWave(idx/b->GetNumberOfChannels(), idx%b->GetNumberOfChannels(), swaveform, 0, 0); if (status == 0) { if (f) for (i=0 ; iGetChannelDepth() ; i++) fprintf(f, "%4d\n", swaveform[i]); else { for (i=0 ; iGetChannelDepth()/16 ; i++) { for (j=0 ; j<15 ; j++) printf("%4d ", swaveform[i*16+j] >> 4); printf("%4d\n", swaveform[i*16+j] >> 4); } } } } } } if (f) { fclose(f); printf("Data successfully written to \"%s\"\n", file_name); } } /* register test ---------- */ else if (match(param[0], "reg")) { b->RegisterTest(); } /* RAM test */ else if (match(param[0], "ram")) { if (param[1][0] == 0) b->RAMTest(3); else b->RAMTest(atoi(param[1])); } /* Change input range */ else if (match(param[0], "range")) { for (i=i_start ; iGetBoard(i); if (param[1][0] == 0) { printf("Input range: "); fgets(str, sizeof(str), stdin); } else strlcpy(str, param[1], sizeof(str)); b->SetInputRange(atof(str)); printf("Range set to %1.2lg V ... %1.2lg V\n", atof(str)-0.5, atof(str)+0.5); } } /* Chip Test */ else if (match(param[0], "ct")) { b->SetStandbyMode(0); Sleep(500); if (drs->GetNumberOfBoards() == 0) puts("No DRS board found"); else { puts("Press 'q' to quit, any other key to repeat test.\n"); do { b->ChipTest(param[1][0] > 0); b->SetStandbyMode(1); for (i=0 ; i<8 ; i++) b->SetDAC(i, 0); i = getch(); b->SetStandbyMode(0); Sleep(500); } while (i != 'q'); } } /* calib0 for speed vs. temperature calibration */ else if (match(param[0], "c0")) { double volt, freq; b->Init(); b->SetFrequency(5, true); b->EnableAcal(0, 0); b->SetDominoMode(1); for (volt=2.5 ; volt > 0 ; volt -= 0.05) { printf("%4.1lf - %5.3lf ", b->GetTemperature(), volt); b->SetDAC(1, volt); b->SetDAC(2, volt); Sleep(100); b->ReadFrequency(0, &freq); printf("%5.3lf\n", freq); if (drs_kbhit()) break; } while (drs_kbhit()) getch(); b->Init(); // reset voltage offset } /* calib1 */ else if (match(param[0], "c1")) { short swaveform[1024]; double volt; double av[1024]; int k; b->Init(); b->SetFrequency(5, true); b->SetDominoMode(1); b->SetDominoActive(1); b->SetReadoutMode(1); for (volt=-0.5 ; volt <= 0.5001 ; volt += 0.02) { printf("%4.1lf - %6.0lf ", b->GetTemperature(), 1000*volt); b->EnableAcal(1, volt); b->StartDomino(); Sleep(100); memset(av, 0, sizeof(av)); for (j=0 ; j<100 ; j++) { for (i=0 ; i<10 ; i++) b->IsBusy(); b->SoftTrigger(); while (b->IsBusy()); b->StartDomino(); b->TransferWaves(b->GetNumberOfChannels()*b->GetNumberOfChips()); i = b->GetTriggerCell(0); b->GetWave(0, 0, swaveform, false, i, 1); for (k=0 ; k<1024 ; k++) av[k] += swaveform[k]; if (drs_kbhit()) break; } for (k=0 ; k<1024 ; k++) av[k] /= j; for (k=0 ; k<5 ; k++) printf("%10.2lf ", 1000*(av[k]/65536-0.5)); printf("\n"); if (drs_kbhit()) break; } // keep chip "warm" b->StartDomino(); } /* test0 */ else if (match(param[0], "t0")) { b->Init(); b->SetDominoMode(1); b->SetDominoActive(1); b->SetReadoutMode(1); b->SetFrequency(0.8, true); b->EnableTrigger(1, 0); b->SetTriggerLevel(1); b->SetChannelConfig(0, 8, 4); do { b->StartDomino(); while (b->IsBusy()) if (drs_kbhit()) break; b->TransferWaves(); if (b->GetBoardType() == 5) { printf("%04d(0x%03X) - %3d\n", b->GetTriggerCell(0), b->GetTriggerCell(0), b->GetStopWSR(0)); } else { printf("%04d %04d %04d %04d - %3d %3d %3d\n", b->GetTriggerCell(0), b->GetTriggerCell(1), b->GetTriggerCell(2), b->GetTriggerCell(3), b->GetTriggerCell(1)-b->GetTriggerCell(0), b->GetTriggerCell(2)-b->GetTriggerCell(0), b->GetTriggerCell(3)-b->GetTriggerCell(0)); } Sleep(300); } while (!drs_kbhit()); while (drs_kbhit()) getch(); } /* test1 simple start/stop loop */ else if (match(param[0], "t1")) { time_t t1, t2; b->SetDebug(1); b->Init(); b->SetFrequency(5, true); b->SetDominoMode(1); b->SetReadoutMode(0); b->SetTranspMode(0); b->SetDominoActive(1); b->EnableAcal(1, 0.5); b->EnableTcal(1); time(&t1); do { time(&t2); } while (t1 == t2); i=0; t1 = t2; do { b->StartDomino(); b->SoftTrigger(); b->TransferWaves(); i++; time(&t2); if (t2 > t1) { printf("%d events/sec\n", i); i = 0; t1 = t2; } } while (!drs_kbhit()); while (drs_kbhit()) getch(); } /* test2 readout from stop position */ else if (match(param[0], "t2")) { short sw[1024]; double volt = 0.5; b->Init(); b->SetNumberOfChannels(10); b->SetChannelConfig(0, 9, 12); b->SetFrequency(2, true); b->EnableTcal(1); b->SetReadoutMode(0); b->SetDominoActive(0); b->SetDominoMode(1); b->SetCalibTiming(0, 0); b->StartDomino(); b->EnableAcal(1, 0.5); if (!b->GetResponseCalibration()->IsRead(0)) if (!b->GetResponseCalibration()->ReadCalibration(0)) printf("cannot read calibration\n"); do { //volt += 0.25; if (volt > 1) volt = 0; b->SoftTrigger(); while (b->IsBusy()); b->StartDomino(); b->EnableAcal(1, volt); b->TransferWaves(); b->GetWave(0, 1, sw, 0, 0); printf("%d ", sw[100]); b->GetWave(0, 1, sw, 1, 0); printf("%1.4lf\n", sw[100]/4096.0); } while (!drs_kbhit()); while (drs_kbhit()) getch(); } /* DAC Loop */ else if (match(param[0], "t3")) { double volt; do { for (volt=2.5 ; volt > 0 ; volt -= 0.05) { printf("%4.1lf - %5.3lf\n", b->GetTemperature(), volt); b->SetDAC(0, volt); b->SetDAC(1, 2.5-volt); Sleep(100); if (drs_kbhit()) break; } } while (!drs_kbhit()); while (drs_kbhit()) getch(); } /* noise measurement */ else if (match(param[0], "t4")) { int i, n; short sw[1024]; double ofs[1024], sx, sxx, avg, stdev, enob; b->Init(); b->SetFrequency(2, true); b->EnableTcal(0); b->SetDominoMode(1); b->StartDomino(); b->EnableAcal(1, 0.5); Sleep(100); b->SoftTrigger(); while (b->IsBusy()); b->StartDomino(); Sleep(100); memset(ofs, 0, sizeof(ofs)); for (i=0 ; i<10 ; i++) { b->SoftTrigger(); while (b->IsBusy()); b->StartDomino(); b->TransferWaves(1); b->GetWave(0, 0, sw, 0, 0); sx = sxx = 0; for (n=0 ; n<1024 ; n++) { ofs[n] += sw[n]; } } for (n=0 ; n<1024 ; n++) ofs[n] /= i; for (i=0 ; i<10 ; i++) { b->SoftTrigger(); while (b->IsBusy()); b->StartDomino(); b->TransferWaves(1); b->GetWave(0, 0, sw, 0, 0); sx = sxx = 0; for (n=10 ; n<1014 ; n++) { sx += (sw[n]-ofs[n])/4096.0; sxx += (sw[n]-ofs[n])/4096.0*(sw[n]-ofs[n])/4096.0; } if (i>5) Sleep(5000); avg = sx / n; stdev = sqrt((sxx-sx*sx/n)/(n-1)); enob = log(1/stdev)/log(2.); printf("avg=%1.4lf sd=%1.4lf ENOB=%1.1lf\n", avg, stdev, enob); }; } /* exit/quit ---------- */ else if (match(param[0], "exit") || match(param[0], "quit")) break; else { if (strchr(param[0], '\r')) *strchr(param[0], '\r') = 0; if (strchr(param[0], '\n')) *strchr(param[0], '\n') = 0; printf("Unknon command \"%s\"\n", param[0]); } } while (1); delete drs; } /*------------------------------------------------------------------*/ int main(int argc, char *argv[]) { if (argc == 2 && argv[1][1] == 'l') { lusb(); return 0; } printf("DRS command line tool, Revision %d\n", atoi(drscl_svn_revision+15)); printf("Type 'help' for a list of available commands.\n\n"); cmd_loop(); return 1; }