/********************************************************************\
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 <math.h>
#ifdef _MSC_VER
#include <windows.h>
#include <conio.h>
#include <io.h>
#include <direct.h>
#define DIR_SEPARATOR '\\'
#elif defined(OS_LINUX) || defined(OS_DARWIN)
#define O_BINARY 0
#include <unistd.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <errno.h>
#define DIR_SEPARATOR '/'
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <sys/stat.h>
#include <assert.h>
#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 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 <conio.h>
#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 <i>|<i1> <i2>|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 Chip Test");
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 <ghz> [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 <voltage> Set offset voltage");
puts("phase <value> [0|1] Set ADC clock phase and inversion");
puts("quit Exit program");
puts("ram Test speed to FPGA RAM");
puts("range <center> Change input range to <center>+=0.5V");
puts("read <chn> [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 <number> 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 <voltage> 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 <file> Upload ACE file to CF");
puts("volt off|<voltage> 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 ; i<prog/2 ; i++)
printf("=");
printf("\r");
fflush(stdout);
}
/*------------------------------------------------------------------*/
void cmd_loop()
{
int i, j, idx, i_start, i_end, nparam, calib, status, debug, cascading,
ext_refclk;
char str[256], dir[256], line[256], file_name[256], param[10][100], *pc;
double freq, triggerfreq, range;
FILE *f = NULL;
DRS *drs;
DRSBoard *b;
#ifdef HAVE_VME
ACE ace;
#endif
static char bar[] = {'\\', '|', '/', '-'};
/* do initial scan */
drs = new DRS();
if (drs->GetError(str, sizeof(str)))
printf("%s", str);
for (i=0 ; i<drs->GetNumberOfBoards() ; 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 ; i<drs->GetNumberOfBoards() ; 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 ; idx<i_end ; idx++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(i);
b->Init();
}
}
/* set led ---------- */
else if (match(param[0], "led")) {
for (i=i_start ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<drs->GetNumberOfBoards() ; 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 ; i<drs->GetNumberOfBoards() ; 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 ; i<drs->GetNumberOfBoards() ; 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 ; i<drs->GetNumberOfBoards() ; 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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(i);
b->SoftTrigger();
}
}
/* set serial ---------- */
else if (match(param[0], "serial")) {
for (i=i_start ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(i);
b->SetVoltageOffset(atof(param[1]), atof(param[2]));
}
}
/* phase ---------- */
else if (match(param[0], "phase")) {
for (i=i_start ; i<i_end ; i++) {
b = drs->GetBoard(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<i_end ; i++) {
/* do only once per VME board */
if (i_end - i_start > 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<i_end ; i++) {
/* do only once per VME board */
if (i_end - i_start > 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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<i_end ; i++) {
b = drs->GetBoard(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 ; i<last_board ; i++) {
b = drs->GetBoard(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<int>(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 ; i<b->GetChannelDepth() ; i++)
fprintf(f, "%6.1lf\n", waveform[i]);
else {
for (i=0 ; i<b->GetChannelDepth()/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 ; i<b->GetChannelDepth() ; i++)
fprintf(f, "%4d\n", swaveform[i]);
else {
for (i=0 ; i<b->GetChannelDepth()/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 ; i<i_end ; i++) {
b = drs->GetBoard(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")) {
if (drs->GetNumberOfBoards() == 0)
puts("No DRS board found");
else {
puts("Press 'q' to quit, any other key to repeat test.\n");
do {
if (b->ChipTest())
puts("Chip test successfully finished");
else
puts("\007Chip Error!");
b->SetStandbyMode(1);
for (i=0 ; i<8 ; i++)
b->SetDAC(i, 0);
i = getch();
b->SetStandbyMode(0);
} 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()
{
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;
}