//#include "tabela.h"
 
//#include "proba.h"
 
 
 
 
 
#include "vme.h"
 
 
 
//#define PTS_ADDR 0x025F0000
 
//#define PTS_ADDR 0x26000000
 
 
 
#include "PtsModule.h"
 
#define PTS_ADDR 0x61000000
 
#include <windows.h>
 
#include <formatio.h>
 
#include <analysis.h>
 
#include "toolbox.h"
 
#include <cvirte.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
 
 
#include <string.h>
 
#include <ctype.h>
 
#include <stdint.h>
 
 
 
#include <signal.h>
 
#include <utility.h>
 
#include <ansi_c.h>
 
#include <userint.h>
 
#include "toolbox.h"
 
 
 
#include "sa02lib.h"
 
#include "CAEN_V729.h"
 
#include "CAEN_V729_CVI.h"
 
#include "icfa.h"
 
 
 
#include "MIKRO.h"
 
const int dsize = 144*4;
 
 
 
#include "H1D.h"
 
#include "H2D.h"
 
#include "H3D.h"
 
#include "HDraw.h"
 
#include "dataio.h"
 
#include "sa02lib.h"
 
#include "sa02_CVI.h"
 
 
 
int ProcessUserEvent(int pID, int rID,int mode);
 
 
 
const char  palaser[0xFF]="\"C:\\home\\software\\daq\\LaserDriver-Ver2.0\\Particulars LASER control.exe\"";
 
 
 
#define MAX_THREADS 10
 
const char slowcname[20][20]= {"TMON0","TMON1","VDD","V2P","V2N","VSS","VTH1","VTH2", "VCC12", "VCC15" ,"VCC25", "V38P" };
 
const int chart_control[4]= {P1_CHART_1,P1_CHART_2,P1_CHART_3,P1_CHART_4};
 
const int hapd_serials [4]= { P1_SERIAL_1, P1_SERIAL_2, P1_SERIAL_3, P1_SERIAL_4 };
 
const int fpga_serials [4]= { P1_SERIAL_FPGA_1, P1_SERIAL_FPGA_2, P1_SERIAL_FPGA_3, P1_SERIAL_FPGA_4 };
 
const int hapd_onoff   [4]= { P1_ONOFF_1, P1_ONOFF_2, P1_ONOFF_3, P1_ONOFF_4 };
 
const int p2graph   [4]= { P2_GRAPH_1, P2_GRAPH_2, P2_GRAPH_3, P2_GRAPH_4 };
 
 
 
#define PTS_ADDR 0x61000000
 
 
 
#define MIKRO_COM 4
 
#define MIKRO_X 1
 
#define MIKRO_Y 2
 
#define MIKRO_Z 3
 
 
 
#define TRUE 1
 
#define FALSE 0
 
#define TIMEOUT 3
 
 
 
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
 
uint32_t gVME_CONTROLLER=WIENER_VMEMM;
 
uint32_t gCAEN_V288=0;
 
uint32_t gBELLEPTS=PTS_ADDR;
 
uint32_t gMIKRO_PORT=MIKRO_COM;
 
uint32_t gMIKRO_X=MIKRO_X, gMIKRO_Y=MIKRO_Y, gMIKRO_Z=MIKRO_Y;
 
uint32_t gCENTER_X=176000, gCENTER_Y=170000;
 
double gCENTER_KX=6./300, gCENTER_KY=3./300;
 
uint32_t gCAEN_V729=0;
 
uint32_t gCAEN_V1495=0;
 
uint32_t gFEBParamRead=0;
 
uint32_t gFEBMask=0xF;
 
uint32_t gTriggerType=2;
 
char gFEBParam[0xFF]="";
 
 
 
uint32_t uInterf = 0;
 
 
 
RUNINFO runinfo;
 
RUNREC runrec;
 
ENDREC endrec;
 
POSREC posrec;
 
EVTREC evtrec;
 
EVTREC evtrec1;
 
DATREC datrec;
 
MONREC monrec;
 
ITERATORREC iteratorrec;
 
 
 
 
 
typedef struct {
 
  int chip;
 
  int ch;
 
  int chx;
 
  int chy;
 
} EID2HAPDY;
 
 
 
EID2HAPDY eid2hapdxy[144];
 
 
 
// Variables
 
static int p1h, pID, rID, tfID;
 
static int p2h;
 
static int p3h;
 
static int p4h;
 
static int p5h;
 
static int pm1;
 
static int daq_on,loop_on;
 
static CmtThreadPoolHandle poolHandle = 0;
 
static CmtTSQHandle  pTSQ = 0;
 
static int pTSQData[2];
 
 
 
double datay[10000];
 
double datax[10000];
 
double datayfit[10000];
 
 
 
//const int mux_map[4]={ 1,3,0,2};
 
 
 
int ctrl_c=0;
 
int integer_val=0;
 
FILE *gFp=NULL;
 
 
 
//***********************VARIABLE ZA BRANJE NAPETOSTI***********************//
 
 
 
#include "CAENV288.h"
 
 
 
#define ReadOperationalParam  0x02 //N470
 
#define TurnChanelOn          0x0a //N470  
 
#define TurnChanelOff         0x0b //N470  
 
#define ReadStatus            0x01 //SYS403
 
#define ReadParameters        0x02 //SYS403
 
 
 
int hvmon=0;
 
int hvmonFirst=0;
 
int32_t vset[24], iset[24];
 
 
 
 
 
// reads the run number from the first line in the file
 
int GetRunNumberFromFile(char *fname) {
 
  char line[MAX_PATHNAME_LEN];
 
  int ndim= MAX_PATHNAME_LEN;
 
  int current_run = -1;
 
  FILE *fp = NULL;
 
  ssize_t size;
 
 
 
  if ( GetFileInfo
(fname
,&size
) ) fp 
= fopen(fname
,"r");  
 
 
  if (fp) {
 
    if (fgets(line
,ndim
,fp
)!= NULL
) current_run 
= atoi(line
);  
  }
 
  return current_run;
 
 
 
}
 
 
 
int IncreaseRunNumberInFile(char *fname) {
 
 
 
  int current_run = GetRunNumberFromFile(fname);
 
  FILE 
*fp 
= fopen(fname
,"w"); 
 
 
  if (fp) {
 
  }
 
  return current_run+1;
 
}
 
 
 
 
 
//**************************** get station parameters from ini file
 
int readIni(char *fname) {
 
 
 
  FILE *fp = NULL;
 
  char cmd[0xFF],val[0xFF];
 
  int ndim=400;
 
  char line[ndim];
 
  ssize_t size;
 
 
 
  if ( GetFileInfo
(fname
,&size
) ) fp 
= fopen(fname
,"r");  
  if (!fp) {
 
    sprintf(line
, "%s not found. Using default values.\n",fname
);  
    MessagePopup ("Info", line);
 
    return -1;
 
  }
 
  while (fgets(line
,ndim
,fp
)!=NULL
) {  
    if (cmd[0]=='#') continue;
 
    if ( strstr(cmd
,"VME_CONTROLLER")!= NULL 
) {  
      if ( strstr(val
,"WIENER_VMUSB")!= NULL 
) gVME_CONTROLLER
=WIENER_VMUSB
;  
      if ( strstr(val
,"WIENER_VMEMM")!= NULL 
) gVME_CONTROLLER
=WIENER_VMEMM
;  
      if ( strstr(val
,"CAEN_V1718")  != NULL 
) gVME_CONTROLLER
=CAEN_V1718
;  
      if ( strstr(val
,"SIS3153_USB")  != NULL 
) gVME_CONTROLLER
=SIS3153_USB
;  
    }
 
    if ( strstr(cmd
,"CAEN_V288" )!= NULL 
) gCAEN_V288 
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"BELLEPTS")  != NULL 
) gBELLEPTS  
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"CAEN_V1495")  != NULL 
) gCAEN_V1495  
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"MIKRO_PORT")!= NULL 
) gMIKRO_PORT
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"MIKRO_X")   != NULL 
) gMIKRO_X   
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"MIKRO_Y")   != NULL 
) gMIKRO_Y   
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"MIKRO_Z")   != NULL 
) gMIKRO_Z   
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"CENTER_X")   != NULL 
) gCENTER_X   
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"CENTER_Y")   != NULL 
) gCENTER_Y   
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"CENTER_KX")   != NULL 
) gCENTER_KX   
=strtod(val
,NULL
);  
    if ( strstr(cmd
,"CENTER_KY")   != NULL 
) gCENTER_KY   
=strtod(val
,NULL
);  
    if ( strstr(cmd
,"CAEN_V729") != NULL 
) gCAEN_V729 
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"FEBParam") != NULL 
) sprintf(gFEBParam
,"%s", val
);  
    if ( strstr(cmd
,"FEBMask") != NULL 
) gFEBMask 
=strtoul(val
,NULL
,0);  
    if ( strstr(cmd
,"TriggerType") != NULL 
) gTriggerType 
=strtoul(val
,NULL
,0);  
  }
 
  return 0;
 
}
 
//**************************** missing declarations in the library
 
char strbuf[0xFF];
 
 
 
int gLog=0;
 
int sa02Printf(const char *format, ...) {
 
  va_list aptr;
 
  int ret;
 
  FILE *flog;
 
 
 
  SetCtrlVal(p1h,P1_STDIO,strbuf);
 
 
 
  if (gLog) {
 
    flog 
= fopen ("stdio.log", "a"); 
  }
 
  return(ret);
 
}
 
 
 
 
 
int CVICALLBACK sa02timeout (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_TIMER_TICK:
 
      sa02TimerOut = TRUE;
 
      sa02Printf("sa02timeout\n");
 
      //sa02Printf("TIMEOUT %s in line %d\n", __FILE__ , __LINE__);
 
      break;
 
  }
 
  return 0;
 
}
 
void sa02Timerast (int signumber) {
 
  sa02TimerOut = TRUE;
 
  sa02Printf("TIMEOUT !!!\n");
 
  SetCtrlAttribute (p1h, P1_DAQ_TIMEOUT, ATTR_ENABLED, 0);
 
}
 
 
 
void sa02Tmlnk (int tout) {
 
  sa02TimerOut = FALSE;
 
  SetCtrlAttribute (p1h, P1_DAQ_TIMEOUT, ATTR_INTERVAL,
 
                    (float)tout/100.);
 
  SetCtrlAttribute (p1h, P1_DAQ_TIMEOUT, ATTR_ENABLED, 1);
 
  //  ResetTimer (p1h, P1_DAQ_TIMEOUT);
 
}
 
 
 
void sa02Tmulk ( void ) {
 
  SetCtrlAttribute (p1h, P1_DAQ_TIMEOUT, ATTR_ENABLED, 0);
 
}
 
//****************************
 
 
 
 
 
int EscapeString(const char *i, char *o) {
 
  unsigned int iptr=0, optr = 0;
 
  // walk though the input string
 
  for (iptr 
= 0; iptr 
< strlen(i
); iptr
++, optr
++) {  
    // search for
 
    if ( (i[iptr]=='\\') ) {
 
      sa02Printf("Escape String %d %d \n",i[iptr] , i[iptr]==92 ) ;
 
      //sa02Printf("Escape String %d %d \n",i[iptr] , ( (i[iptr] == 92) || (i[iptr] == 42) )) ;
 
      o[optr] = i[iptr];
 
      optr++;
 
    }
 
 
 
    o[optr] = i[iptr];
 
  }
 
 
 
  o[optr] = '\0';
 
 
 
 
 
  return 0;
 
}
 
 
 
 
 
 
 
int p1plothandle=0;
 
int p2plothandle[4]= {0,0,0,0};
 
int p3plothandle=0;
 
 
 
int plothandle=0;
 
 
 
int phandle[4]= {0,0,0,0};
 
 
 
 
 
int plothandle2dfit=0;
 
int plothandleslix=0;
 
int plothandlesliy=0;
 
int plothandlefit=0;
 
 
 
void SigInt (int sig) {
 
  ctrl_c = 1;
 
  sa02TimerOut=1;
 
}
 
 
 
//int sa02Verbose=0;
 
int module_header(int recid,uint32_t *data,int len) {
 
  data[0] = recid;
 
  data[1] = (len >0)? len : 0 ;
 
  return data[1]+2;
 
}
 
 
 
int PrintData(uint32_t *rdata, int count) {
 
  int j;
 
  uint32_t i;
 
  for (j=0; j<count; j++) {
 
    uint32_t recid   = rdata[j++];
 
    uint32_t len     = rdata[j++];
 
    sa02Printf(" recid=0x%0x len=%d pos=%d(maxpos %d) val=",recid, len, j, count);
 
    if (len>2) {
 
      sa02Printf("\n");
 
    }
 
    for (i=0; i<len; i++) {
 
      if (j< count) {
 
        sa02Printf("0x%0x\t", rdata[j]);
 
      }
 
      if (i%4==3) {
 
        sa02Printf("\n");
 
      }
 
      j++;
 
    }
 
    sa02Printf("\n");
 
    if (len) {
 
      j--;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
//-------------------------------------------------------------------------
 
int CVICALLBACK PlotSliceY (int panel, int control, int event,
 
                            void *callbackData, int eventData1, int eventData2) {
 
  int nslice,i;
 
  int h2=(int) callbackData;
 
 
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int ny       =  H2DGetNbinsY(h2);
 
      double miny  =  H2DGetMinY(h2);
 
      double stepy =  H2DGetStepY(h2);
 
      GetCtrlVal(panel,P1_NSLIX,&nslice);
 
 
 
      for (i=0; i < ny; i++ ) {
 
        datax[i]=H2DGetBinContent(h2,nslice,i);
 
      }
 
      if (ny>0) {
 
        if (plothandleslix) {
 
          DeleteGraphPlot (p1h, P1_GRAPHY, plothandleslix, VAL_IMMEDIATE_DRAW);
 
        }
 
 
 
        plothandleslix = PlotWaveform (p1h, P1_GRAPHY, datax, ny,
 
                                       VAL_DOUBLE, 1.0, 0.0, miny,
 
                                       stepy, VAL_FAT_LINE,
 
                                       VAL_EMPTY_SQUARE, VAL_SOLID, 1,
 
                                       VAL_BLUE);
 
      }
 
 
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK PlotSliceX (int panel, int control, int event,
 
                            void *callbackData, int eventData1, int eventData2) {
 
  int nslice,i;
 
  int h2=(int) callbackData;
 
 
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int nx       =  H2DGetNbinsX(h2);
 
      double minx  =  H2DGetMinX(h2);
 
      double stepx =  H2DGetStepX(h2);
 
      GetCtrlVal(panel,P1_NSLIY,&nslice);
 
      for (i=0; i < nx; i++ ) {
 
        datax[i]=H2DGetBinContent(h2,i,nslice);
 
      }
 
      if (nx>0) {
 
        if (plothandlesliy) {
 
          DeleteGraphPlot (p1h, P1_GRAPHX, plothandlesliy, VAL_IMMEDIATE_DRAW);
 
        }
 
 
 
        plothandlesliy = PlotWaveform (p1h, P1_GRAPHX, datax, nx,
 
                                       VAL_DOUBLE, 1.0, 0.0, minx,
 
                                       stepx, VAL_FAT_LINE,
 
                                       VAL_EMPTY_SQUARE, VAL_SOLID, 1,
 
                                       VAL_BLUE);
 
      }
 
 
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
 
 
void plot1d(int npoints, double x0, double dx) {
 
  sa02Printf("TEST %d\n", npoints);
 
  if (npoints>0) {
 
    if (plothandle) {
 
      DeleteGraphPlot (p1h, P1_GRAPH, plothandle, VAL_IMMEDIATE_DRAW);
 
    }
 
    plothandle = PlotWaveform (p1h, P1_GRAPH, datay, npoints, VAL_DOUBLE,
 
                               1.0, 0.0, x0, dx, VAL_CONNECTED_POINTS,
 
                               VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_BLUE);
 
  }
 
}
 
 
 
/*
 
void plotxy(int h2d){
 
  if (plothandlexy > 0 ) DeleteGraphPlot (p2h, P2_GRAPHXY, plothandlexy, VAL_IMMEDIATE_DRAW);
 
  RangeColors(H2DGetMin(h2d),H2DGetMax(h2d));
 
  plothandlexy = PlotScaledIntensity (p2h, P2_GRAPHXY, H2DGetData(h2d),
 
                   H2DGetNbinsX(h2d), H2DGetNbinsY(h2d), VAL_DOUBLE,
 
                   H2DGetStepY(h2d),H2DGetMinY(h2d),H2DGetStepX(h2d),H2DGetMinX(h2d),
 
                   colormap->array,
 
                   colormap->HiColor,
 
                   colormap->numberofColors, 1, 0);
 
  ProcessSystemEvents ();
 
}
 
*/
 
 
 
int CVICALLBACK ZoomToFebCB (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  int feb=-1;
 
  float xmin=0, xmax=0;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal(panel,control,&feb);
 
      switch (feb) {
 
        case -1:
 
          xmin=0;
 
          xmax=144*4-1;
 
          break;
 
        default:
 
          xmin =  feb *144;
 
          xmax =xmin+144 -1;
 
          break;
 
      }
 
      SetAxisRange (p1h, P1_GRAPH2D, VAL_MANUAL, xmin, xmax, VAL_NO_CHANGE, 0.0, 1.0);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
 
 
 
 
void plot2d(int h2d, int nslice) {
 
  if  (nslice < 0 ) {
 
    nslice=0;
 
  }
 
  if (plothandle2dfit > 0 ) {
 
    DeleteGraphPlot (p1h, P1_GRAPH2D, plothandle2dfit, VAL_IMMEDIATE_DRAW);
 
    plothandle2dfit=0;
 
  }
 
  H2DDraw(h2d,p1h, P1_GRAPH2D, &p1plothandle);
 
 
 
  if (sa02Verbose > 2) {
 
    sa02Printf("min %f max %f  x:min %f step%f y:min %f step%f\n",
 
               H2DGetMin(h2d),H2DGetMax(h2d), H2DGetMinX(h2d),
 
               H2DGetStepX(h2d),H2DGetMinY(h2d), H2DGetStepY(h2d));
 
  }
 
  SetCtrlVal(p1h, P1_NSLIY, nslice);
 
  PlotSliceX(p1h,P1_GRAPHY,EVENT_COMMIT, NULL,0,0);
 
  PlotSliceY(p1h,P1_GRAPHY,EVENT_COMMIT, NULL,0,0);
 
  ProcessSystemEvents ();
 
}
 
 
 
void SetDimming(int state) {
 
  SetCtrlAttribute (p1h, P1_MULTIFPGAWRITE, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p1h, P1_DAQ, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p1h, P1_READOUT, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p1h, P1_FPGAWRITE, ATTR_DIMMED, state);
 
  SetCtrlVal (p1h, P1_LED, state);
 
  SetCtrlAttribute (p2h, P2_DAQ, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p2h, P2_RUNSCRIPT, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p3h, P3_DAQ, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p4h, P4_DAQ, ATTR_DIMMED, state);
 
  SetCtrlAttribute (p1h, P1_STOP, ATTR_DIMMED, !state);
 
  SetCtrlAttribute (p2h, P2_STOP, ATTR_DIMMED, !state);
 
  SetCtrlAttribute (p3h, P3_STOP, ATTR_DIMMED, !state);
 
  SetCtrlAttribute (p4h, P4_STOP, ATTR_DIMMED, !state);
 
}
 
 
 
 
 
uint16_t GetConnectedFebMask(void) {
 
 
 
  uint16_t mask=0;
 
  int ison;
 
  for (int i=0; i<4; i++) {
 
    GetCtrlVal(p1h,hapd_onoff[i], &ison);
 
    mask |= (ison << i);
 
  }
 
  sa02Printf("Connected FEBs mask, 0x%0x\n",mask);
 
  return mask;
 
}
 
 
 
int CVICALLBACK daq(void *functionData) {
 
 
 
  char title[256], serial[64];
 
  int daqmode=1;
 
#define MAXSIZE 10000
 
  int h2=0;
 
  int maxsize = MAXSIZE;
 
  uint32_t *rdata;
 
  uint32_t response[2]= {0,0};
 
 
 
  uint32_t fixeddata =0;
 
  int testfixeddata =0;
 
  uint32_t data    =0;
 
  uint32_t data0    =0;
 
  uint32_t dataoff =0;
 
  uint32_t dataon =0;
 
 
 
  uint32_t cmd     =0;
 
  uint32_t chip    =0;
 
  uint32_t asicpar =0;
 
  uint32_t asicshft=0;
 
  uint32_t dstep   =0;
 
  uint32_t sendswtrg  =0;
 
  uint32_t tpenb   =0;
 
 
 
  uint32_t trglen;
 
  uint16_t mask;
 
  //uint32_t boardnumber_current=0;
 
  // uint32_t hdr[10];
 
 
 
  unsigned int aborttimeout =0;
 
  int append   =0;
 
  int remap    =0;
 
  int neve     =0;
 
  int towrite  =0;
 
  int toread   =0;
 
  int ch       =0;
 
  int output   =0;
 
  int externalcmd   =0;
 
  int i=0,j=0, ir;
 
  int ich;
 
  //int ison;
 
 
 
  char sfixeddata[0xFF]="";
 
  char scmd[0xFF]="";
 
 
 
  char filename[0xFF]="";
 
 
 
  char externalcommand[0xFF]="";
 
 
 
  FILE *fp=NULL;
 
  int nbtotal=0;
 
  time_t t,told, tstart;
 
  int ncount=0;
 
  int nerrors=0;
 
  int readerror=0;
 
  //int writeevents=0;
 
  double fraction=0;
 
  int board;
 
  double t0;
 
 
 
  rdata 
= malloc(sizeof(uint32_t)*maxsize
); 
 
 
  // intercept routine
 
  if (signal (SIGINT, SigInt) == SIG_ERR) {
 
  }
 
 
 
 
 
  mask=GetConnectedFebMask();
 
  GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
  GetCtrlVal(p1h,P1_APPEND,&append);    // append the data to the file filename
 
  GetCtrlVal(p1h,P1_FRACTION, &fraction);
 
 
 
  GetCtrlVal(p1h,P1_ABORTTOUT, &aborttimeout);
 
 
 
  GetCtrlVal( p1h,P1_EXTERNALCMD, externalcommand);
 
  GetCtrlVal( p1h,P1_EXTCMD, &externalcmd);
 
 
 
  GetCtrlVal(p1h,P1_FIXEDDATA, sfixeddata);
 
  fixeddata 
=  strtoul (sfixeddata
,NULL
,0); 
  GetCtrlVal(p1h,P1_TESTFIXEDDATA, &testfixeddata);
 
 
 
 
 
  GetCtrlVal(p1h,P1_TOREAD, &toread);
 
 
 
 
 
  GetCtrlVal(p1h,P1_NEVE, &neve);
 
  GetCtrlVal(p1h,P1_DSTEP, &dstep );
 
 
 
 
 
  GetCtrlVal(p1h,P1_SENDSWTRIG,&sendswtrg);
 
  GetCtrlVal(p1h,P1_INTTRGLEN, &trglen);
 
  GetCtrlVal(p1h,P1_DAQMODE, &daqmode);
 
  Sa02DaqMode (daqmode);
 
  Sa02SelectTriggerWithMaskAndLength (sendswtrg, mask, trglen);
 
 
 
 
 
  GetCtrlVal(p1h,P1_CHIP,&chip);
 
  GetCtrlVal(p1h,P1_CHANNEL,&ch);
 
  GetCtrlVal(p1h,P1_DATA,&data);
 
  data0=data;
 
  GetCtrlVal(p1h,P1_SCANTYPE,&towrite);
 
  switch (towrite) {
 
    case 1:
 
      GetCtrlVal(p1h,P1_WRITECMD,scmd);
 
      if (strcmp(scmd
,"MUXASIC")==0) {  
        remap=1;
 
      }
 
      cmd =sa02GetCmdCode(scmd);
 
      break;
 
    case 3:
 
      GetCtrlVal(p1h,P1_CHANNELOFF,scmd);
 
      GetCtrlVal(p1h,P1_CHANNELON,scmd);
 
      chip    =data/36;
 
      ch      =data%36;
 
    case 2:
 
      GetCtrlVal(p1h,P1_ASICPAR,scmd);
 
      if (strlen(scmd
))  cmd 
= sa02GetAsicCode
(scmd
,&asicpar
, &asicshft
);  
 
 
      break;
 
  }
 
 
 
 
 
  if (remap) {
 
    data = sa02MuxMap(data);
 
    sa02Printf("MUX %d\n",data);
 
  }
 
 
 
  GetCtrlVal(p1h,P1_TPENB,&tpenb);
 
  //ReplaceAxisItem (p1h, P1_GRAPH2D, VAL_LEFT_YAXIS, 0, scmd, data0);
 
 
 
    if (sa02Verbose) {
 
      sa02Printf("Data in the file:%s\n", filename);
 
    }
 
    if (gFp) {
 
      fp=gFp;
 
    } else {
 
      if (append) {
 
      } else {
 
      }
 
    }
 
    output=1;
 
    // run header
 
    runinfo.id= RUNINFO_ID; // run record ID
 
    runinfo.len= sizeof(runinfo);
 
    runinfo.cmd= cmd;
 
    runinfo.x0 = data;
 
    runinfo.dx = dstep;
 
    runinfo.nx = neve;
 
    runinfo.chip= chip;
 
    runinfo.ch  = ch;
 
    runinfo.neve= toread;
 
    runinfo.writemode= towrite;
 
    sa02Printf("RUNINFO x0=%d nx=%d dx=%d\n", runinfo.x0,runinfo.dx,runinfo.nx);
 
    nbtotal
+=fwrite(&runinfo
, 1,sizeof(runinfo
),fp
); //gzip 
  } else {
 
    if (sa02Verbose) {
 
      sa02Printf("Data are not written to the file!\n");
 
    }
 
  }
 
 
 
  if (!neve & (towrite || toread) ) {
 
    neve=1;
 
  }
 
 
 
 
 
  tstart=t;
 
  told=t;
 
  t0 = Timer();
 
 
 
 
 
  title[0] = 0;
 
  for (i=0; i<4; i++) {
 
    int febon=0;
 
    Sa02TestPulseEnable(i, tpenb); // Enable/disable test pulse
 
    sa02GetSerial(i, serial);
 
    GetCtrlVal(p1h,hapd_onoff[i], &febon);
 
    if (strstr(serial
,"0x00000000000000")!=NULL 
&& febon
) {  
      char txt[0xFF];
 
      sprintf(txt
, "FEB %d not connected or firmware not loaded? Serial number error! Switch Off FEB!",i
);  
      MessagePopup ("Error", txt);
 
      return -1;
 
    }
 
    sprintf(title
,"%s FEB%d=%s", title
, i
, serial
);  
  }
 
 
 
  ///////////////////////////////////////////////////////////////
 
  int icfa_visible=0;
 
  int icfa_add=0;
 
  GetPanelAttribute (p6h, ATTR_VISIBLE, &icfa_visible);
 
  GetCtrlVal (p6h, MINIRICH_ADD, &icfa_add);
 
  if (icfa_visible) {
 
    icfa_Init(); 
 
    icfa_Histo();
 
  }  
 
  ///////////////////////////////////////////////////////////////
 
  SetCtrlAttribute  (p1h, P1_GRAPH2D, ATTR_LABEL_TEXT , title);
 
  H2DInit(h2, "h2d",title, 144*4, 0,1,neve,data0, dstep);
 
  H2DSetTitleY(h2,scmd);
 
 
 
  sa02Printf("H2D nx=%d ny=%d  i=%d neve=%d\n", H2DGetNbinsX(h2),H2DGetNbinsY(h2), i, neve);
 
 
 
 
 
  plot2d(h2,1);
 
  for (i=0; i<neve; i++) {
 
    int nb = sizeof(uint32_t);
 
    int count=0;
 
 
 
 
 
    for (board=0; board<4; board++) {
 
 
 
      switch (towrite) {
 
        case 1: {
 
          rdata[count+2]= data;
 
          rdata[count+3]= sa02Cmd(board, cmd, data, chip, ch,1,response);
 
          count+=module_header(cmd,&rdata[count],2 );
 
          break;
 
        }
 
        case 2: {
 
          uint32_t datal = asicpar & (data << asicshft);
 
          rdata[count+2] =  data;
 
          rdata[count+3] =  sa02AsicWrite(board, cmd, datal, chip, ch, asicpar,asicshft);
 
          count+=module_header(cmd ,&rdata[count],2); // recid cmd
 
          break;
 
        }
 
        case 3: {
 
          rdata[count+2] =  chip*36+ch;
 
          rdata[count+3] =  sa02AsicWrite(board, cmd, dataon, chip, ch, asicpar,asicshft);  // switch on the channel
 
          count+=module_header(cmd ,&rdata[count],2); // recid cmd
 
          break;
 
        }
 
      }
 
      if (towrite==3) {
 
        SetCtrlVal(p1h,P1_SETVALUE, chip*36+ch );
 
      } else {
 
        SetCtrlVal(p1h,P1_SETVALUE, data);
 
      }
 
 
 
 
 
 
 
    }
 
 
 
    Sa02SetNeve(toread);
 
    sa02Reset();
 
 
 
//    for ( j=0; j< toread; j++)
 
    {
 
      int eventerror =  0;
 
 
 
      if ( (count +2 +dsize)  >= maxsize) {
 
 
 
        maxsize*=2;
 
        sa02Printf("Increasing data buffer to %d elements\n", maxsize);
 
        rdata
=realloc(rdata 
,sizeof(uint32_t)*maxsize
); 
      }
 
 
 
      do {
 
        if (sendswtrg == 1) Sa02SoftwareTrigger();
 
        nb  = sa02Read(mask, &rdata[count+2] );
 
      } while  ( nb==0 && !ctrl_c);
 
      if (nb==0)  sa02Printf("nb==0 LINE=%d\n",__LINE__);
 
 
 
      if (testfixeddata && nb>0) {
 
        int len = nb / sizeof(uint32_t);
 
        for (ir=0; ir<len; ir++) {
 
          if ( rdata[count+2+ir]!=fixeddata ) {
 
            sa02Printf("INSERT INTO fixederror VALUES ( '%d', '%d','%d','%d','0x%08x','0x%08x' ) \n", t, t-tstart, i*toread+j, ir, rdata[count+2+ir], fixeddata );
 
            eventerror++;
 
          }
 
        }
 
      }
 
      if (eventerror) {
 
        readerror++;
 
        if (readerror==3) {
 
          ctrl_c = 1;
 
          system("date >> firmware.lock");  
        }
 
      } else {
 
        readerror= 0;
 
      }
 
 
 
      for (ich=0; ich<144*4; ich++) {
 
        int xch = (143 - ich%144) + ich/144*144;
 
        H2DFillBin(h2, xch,i,rdata[count+2+ich]);
 
      }
 
     
 
      if (icfa_visible) icfa_Event(&rdata[count+2], icfa_add );
 
        
 
      /*
 
      for (ich=0; ich<144; ich++) {
 
      //        id=(35-ich/4)+gBoardNumber*36;
 
      //        shft=(ich%4)*8;
 
        id=(17-ich/8)+sa02BoardNumber*18;
 
        shft=(ich%8)*4;
 
 
 
      //        if ( rdata[count+2+id]  & (0xFF <<shft)  ) {
 
        if ( rdata[count+2+id]  & (0xF <<shft)  ) {
 
          H2DFillBin(h2, ich,i,1);
 
        }
 
        if (sa02Verbose>2) {
 
          sa02Printf("%02X ",(rdata[count+2+id]>> shft)& 0xF );
 
      //        sa02Printf("%02X ",(rdata[count+2+id]>> shft)& 0xFF );
 
        }
 
      }
 
      */
 
 
 
      if (sa02Verbose>2) sa02Printf("\n" );
 
      if (nb>=0) count+=module_header(0x3,&rdata[count],nb/sizeof(uint32_t));  // recid 0x3
 
 
 
      if (ctrl_c) {
 
        sa02Printf("ctrl_c detected ....\n");
 
        break;
 
      }
 
 
 
      if (t!=told ) {
 
        double done= (double) (i)/neve;
 
        EstimatedFinish(p1h, P1_PROGRESS, P1_ETA, tstart, done);
 
        plot2d(h2,i-1);
 
        GetPanelAttribute (p6h, ATTR_VISIBLE, &icfa_visible);
 
        if (icfa_visible) icfa_Draw();
 
        SetCtrlVal(p1h,P1_CUREVE, j);
 
        sa02Printf
("%d events in %2.2f min (%d s)  TIMEOUTS=%d %s",ncount
, (double)(t
-tstart
)/60.
,t
-tstart
,  nerrors
, ctime(&t
)); 
      }
 
      if (aborttimeout && (t-tstart)>aborttimeout) {
 
        sa02Printf("Abort timeout reached ....\n");
 
        ctrl_c=1;
 
        break;
 
      }
 
      told=t;
 
      if (nb==0) {
 
        nerrors++;
 
        //j--;    /// kako potem pride cez zeljeno stevil ozadetkov?
 
      } else {
 
        ncount++;
 
      }
 
    }
 
    if (externalcmd) {
 
      char ecmd[256];
 
      sprintf(ecmd
,"%s %u %u %u %u",externalcommand
,(unsigned int)  tstart
,data
, rdata
[2], rdata
[3]);  
      if (sa02Verbose) {
 
        sa02Printf("Executing external command %s\n",ecmd);
 
      }
 
    }
 
 
 
    if (output && Random(0,1)<fraction) {
 
      evtrec.id = EVTREC_ID;
 
      evtrec.len=count*sizeof(uint32_t)+ sizeof(evtrec);
 
      evtrec.nev=i;
 
      nb 
= (int) fwrite( &evtrec
,  1,  sizeof(evtrec
),fp
); //gzip 
      if (count) {
 
        nb
+= (int) fwrite(&rdata
[0],1,count
*sizeof(uint32_t),fp
);  //gzip 
      }
 
      if (nb!= (int) evtrec.len) {
 
        sa02Printf("Error writing! %d!=%d\n",nb,evtrec.len);
 
      }
 
      nbtotal+= nb;
 
    }
 
 
 
    if (sa02Verbose==1)  {
 
      sa02Printf
("[%d/%d] %u \t", i
,count
, (unsigned int) time(NULL
)); 
      PrintData(rdata,count);
 
    }
 
    if (towrite ==3) {
 
      sa02AsicWrite(board, cmd, dataoff, chip, ch, asicpar, asicshft);
 
      ch += dstep;
 
      if (ch>35) {
 
        ch-=36;
 
        chip++;
 
      }
 
    } else {
 
      data += dstep;
 
    }
 
    if (ctrl_c ) {
 
      if (!testfixeddata) {
 
        sa02Printf("Ctrl+C Program interrupted ....\n");
 
      }
 
      break;
 
    }
 
  }
 
  plot2d(h2, i-1);
 
  if (icfa_visible) icfa_Draw(); 
 
 
 
  if (output) {
 
    sprintf(scmd
,"channel;daqtime=%f", Timer
()-t0 
);  
    H2DSetTitleX(h2,scmd);
 
    H2DWrite2File(h2,fp);
 
    if (!gFp) {
 
    }
 
  }
 
  if (sa02Verbose>1) sa02Printf("%d bytes written to file %s\n", nbtotal, filename);
 
  if (toread 
&& !testfixeddata
) sa02Printf
("%d events in %2.2f min  (%f s)  TIMEOUTS=%d  %s",ncount
, (double)(Timer
()-t0
)/60.
,Timer
()-t0
, nerrors
, ctime(&t
));  
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK quit (int panel, int event, void *callbackData,
 
                      int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_CLOSE:
 
      // Stop timer callbacks
 
      SuspendTimerCallbacks();
 
      QuitUserInterface (0);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK Exit (int panel, int control, int event,
 
                      void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      quit(0,0,NULL,0,0);
 
  }
 
  return 0;
 
}
 
 
 
int SetParametersFromFile( const char *fname) {
 
  uint32_t gdata;
 
  uint32_t cdata;
 
 
 
  sa02AsicGlobalRegister  *greg = (sa02AsicGlobalRegister *) &gdata ;
 
  sa02AsicChannelRegister *creg = (sa02AsicChannelRegister *) &cdata ;
 
  unsigned short cregdata[8*144*4];
 
  unsigned short gregdata[7*4*4];
 
#define NDIM 400
 
  int ndim=NDIM;
 
  char line[NDIM];
 
  char cmd[NDIM];
 
  char sasic[NDIM];
 
  char v0[NDIM];
 
  char v1[NDIM];
 
  int asic=0, ch=0;
 
  int gval=0, cval=0;
 
  int board=0;
 
  int row=0;
 
  uint32_t sa02code;
 
  int i;
 
  ssize_t size;
 
  FILE *fp = NULL;
 
  if ( GetFileInfo
(fname
,&size
) ) fp 
= fopen(fname
,"r");  
  if (!fp) {
 
    sa02Printf("Error! Cannot open file %s\n",fname);
 
    return -1;
 
  }
 
  for (i=0; i<8*144*4; i++) {
 
    cregdata[i]=0;
 
  }
 
  for (i=0; i<7*4*4; i++) {
 
    gregdata[i]=0;
 
  }
 
  gdata=0;
 
  cdata=0;
 
  ResetTextBox(p3h,P3_FPGAPAR,"");
 
  while (fgets(line
,ndim
,fp
)!=NULL
) {  
    int nb 
= sscanf(line
,"%s%s%s%s",cmd
,sasic
,v0
,v1
);  
    if (nb<1 || cmd[0]=='#') {
 
      continue;
 
    }
 
    if (sa02Verbose>2) {
 
      sa02Printf("%d %s",nb,line);
 
    }
 
    sa02code = sa02GetCmdCode(cmd);
 
    if (strcmp(cmd
,"MUXASIC")==0) {  
      asic = sa02MuxMap(asic);
 
    }
 
    switch (nb) {
 
      case 1: {
 
        if ( sa02code ) {
 
          SetCtrlVal(p3h,P3_FPGAPAR,line);
 
 
 
          break;
 
        }
 
        break;
 
      }
 
      case 2: {
 
        if ( sa02code ) {
 
          SetCtrlVal(p3h,P3_FPGAPAR,line);
 
 
 
          break;
 
        }
 
        if (strcmp(cmd
,"param_board")==0) {  
          board= asic;
 
        }
 
        if (strcmp(cmd
,"load_global")==0) {  
          row= asic+1;
 
          greg->id=13;
 
          /*
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (1,row), greg->phasecmps);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (2,row), greg->gain);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (3,row), greg->shapingtime);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (4,row), greg->comparator);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (5,row), greg->vrdrive);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (6,row), greg->monitor);
 
          SetTableCellVal (p3h, P3_GREG, MakePoint (7,row), greg->id);
 
          */
 
          gregdata[(board*4+asic)*7]   = greg->phasecmps;
 
          gregdata[(board*4+asic)*7+1] = greg->gain;
 
          gregdata[(board*4+asic)*7+2] = greg->shapingtime;
 
          gregdata[(board*4+asic)*7+3] = greg->comparator;
 
          gregdata[(board*4+asic)*7+4] = greg->vrdrive;
 
          gregdata[(board*4+asic)*7+5] = greg->monitor;
 
          gregdata[(board*4+asic)*7+6] = greg->id;
 
 
 
          break;
 
        }
 
        break;
 
      }
 
      case 3: {
 
        if ( sa02code) {
 
          SetCtrlVal(p3h,P3_FPGAPAR,line);
 
          break;
 
        }
 
        if (strcmp(cmd
,"param_global")==0)    {  
          gdata = 0;
 
          break;
 
        }
 
        if (strcmp(cmd
,"phasecmps")==0)   {  
          greg->phasecmps = gval;
 
          break;
 
        }
 
          greg->gain = gval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"shapingtime")==0) {  
          greg->shapingtime = gval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"comparator")==0)  {  
          greg->comparator = gval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"vrdrive")==0)     {  
          greg->vrdrive = gval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"monitor")==0)     {  
          greg->monitor = gval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"load_ch")==0)   {  
          row = board*144+asic*36+ch+1;
 
          /*
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (1,row), asic);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (2,row), ch);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (3,row), creg->decaytime);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (4,row), creg->offset);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (5,row), creg->fineadj_unipol);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (6,row), creg->fineadj_diff);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (7,row), creg->tpenb);
 
          SetTableCellVal (p3h, P3_CREG, MakePoint (8,row), creg->kill);
 
          */
 
 
 
          cregdata[(row -1)*8]   = (unsigned short) asic;
 
          cregdata[(row -1)*8+1] = (unsigned short) ch;
 
          cregdata[(row -1)*8+2] = creg->decaytime;
 
          cregdata[(row -1)*8+3] = creg->offset;
 
          cregdata[(row -1)*8+4] = creg->fineadj_unipol;
 
          cregdata[(row -1)*8+5] = creg->fineadj_diff;
 
          cregdata[(row -1)*8+6] = creg->tpenb;
 
          cregdata[(row -1)*8+7] = creg->kill;
 
          cdata=0;
 
          break;
 
        }
 
        if (strcmp(cmd
,"select")==0)    {  
          sa02Printf ("%s not implemeted yet\n", cmd);
 
          break;
 
        }
 
        break;
 
      }
 
      case 4: {
 
        if (strcmp(cmd
,"param_ch")==0)    {  
          cdata = 0;
 
          break;
 
        }
 
        if (strcmp(cmd
,"decaytime")==0)  {  
          creg->decaytime = cval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"offset")==0)     {  
          creg->offset = cval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"fineadj_unipol")==0) {  
          creg->fineadj_unipol = cval;
 
          break;
 
        }
 
        if (strcmp(cmd
,"fineadj_diff")==0) {  
          creg->fineadj_diff   = cval;
 
          break;
 
        }
 
          creg->tpenb = cval;
 
          break;
 
        }
 
          creg->kill  = cval;
 
          break;
 
        }
 
        break;
 
      }
 
    }
 
 
 
  }
 
  SetTableCellRangeVals (p3h, P3_CREG, MakeRect (1, 1, 144*4, 8), cregdata, VAL_ROW_MAJOR);
 
  SetTableCellRangeVals (p3h, P3_GREG, MakeRect (1, 1, 4*4, 7)  , gregdata, VAL_ROW_MAJOR);
 
 
 
  sa02Printf("Parameters loaded from file %s to Parameter Panel \n", fname);
 
  return 0;
 
}
 
 
 
void CVICALLBACK MenuCB(int menubar, int menuItem, void *callbackData, int panel) {
 
  switch (menuItem) {
 
    case MENU_OPERATIO_CAEN_V729:
 
      DisplayPanel(p4h);
 
      break;
 
    case MENU_OPERATIO_SA02CFG :
 
      DisplayPanel(p3h);
 
      break;
 
    case MENU_OPERATIO_2DSCAN:
 
      DisplayPanel(p2h);
 
      break;
 
    case MENU_OPERATIO_LASER:
 
      DisplayPanel(p5h);
 
      break;
 
    case MENU_MINIRICH:
 
      DisplayPanel(p6h);
 
      break;  
 
    case MENU_OPERATIO_EXIT :
 
      quit(0,0,NULL,0,0);
 
      //loop_on=0;
 
      break;
 
    case MENU_HELP :
 
      sa02Help();
 
      break;
 
  }
 
}
 
 
 
int CVICALLBACK daq_readonly(void *functionData) {
 
  int h2=0;
 
  uint32_t trglen;
 
  uint32_t data[10000];
 
  uint16_t mask;
 
  //int ison;
 
  //int *fdata= (int *) functionData;
 
  int nbit,neve,nb,ch,i,j,sendswtrg;
 
 
 
  time_t t,told, tstart;
 
  //int gBoardNumber=0;
 
  int ploteachevent =0;
 
 
 
  GetCtrlVal(p1h,P1_PLOTEACHEVENT, &ploteachevent);
 
  GetCtrlVal(p1h,P1_TOREAD , &neve);
 
  GetCtrlVal(p1h,P1_NSLIX , &nbit);
 
  if (nbit>7) {
 
    nbit=7;
 
  }
 
  GetCtrlVal(p1h,P1_SENDSWTRIG,&sendswtrg);
 
  GetCtrlVal(p1h,P1_INTTRGLEN, &trglen);
 
 
 
  mask=GetConnectedFebMask();
 
  Sa02SelectTriggerWithMaskAndLength (sendswtrg, mask, trglen);
 
  Sa02SetNeve(2);
 
 
 
  H2DInit(h2,"hbit","Bit Occupancy", 144*4, 0,1,8,0, 1);
 
  H2DSetTitleX(h2,"channel");
 
  H2DSetTitleY(h2,"Data bit");
 
  tstart=t;
 
  told=t;
 
  for ( j=0; j< neve; j++) {
 
    do {
 
      if (sendswtrg==1) Sa02SoftwareTrigger();
 
      nb  = sa02Read(mask, data );
 
    } while  ( nb==0 && !ctrl_c);
 
    if (nb==0)  sa02Printf("nb==0 LINE=%d\n",__LINE__);
 
 
 
    if (ctrl_c==1) break;
 
 
 
    for (ch=0; ch<144*4; ch++) {
 
      int board = ch/144;
 
      int xch   = (143 - ch%144) + board *144;
 
      for (i=0; i<8; i++) if (data[ch] & (1<<i) ) H2DFillBin(h2,xch,i,1);
 
    }
 
    /*
 
    for (ch=0; ch<144*4; ch++)
 
    {
 
      id=(35-ch/4)+gBoardNumber*36;
 
      shft=(ch%4)*8;
 
      for (i=0; i<8; i++)
 
      {
 
        if (data[id] & (1<<(i+shft)) )
 
        {
 
          H2DFillBin(h2,ch,i,1);
 
        }
 
      }
 
      if (sa02Verbose>2)
 
      {
 
        sa02Printf("%02X ",(data[id]>> shft)& 0xFF );
 
      }
 
    }
 
    */
 
 
 
    if (sa02Verbose>2) {
 
      sa02Printf("\n" );
 
    }
 
 
 
    if (t!=told || ploteachevent) {
 
      sa02Printf
("%d events in %2.2f min (%d s) %s",j
, (double)(t
-tstart
)/60.
,t
-tstart
, ctime(&t
)); 
      GetCtrlVal(p1h,P1_NSLIY,&nbit);
 
      plot2d(h2, nbit);
 
      GetCtrlVal(p1h,P1_PLOTEACHEVENT, &ploteachevent);
 
      SetCtrlVal(p1h,P1_CUREVE, j);
 
      ProcessSystemEvents ();
 
      ProcessSystemEvents ();
 
    }
 
 
 
    told=t;
 
 
 
  }
 
 
 
  plot2d(h2, nbit);
 
  SetCtrlVal(p1h,P1_CUREVE, j);
 
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK LoadParameters (int panel, int control, int event,
 
                                void *callbackData, int eventData1, int eventData2) {
 
  char fname[0xFF];
 
  uint16_t mask;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      mask=GetConnectedFebMask();
 
      sa02Printf("LoadParameters 0x%0x\n", mask);
 
      GetCtrlVal(p3h, P3_INPUTFILE, fname);
 
      GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 1);
 
      sa02LoadParametersFromFile(fname, mask);
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 0);
 
 
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int SlowControl(uint32_t board, FILE *fp) {
 
  uint32_t data;//,step,cmd;//,response[2]= {0,0};
 
  int chip,channel,i;
 
  //double doubleval;
 
  char saddress[0xFF];
 
  double sdata[20];
 
 
 
  chip=0;
 
  channel=0;
 
  data=0;
 
 
 
  GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
  sa02Status(board,saddress,sdata);
 
  SetCtrlVal(p1h,fpga_serials[board],saddress);
 
  if (fp) {
 
    fprintf(fp
,"<slowc>\n<id>%d</id>\n", board 
);  
    fprintf(fp
,"<dna>%s</dna>\n",saddress 
);  
    for (i
=0; i
<12; i
++) fprintf(fp
,"<%s>%f</%s>\n",slowcname
[i
],sdata
[i
],slowcname
[i
] );  
  }
 
  PlotStripChart (p1h, chart_control[board], sdata, 12, 0, 0, VAL_DOUBLE);
 
  return 0;
 
}
 
 
 
 
 
int WriteChannelParameters ( int offset, int fine_offset, int tpenb) {
 
 
 
  uint32_t response[2]= {0,0};
 
  uint32_t cdata;
 
 
 
  sa02AsicChannelRegister *creg = (sa02AsicChannelRegister *) &cdata ;
 
  unsigned int i=0, j=0;
 
  int row=0;
 
  unsigned short val,asic,ch, board;
 
  uint16_t mask=GetConnectedFebMask();
 
  for (j=0; j<144*4; j++) {
 
    i = j%144;
 
    board = (unsigned short) j/144;
 
    asic=(unsigned short )(i/36);
 
    ch=(unsigned short )(i%36);
 
    row=j+1;
 
    GetTableCellVal (p3h, P3_CREG, MakePoint (1,row), &asic);
 
    GetTableCellVal (p3h, P3_CREG, MakePoint (2,row), &ch);
 
    GetTableCellVal (p3h, P3_CREG, MakePoint (3,row), &val);
 
    creg->decaytime=val;
 
    creg->offset = offset;
 
    creg->fineadj_unipol = fine_offset;
 
    GetTableCellVal (p3h, P3_CREG, MakePoint (6,row), &val);
 
    creg->fineadj_diff = val;
 
    creg->tpenb = tpenb;
 
    //sa02Printf("===%d   %d\n",i, tpenb);
 
    GetTableCellVal (p3h, P3_CREG, MakePoint (8,row), &val);
 
    creg->kill = val;
 
    creg->unused=0;
 
    if ( mask &(1<<board)) sa02Cmd(board,SA0x_ASIC0_CREG, cdata, asic, ch,1,response);
 
 
 
    if (ctrl_c) {
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
int FebTestAna(void) {
 
  int current_run;
 
  char cmdCommand[0xFF];
 
  current_run = GetRunNumberFromFile("current_run.txt");
 
  sprintf(cmdCommand 
,"C:/root/bin/root.exe \"../macros/febreport.cxx(\\\"data\\\", %d )\"", current_run
);  
  sa02Printf("%s\n",cmdCommand);
 
  LaunchExecutable(cmdCommand);
 
  return 0;
 
}
 
 
 
int FebTest(void) {
 
  int board=0, j=0, value, step;
 
 
 
  FILE *fp;
 
  int ndim=400;
 
  char line[ndim];
 
  int current_run=1;
 
  time_t t;
 
  int start;
 
  int addheader=1;
 
  char filename[0xFF];
 
  char cmdCommand[0xFF];
 
 
 
  uint32_t mask=GetConnectedFebMask();
 
 
 
  LoadParameters(p3h, P3_LOADPAR,EVENT_COMMIT,NULL,0,0);
 
 
 
 
 
  fp 
= fopen ("current_run.txt","r"); 
  if (fp) {
 
    if (fgets(line
,ndim
,fp
)!=NULL
) current_run
=atoi(line
)+1;  
    fp= NULL;
 
  }
 
 
 
  sprintf(line
,"data\\febtest_%04d.dat",current_run 
);  
  SetCtrlVal(p1h,P1_OUTPUTFILE, line);
 
 
 
  SetCtrlVal(p1h,P1_SENDSWTRIG,3 ); // set internal trigger
 
  SendTriggerTypeCB(p1h,P1_TEST, EVENT_COMMIT,NULL, 0,0);
 
 
 
  ThresholdLinearityCB (p1h, P1_THRVSADC, EVENT_COMMIT, NULL, 0, 0 );
 
 
 
  GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
  if(fp) {
 
    for (board=0; board<4; board++) if ( mask &(1<<board))  H1DWrite2File(board,fp);
 
  }
 
 
 
 
 
  sprintf(line
,"data/febslowc_%04d.xml",current_run 
);  
//  SetCtrlVal(p1h, P1_RUNID, current_run);
 
 
 
 
 
 
 
  if (!ctrl_c)  for (board=0; board<4; board++) {
 
      if ( mask &(1<<board)) {
 
        for (j=0; j<10; j++) {
 
          SlowControl(board,fp);
 
          ProcessSystemEvents ();
 
          if (ctrl_c) break;
 
        }
 
      }
 
      if (ctrl_c) break;
 
    }
 
 
 
 
 
 
 
 
 
  fp 
= fopen ("current_run.txt","w"); 
 
 
 
 
 
 
 
 
 
 
  WriteChannelParameters ( 0,0,0);   // Test pulse on all channels
 
  for (board=0; board<4; board++) if ( mask &(1<<board)) SlowControl(board,fp);
 
  SetCtrlVal(p1h,P1_TPENB,1);    // enable test pulse
 
 
 
  SetCtrlVal(p1h,P1_DATA, 350);
 
  SetCtrlVal(p1h,P1_NEVE, 150);
 
 
 
  GetCtrlVal(p1h,P1_DATA, &start);
 
 
 
  daq(NULL);
 
  SetCtrlVal(p1h,P1_TPENB,0);    // disable test pulse
 
 
 
 
 
  // coarse offset
 
  step=1;
 
  if (!ctrl_c)  for (value=0; value<16; value+=step) {
 
      if (addheader) {
 
        iteratorrec.id = ITERATORREC_ID;
 
        iteratorrec.len = sizeof(iteratorrec);
 
        iteratorrec.value = value;
 
        iteratorrec.n     = 16;
 
        iteratorrec.step  = step;
 
        iteratorrec.level = 1;
 
        GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
        fp 
= fopen(filename
, "ab"); 
        if(fp) {
 
          fwrite (&iteratorrec
, 1, iteratorrec.
len, fp
);  
        }
 
      }
 
 
 
      WriteChannelParameters ( value,0,1);
 
 
 
      SetCtrlVal(p1h,P1_DATA,start - (value%8) * 13 + (value/8)*13*8 );
 
      sa02Printf("offset=>%d\n", value);
 
      daq(NULL);
 
      if (ctrl_c) break;
 
    }
 
 
 
  // fine offset
 
  if (!ctrl_c)  for (value=0; value<16; value+=step) {
 
      if (addheader) {
 
        iteratorrec.id = ITERATORREC_ID;
 
        iteratorrec.len = sizeof(iteratorrec);
 
        iteratorrec.value = value;
 
        iteratorrec.n     = 16;
 
        iteratorrec.step  = step;
 
        iteratorrec.level = 1;
 
        GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
        fp 
= fopen(filename
, "ab"); 
        if(fp) {
 
          fwrite (&iteratorrec
, 1, iteratorrec.
len, fp
);  
        }
 
      }
 
 
 
 
 
      WriteChannelParameters (0, value,1);
 
 
 
      SetCtrlVal(p1h,P1_DATA, start - (value%8)  + (value/8)*8 );
 
      sa02Printf("offset=>%d\n", value);
 
      daq(NULL);
 
      if (ctrl_c) break;
 
    }
 
 
 
  SetCtrlVal(p1h,P1_DATA, start);
 
 
 
  GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
 
 
  sprintf(cmdCommand
,"..\\sa02read -i %s -o data\\febtest_%04d.root", filename
, current_run
);  
  sa02Printf("%s\n",cmdCommand);
 
  LaunchExecutable(cmdCommand);
 
 
 
  //sprintf(cmdCommand ,"C:/root/bin/root.exe ../macros/febreport.cxx(\\\"data/febtest_%04d.root\\\")", current_run);
 
  sprintf(cmdCommand 
,"C:/root/bin/root.exe \"../macros/febreport.cxx(\\\"data\\\", %d )\"", current_run
);  
  sa02Printf("%s\n",cmdCommand);
 
  LaunchExecutable(cmdCommand);
 
 
 
  SetCtrlVal(p1h,P1_OUTPUTFILE, line);
 
  //daq(NULL);
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK ThresholdLinearityCB (int panel, int control, int event,
 
                                      void *callbackData, int eventData1, int eventData2) {
 
  const int kmax= 1024;
 
  const int boardmax= 4;
 
 
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      uint32_t val,retval, board,data,response[2]= {0,0};
 
      int k;
 
      int chip,channel;
 
      double doubleval;
 
      time_t t,told;
 
      char title[0xFF];
 
      char name[0xFF];
 
      int h1=0;
 
      uint16_t mask=GetConnectedFebMask();
 
      chip=0;
 
      channel=0;
 
      GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
 
 
      for (board=0; board<boardmax; board++) if ( mask &(1<<board)) {
 
          char serial[0xFF];
 
          GetCtrlVal(p1h,hapd_serials[board],serial );
 
          sprintf(title
,"VTH1 linearity, position  %d sn=%s", board
, serial
);  
          H1DInit(h1+board, name,title, kmax, 0 ,1);
 
          H1DSetTitleX(h1+board,"VTH1");
 
          H1DSetTitleY(h1+board,"ADC(VTH1)");
 
          SetCtrlAttribute  (p1h, P1_GRAPH, ATTR_XNAME, H1DGetTitleX(h1+board) );
 
          SetCtrlAttribute  (p1h, P1_GRAPH, ATTR_YNAME, H1DGetTitleY(h1+board) );
 
          //SetCtrlAttribute  (p1h, P1_GRAPH, ATTR_LABEL_TEXT , H1DGetTitle(h1+board) );
 
          if (phandle[board]> 0 ) DeleteGraphPlot (p1h, P1_GRAPH, phandle[board], VAL_IMMEDIATE_DRAW);
 
          phandle[board] = 0;
 
        }
 
      for (board=0; board<boardmax; board++) if ( mask &(1<<board)) {
 
          val=sa02Cmd(board, FEB_MUX, data=0x20, chip, channel ,1,response);  // set mux to  VTH1
 
          told=t;
 
          if (ctrl_c) break;
 
          for (k=0; k<kmax; k++) {
 
            if (ctrl_c) break;
 
            SetCtrlVal(p1h,P1_SETSINGLEVALUE,k);
 
            SetCtrlVal(p1h,P1_CUREVE,k);
 
            retval=sa02Cmd(board, FEB_VTH1 , k  , chip, channel ,1, response);
 
            val=sa02Cmd(board, FEB_ADC_READ, data, chip, channel ,1,response);
 
            if (sa02BoardType>2)
 
              doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
 
            else
 
              doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
 
 
 
 
 
            H1DFillBin(h1+board, k, doubleval);
 
            if (t!=told || k==kmax-1 ||k==0 ) {
 
              H1DDraw(h1+board,p1h, P1_GRAPH, &phandle[board]);
 
              sa02Printf("[%d] set VTH1=%d  ADC(VTH1)= %6.3f V\n",board, k,  doubleval);
 
              SetCtrlVal(p1h,P1_CUREVE, k);
 
              ProcessSystemEvents ();
 
            }
 
            told=t;
 
          }
 
        }
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK MultiFpgaWrite (void *functionData) {
 
  uint32_t val, board,data,step,cmd,response[2]= {0,0};
 
  char  scmd[0xFF],sdata[0xFF];
 
  int chip, channel;
 
  char filename[0xFF];
 
  double delay, doubleval=0, x0, dx;
 
  int neve,i,daqexe,addheader;
 
  time_t t,told, tstart;
 
  FILE *fp;
 
  //int h2=0;
 
  int *fdata= (int *) functionData;
 
 
 
  datrec.id = DATREC_ID;
 
  datrec.len = sizeof(datrec);
 
  GetCtrlVal(p1h,P1_MULTINEVE , &neve);
 
  GetCtrlVal(p1h,P1_WAIT , &delay);
 
  GetCtrlVal(p1h, P1_SINGLEWRITECMD, scmd);
 
  cmd=sa02GetCmdCode(scmd);
 
  GetCtrlVal(p1h,P1_BOARDNUMBER, &board);
 
  GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
  GetCtrlVal(p1h, P1_SINGLEDATA, sdata);
 
//        if (strcmp(scmd,"MUXASIC")==0) {
 
//               data = sa02MuxMap(data);
 
//               sa02Printf("MUX %d\n",data);
 
//        }
 
  GetCtrlVal(p1h, P1_SINGLEDATA, sdata);
 
  x0=(double)data;
 
  GetCtrlVal(p1h, P1_DSTEP0, &step);
 
  dx=(double)step;
 
  GetCtrlVal(p1h,P1_SINGLECHIP,&chip);
 
  GetCtrlVal(p1h,P1_SINGLECHANNEL,&channel);
 
  if (fdata[0]==P1_FPGAWRITE) {
 
    neve=1;
 
  }
 
  GetCtrlVal(p1h,P1_DAQEXE,&daqexe);
 
  GetCtrlVal(p1h,P1_ADDHEADER,&addheader);
 
  tstart=t;
 
  told=t;
 
  if (addheader) {
 
    iteratorrec.id = ITERATORREC_ID;
 
    iteratorrec.len = sizeof(iteratorrec);
 
    iteratorrec.value = data;
 
    iteratorrec.n     = neve;
 
    iteratorrec.step  = step;
 
    iteratorrec.level = 2;
 
    GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
    fp 
= fopen(filename
, "ab"); 
    if(fp) {
 
      fwrite (&iteratorrec
, 1, iteratorrec.
len, fp
);  
    }
 
  }
 
  for (i=0; i<neve; i++) {
 
    SetCtrlVal(p1h,P1_SETSINGLEVALUE,data);
 
    SetCtrlVal(p1h,P1_CUREVE,i);
 
    val=sa02Cmd(board, cmd, data, chip, channel ,1, response);
 
    if (addheader) {
 
      datrec.cmd    =cmd;
 
      datrec.data   =data;
 
      datrec.chip   =chip;
 
      datrec.channel=channel;
 
      datrec.retval =val;
 
      GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
      fp 
= fopen(filename
, "ab"); 
      if(fp) {
 
        fwrite (&datrec
, 1, datrec.
len, fp
);  
      }
 
    }
 
    switch (cmd & (~ FEB_RO)) {
 
      case FEB_ADC_READ:
 
      case FEB_ADC_RESET:
 
        doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
 
        sa02Printf("ADC %f, 0x%08x\n", doubleval, val ) ;
 
        break;
 
      case FEB_TMON1:
 
      case FEB_TMON0:
 
        doubleval = ( (val >>2 ) & 0xFFF ) * 0.0625;
 
        if (val&0x4000) {
 
          doubleval=-doubleval;
 
        }
 
        sa02Printf("TMON %f 0x%x\n",doubleval, val ) ;
 
        break;
 
      case FEB_VTH1:
 
      case FEB_VTH2:
 
        doubleval = (val & 0xFFFF );
 
        if (cmd & 1)
 
          val=0x20;
 
        else
 
          val=0x30;
 
        val=sa02Cmd(board, FEB_MUX, val, 0, 0 ,1,response);
 
        val=sa02Cmd(board, FEB_ADC_READ, 0, 0, 0, 1,response);
 
        if (sa02BoardType>2)
 
          doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
 
        else
 
          doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
 
        sa02Printf("%5d %6.3f\n",data, doubleval);
 
        break;
 
      case SA0x_ASIC0_GREG:
 
        if (cmd & FEB_RO) {
 
          sa02PrintGREG(&val,"Returned GREG data->");
 
        }
 
        break;
 
      case SA0x_ASIC0_CREG:
 
        if (cmd & FEB_RO) {
 
          sa02PrintCREG(&val,"Returned CREG data->");
 
        }
 
        break;
 
      default:
 
        sa02Printf("0x%08X\n",val);
 
//        break;
 
    }
 
    datay[i]=doubleval;
 
    if (delay>0 && fdata[0]==P1_MULTIFPGAWRITE) {
 
      Delay(delay);
 
    }
 
    if  (daqexe) {
 
      daq(NULL);
 
    }
 
    if (ctrl_c) {
 
      break;
 
    }
 
    if (t!=told  ) {
 
      plot1d(i,x0,dx);
 
      SetCtrlVal(p1h,P1_CUREVE, i);
 
      ProcessSystemEvents ();
 
    }
 
    data+=step;
 
    told=t;
 
  }
 
  plot1d(i,x0,dx);
 
  SetCtrlVal(p1h,P1_CUREVE, i);
 
  return 0;
 
}
 
 
 
int CVICALLBACK SendSEUTRigger (int panel, int control, int event,
 
                                void *callbackData, int eventData1, int eventData2) {
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      Sa02SEUTrigger();
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK FSelect (int panel, int control, int event,
 
                         void *callbackData, int eventData1, int eventData2) {
 
  int status,fcontrol = 0;
 
  char pathName[MAX_PATHNAME_LEN];
 
  char defName[MAX_PATHNAME_LEN];
 
  char fileMessage[100] = "";
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      switch (control) {
 
        case P3_FSELECT:
 
          fcontrol=P3_INPUTFILE;
 
          strcpy(fileMessage
,"Select Parameter file");  
          break;
 
        case P3_PTSFSELECT:
 
          fcontrol=P3_PTSFIRMWARE;
 
          strcpy(fileMessage
,"Select PTS Firmware file");  
          break;
 
      }
 
      sa02Printf("MAX_PATHNAME_LEN %d\n",MAX_PATHNAME_LEN);
 
      GetCtrlVal(panel,fcontrol,defName);
 
      status = FileSelectPopup ("",defName,"",
 
                                fileMessage, VAL_LOAD_BUTTON, 0,
 
                                0, 1, 0, pathName);
 
      if (status>0)
 
        SetCtrlVal(panel,fcontrol,pathName);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK Verbose (int panel, int control, int event,
 
                         void *callbackData, int eventData1, int eventData2) {
 
  //int * data;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal(panel,control,&sa02Verbose);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK Print (int panel, int control, int event,
 
                       void *callbackData, int eventData1, int eventData2) {
 
  char dfile[MAX_PATHNAME_LEN];
 
  char name[MAX_PATHNAME_LEN];
 
  int h2=0;
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int hours, minutes, seconds;
 
      int month, day, year;
 
      int   id=-1;
 
      //int   bitmap = 0;
 
      if (panel == p1h) {
 
        switch (control) {
 
          case P1_PRINT:
 
            id= P1_GRAPH;
 
            break;
 
          case P1_PRINT2D:
 
            id= P1_GRAPH2D;
 
            break;
 
          case P1_PRINTX:
 
            id= P1_GRAPHX;
 
            break;
 
          case P1_PRINTY:
 
            id= P1_GRAPHY;
 
            break;
 
        }
 
        h2=0;
 
      } else {
 
        switch (control) {
 
          case P2_PRINTXY:
 
            id= P2_GRAPH_1;
 
            break;
 
        }
 
        h2=1;
 
      }
 
      GetSystemDate (&month,&day ,&year );
 
      GetSystemTime(&hours, &minutes, &seconds);
 
      if (id>=0) {
 
        if( ( (panel == p1h)&&(control ==  P1_PRINT2D) ) || ((panel == p2h)&&(control ==  P2_GRAPH_1))) {
 
          sprintf(dfile 
,"data/%d_%d_%d_%d_%d_%s.th2d",year
,month
,day
,hours
,minutes
, name 
);  
          H2DWrite(h2,dfile,"wb");
 
          sa02Printf("sizeof H2D %d \n",sizeof(H2D));
 
          sa02Printf("H2D image saved as %s\n", dfile);
 
          sprintf(name 
,"C:\\root\\bin\\root.exe ..\\macros\\H2Dload.cxx(\\\"%s\\\")", dfile
);  
          LaunchExecutable(name);
 
        } else {
 
          sprintf(dfile 
,"data/%d_%d_%d_%d_%d_%s.bmp",year
,month
,day
,hours
,minutes
, name 
);  
          SaveCtrlDisplayToFile (panel,id, 0, -1, -1, dfile);
 
          sa02Printf("bmp image saved as %s\n", dfile);
 
        }
 
      }
 
      //PrintCtrl (p1h, P1_GRAPH2D, "sa02_CVI", 1, 1);
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK CursorCB (int panel, int control, int event,
 
                          void *callbackData, int eventData1, int eventData2) {
 
  double x=0,y=0;
 
  int ix=0,iy=0;
 
  int h2=(int) callbackData;
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetGraphCursor (p1h, P1_GRAPH2D, 1, &x, &y);
 
      if(H2DGetStepX(h2)>0) {
 
        ix=(int)((x-H2DGetMinX(h2))/H2DGetStepX(h2));
 
      }
 
      if(H2DGetStepY(h2)>0) {
 
        iy=(int)((y-H2DGetMinY(h2))/H2DGetStepY(h2));
 
      }
 
      SetCtrlVal(panel,P1_NSLIX,ix);
 
      SetCtrlVal(panel,P1_NSLIY,iy);
 
      sa02Printf("Cursor %f %f h2=%d val=%f min=%f max=%f\n",
 
                 x,y,h2,H2DGetBinContent(h2,ix,iy),H2DGetMin(h2),
 
                 H2DGetMax(h2) );
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK HistoInfoCB (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  double x=0,y=0;
 
  int ix=0,iy=0;
 
  int h2=(int) callbackData;
 
  int b=0;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
 
 
      GetGraphCursor (panel, control, 1, &x, &y);
 
      if (panel == p2h ) {
 
        for (b=0; b<4; b++) {
 
          if (control==p2graph[b]) break;
 
        }
 
        h2=100+b;
 
        if(H2DGetStepX(h2)>0) {
 
          ix=(int)((x-H2DGetMinX(h2))/H2DGetStepX(h2));
 
        }
 
        if(H2DGetStepY(h2)>0) {
 
          iy=(int)((y-H2DGetMinY(h2))/H2DGetStepY(h2));
 
        }
 
 
 
        sa02Printf("Cursor %f %f h2=%d val=%f min=%f max=%f\n",
 
                   x,y,h2,H2DGetBinContent(h2,ix,iy),H2DGetMin(h2),
 
                   H2DGetMax(h2) );
 
      }
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
int GetElectronicChannel(int x, int y, int *chip, int *ch) {
 
  int i=0;
 
  for (i=0; i<144; i++) {
 
    if (eid2hapdxy[i].chx == x && eid2hapdxy[i].chy == y) {
 
      *chip = eid2hapdxy[i].chip;
 
      *ch   = eid2hapdxy[i].ch  ;
 
      return 0;
 
    }
 
  }
 
  return -1;
 
}
 
 
 
int SetCMon(int chx,int chy) {
 
  int chip,ch,asic;
 
  uint32_t response[2]= {0,0};
 
  uint32_t board;
 
  uint16_t mask=GetConnectedFebMask();
 
 
 
//  GetCtrlVal(p1h,P1_BOARDNUMBER, &board);
 
  GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
  GetElectronicChannel(chx,chy,&chip,&ch);
 
  asic = sa02MuxMap(chip);
 
  sa02Printf("CHX %d CHY %d ",chx, chy);
 
  sa02Printf("MUX %d ",asic);
 
  sa02Printf("CMON ASIC: %d  ch: %d\n",chip, ch);
 
  for (board=0; board<4; board++) {
 
    if (mask & (1<<board)) {
 
      sa02Cmd(board,FEB_MUX , asic, 0, 0 ,2,response);
 
      sa02Cmd(board,SA0x_ASIC0_CMON,0,chip,ch,2,response);
 
    }
 
  }
 
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK HDraw2DCB (int panel, int control, int event,
 
                           void *callbackData, int eventData1, int eventData2) {
 
  int ch=0;
 
  int ctrlID=0;
 
  int *plot=0;
 
  int graph=0;
 
  int board=0;
 
  switch (event) {
 
 
 
    case EVENT_COMMIT:
 
      for (board=0; board<4; board++) {
 
//        if (panel == p1h){ rID = P1_CH; graph = P1_GRAPH; plot =&p1plothandle;}
 
        if (panel == p2h) {
 
          ctrlID = P2_CH;
 
          graph = p2graph[board];
 
          plot =&p2plothandle[board];
 
        }
 
//        if (panel == p3h){ rID = P3_CH; graph = P3_GRAPH; plot =&p3plothandle;}
 
//        if (panel == p4h){ rID = P4_CH; graph = P4_GRAPH; plot =&p4plothandle;}
 
 
 
 
 
        GetCtrlVal(panel,ctrlID, &ch);
 
        if (ch) {
 
          H3DDrawSliceXY(100+board,ch-1,panel,graph, plot);
 
        } else {
 
          H2DDraw(100+board,panel,graph, plot);
 
        }
 
      }
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int GetHvMonitor( void ) {
 
  int N470mid   = 4;
 
  int SYS403mid = 2;
 
  unsigned short buf[256]= {0};
 
  int retval;
 
  int ii;
 
//                 G0,A0,B0,C0,D0,H0,G1,A1,B1,C1,D1,H1,G2,A2,B2,C2,D2,H2,G3,A3,B3,C3,D3,H3
 
  int channels[]= {24, 0, 1, 2, 3, 0,25, 4, 5, 6, 7, 1,26, 8, 9,10,11, 2,27,12,13,14,15, 3}; //channel for  SYS403 , then for  N470
 
//  int channels[]= {0,1,2,3,4,0,5,6,7,8,9,1,10,11,12,13,14,2,15,16,17,18,19,3}; //channel for  SYS403 , then for  N470
 
 
 
  for (ii=0; ii<256; ii++) buf[ii]=0;
 
  for (ii=0; ii<=23; ii++) {
 
    if ((ii+1)%6==0 && ii!=0) {
 
      buf[0]=(unsigned short) (channels[ii]<<8) | ReadOperationalParam;
 
      if (gCAEN_V288) {
 
        V288_Send(0,N470mid,1,buf);
 
        retval=V288_Receive(0,255, buf);
 
      }
 
      monrec.status[ii] = buf[0];   //status
 
      monrec.vmon[ii] = buf[1]*1000;//zapisano v mV
 
      monrec.imon[ii] = buf[2]*1000;//zapisano v nA
 
      monrec.vset[ii] = buf[3]*1000;//zapisano v mV
 
      monrec.iset[ii] = buf[4]*1000;//zapisano v nA
 
    } else {
 
      buf[0]=(unsigned short) (channels[ii]<<8) | ReadStatus;
 
      if (gCAEN_V288) {
 
        V288_Send(0,SYS403mid,1,buf);
 
        retval=V288_Receive(0,255,buf);
 
      }
 
      monrec.vmon[ii] = buf[1]*10;//zapisano v mV
 
      monrec.imon[ii] = buf[2]*10;//zapisano v nA
 
      monrec.status[ii] = buf[3]; //status
 
 
 
      if (!hvmonFirst) {
 
        buf[0]=(unsigned short) (channels[ii]<<8) | ReadParameters;
 
        if (gCAEN_V288) {
 
          V288_Send(0,SYS403mid,1,buf);
 
          retval=V288_Receive(0,255,buf);
 
        }
 
        vset[ii] = monrec.vset[ii] = buf[7]*10;//zapisano v mV
 
        iset[ii] = monrec.iset[ii] = buf[10]*10;//zapisano v nA
 
      }
 
      monrec.vset[ii] = vset[ii];//zapisano v mV
 
      monrec.iset[ii] = iset[ii];//zapisano v nA
 
    }
 
    //sa02Printf("%04x \t %d \t %d \t %d \t %d *\n",monrec.status[ii],monrec.vmon[ii],monrec.vset[ii],monrec.imon[ii],monrec.iset[ii]);
 
  }
 
  hvmonFirst=1;
 
  return 0;
 
}
 
 
 
int CVICALLBACK daq_scan(void *functionData) {
 
  int ich,count=0, xyval[4]= {0,0,0,0};
 
  //int c[4]= {0,0,0,0};
 
  //int e[4]= {0,0,0,0};
 
  uint32_t daqmode=1;
 
  uint32_t trglen;
 
  int nb,dsave,fcount=0,fmax=0,status,ch;
 
  unsigned int i;
 
  int hxy=100;
 
  //int h2=0;
 
  time_t t,told, tstart, t0;
 
 
 
  uint32_t board;
 
  uint32_t tpenb   =0;
 
  uint32_t response[2]= {0,0};
 
  char title[0xFF];
 
  char dfile[MAX_PATHNAME_LEN],dfile0[MAX_PATHNAME_LEN];
 
#define MAXSIZE 10000
 
  int maxsize = MAXSIZE;
 
  uint32_t sendswtrg=0;
 
  int ncount=0;
 
  uint32_t *rdata;
 
  float dx,dy,gapx,gapy,addgap;
 
  int ix,iy,nx,ny;
 
  int scanunitsx=0,scanunitsy=0;
 
  int x0,y0;
 
  const float fx= (float)(1000 / 0.3595); // 4M scaling factor steps/mm
 
  int daqexe;
 
  int writeevents=0;
 
  double fraction=0;
 
  uint32_t *data;
 
  char serial[4][0xFF];
 
  char hname[0xFF];
 
  time_t cas;
 
 
 
  uint16_t mask=GetConnectedFebMask();
 
  runrec.id = RUNREC_ID;
 
  runrec.len = sizeof(runrec);
 
  endrec.id = ENDREC_ID;
 
  endrec.len = sizeof(endrec);
 
  posrec.id = POSREC_ID;
 
  posrec.len = sizeof(posrec);
 
  evtrec.id = EVTREC_ID;
 
  evtrec.len = sizeof(evtrec);
 
  datrec.id = DATREC_ID;
 
  datrec.len = sizeof(datrec);
 
  monrec.id = MONREC_ID;
 
  monrec.len = sizeof(monrec);
 
 
 
  SetCtrlAttribute (p2h, P2_DAQ, ATTR_DIMMED, 1);
 
  ctrl_c=0;
 
 
 
  GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
 
 
  GetCtrlVal (p1h, P1_SERIAL_1, serial[0]);
 
  GetCtrlVal (p1h, P1_SERIAL_2, serial[1]);
 
  GetCtrlVal (p1h, P1_SERIAL_3, serial[2]);
 
  GetCtrlVal (p1h, P1_SERIAL_4, serial[3]);
 
 
 
  sprintf(runrec.
serial,"HAPD=%s,%s,%s,%s", serial
[0],serial
[1],serial
[2],serial
[3]);  
 
 
  GetCtrlVal (p2h, P2_NEVE, &runrec.nev);
 
  GetCtrlVal (p2h, P2_PEDESTAL, &runrec.ped);
 
  GetCtrlVal (p2h, P2_NX, &runrec.nx);
 
  GetCtrlVal (p2h, P2_XSTEP, &runrec.dx);
 
  GetCtrlVal (p2h, P2_XMIN, &runrec.x0);
 
  GetCtrlVal (p2h, P2_NY, &runrec.ny);
 
  GetCtrlVal (p2h, P2_YSTEP, &runrec.dy);
 
  GetCtrlVal (p2h, P2_YMIN, &runrec.y0);
 
  GetCtrlVal ( p1h, P2_TPENB,&tpenb);
 
  GetCtrlVal ( p2h,P2_DAQEXE,&daqexe);
 
  GetCtrlVal(p2h,P2_FRACTION, &fraction);
 
  GetCtrlVal (p2h, P2_SCANUNITSX,  &scanunitsx);
 
  GetCtrlVal (p2h, P2_SCANUNITSY,  &scanunitsy);
 
  GetCtrlVal (p2h, P2_GAPX,  &gapx);
 
  GetCtrlVal (p2h, P2_GAPX,  &gapy);
 
  GetCtrlVal (p2h, P2_DX, &dx);
 
  GetCtrlVal (p2h, P2_DX, &dy);
 
 
 
  GetCtrlVal (p2h, P2_XC,  &x0);
 
  GetCtrlVal (p2h, P2_YC,  &y0);
 
 
 
  GetCtrlVal (p2h, P2_DIRECTION,  &runrec.direction);
 
 
 
 
 
  SetCtrlAttribute(p1h,P1_TRGHVMON,ATTR_ENABLED,1);
 
  hvmonFirst = 0;
 
 
 
 
 
  GetCtrlVal(p1h,P1_SENDSWTRIG,&sendswtrg);
 
  GetCtrlVal(p1h,P1_INTTRGLEN, &trglen);
 
  GetCtrlVal(p1h,P1_DAQMODE, &daqmode);
 
 
 
 
 
 
 
 
 
  runrec.fver = scanunitsx + scanunitsy*2 ;
 
  if (scanunitsx) {
 
    x0 = (int)(x0 - 5.5 * fx * dx  - gapx * fx * 0.5);
 
  }
 
  if (scanunitsy) {
 
    y0 = (int)(y0 - 5.5 * fx * dy  - gapy * fx * 0.5);
 
  }
 
 
 
  GetCtrlVal(p2h, P2_DSAVE, &dsave);
 
  if (dsave) {
 
    GetCtrlVal (p2h, P2_DFILE, dfile0);
 
    fcount=1;
 
    GetCtrlVal (p2h, P2_NEWF, &fmax);
 
    fmax*=1000000;//fmax in Mega Bytes
 
  }
 
  sa02Printf("---->daq_scan\n");
 
  
 
  if (dsave) {
 
    sprintf(dfile
,"%s_file%02d.dat",dfile0
,fcount
);  
    //gFp = fopen (dfile, "ab");
 
    gFp 
= fopen (dfile
, "ab"); 
    if (gFp==NULL) sa02Printf("----> !!! gFp==NULL !!!\n");
 
    if (ferror (gFp
)) sa02Printf
("----> !!! ferror (gFp) after fopen !!!\n");       
    //time ((time_t *) &runrec.time);
 
    runrec.
time = (uint32_t) cas
; 
    status 
= (int) fwrite (&runrec
, 1, runrec.
len, gFp
); 
    if(status != runrec.len) sa02Printf("----> !!! status != runrec.len (= %d) !!!\n", status);    
 
    if (ferror (gFp
)) sa02Printf
("----> !!! ferror (gFp) = %d !!!\n", ferror (gFp
));    
    
 
  }
 
 
 
 
 
  for (i=0; i<4; i++) {
 
    sprintf(title
,"HAPD%d Surface Scan single channels", i
);  
    H3DInit(hxy+i,hname,title, runrec.nx,runrec.x0, runrec.dx,runrec.ny,runrec.y0, runrec.dy, 144, -0.5, 1);
 
    H3DSetTitleZ(hxy+i,"channel");
 
    H2DInit(hxy+i,hname,runrec.serial, runrec.nx,runrec.x0, runrec.dx,runrec.ny,runrec.y0, runrec.dy);
 
    if (scanunitsx) {
 
      H2DSetTitleX(hxy+i,"x (channels)");
 
      H3DSetTitleX(hxy+i,"x (channels)");
 
    } else {
 
      H2DSetTitleX(hxy+i,"x (stage steps)");
 
      H3DSetTitleX(hxy+i,"x (stage steps)");
 
    }
 
    if (scanunitsy) {
 
      H2DSetTitleY(hxy+i,"y (channels)");
 
      H3DSetTitleY(hxy+i,"y (channels)");
 
    } else {
 
      H2DSetTitleY(hxy+i,"y (stage steps)");
 
      H3DSetTitleY(hxy+i,"y (stage steps)");
 
    }
 
 
 
  }
 
  if (runrec.direction) {
 
    ny = runrec.ny;
 
    nx = runrec.nx;
 
  } else {
 
    ny = runrec.nx;
 
    nx = runrec.ny;
 
  }
 
  rdata 
= malloc(sizeof(uint32_t)*maxsize
); 
 
 
  tstart=t;
 
  told=t-1;
 
 
 
  for (iy=0; iy<ny; iy++) {
 
 
 
    if (ctrl_c) break;
 
 
 
    if (runrec.direction) {
 
      posrec.iy = iy;
 
      posrec.yset=runrec.y0+posrec.iy*runrec.dy;
 
      if (scanunitsy) {
 
        if (posrec.yset>5) {
 
          addgap=gapy * fx;
 
        } else {
 
          addgap=0;
 
        }
 
        posrec.yset = (int32_t)(y0+dy *fx * posrec.yset + addgap);
 
      }
 
      if (gMIKRO_Y) {
 
        //sa02Printf("MIKRO_MoveTo (2, y);%d\n",y);
 
        MIKRO_MoveTo (MIKRO_Y, posrec.yset);
 
        sa02Printf("->MIKRO_MoveTo (2, y);%d\n",posrec.yset);
 
      }
 
 
 
      SetCtrlVal (p2h, P2_Y, posrec.yset);
 
      SetCtrlVal (p2h, P2_IY, posrec.iy);
 
    } else {
 
      posrec.ix = iy;
 
      posrec.xset=runrec.x0+posrec.ix*runrec.dx;
 
      if (scanunitsx) {
 
        if (posrec.xset>5) {
 
          addgap=gapx * fx;
 
        } else {
 
          addgap=0;
 
        }
 
        posrec.xset =  (int32_t)(x0+dx *fx * posrec.xset + addgap);
 
      }
 
      if (gMIKRO_Y) {
 
        //sa02Printf("MIKRO_MoveTo (2, y);%d\n",y);
 
        MIKRO_MoveTo (MIKRO_X, posrec.xset);
 
        sa02Printf("->MIKRO_MoveTo (1, x);%d\n",posrec.xset);
 
      }
 
      SetCtrlVal (p2h, P2_X, posrec.xset);
 
      SetCtrlVal (p2h, P2_IX, posrec.ix);
 
    }
 
    for (ix=0; ix<nx; ix++) {
 
      if (ctrl_c) break;
 
 
 
      if (runrec.direction) {
 
        posrec.ix = ix;
 
        posrec.xset=runrec.x0+posrec.ix*runrec.dx;
 
        if (scanunitsx) {
 
          if (posrec.xset>5) {
 
            addgap=gapx * fx;
 
          } else {
 
            addgap=0;
 
          }
 
          posrec.xset =  (int32_t)(x0+dx *fx * posrec.xset + addgap);
 
        }
 
        if (gMIKRO_X) {
 
          //sa02Printf("MIKRO_MoveTo (1, x);%d\n",posrec.x);
 
          MIKRO_MoveTo (MIKRO_X, posrec.xset);
 
          sa02Printf("->MIKRO_MoveTo (1, x);%d\n",posrec.xset);
 
        }
 
        SetCtrlVal (p2h, P2_X, posrec.xset);
 
        SetCtrlVal (p2h, P2_IX, posrec.ix);
 
      } else {
 
        posrec.iy = ix;
 
        posrec.yset=runrec.y0+posrec.iy*runrec.dy;
 
        if (scanunitsy) {
 
          if (posrec.yset>5) {
 
            addgap=gapy * fx;
 
          } else {
 
            addgap=0;
 
          }
 
          posrec.yset =  (int32_t)(y0+dy *fx * posrec.yset + addgap);
 
        }
 
        if (gMIKRO_X) {
 
          //sa02Printf("MIKRO_MoveTo (1, x);%d\n",posrec.y);
 
          MIKRO_MoveTo (MIKRO_Y, posrec.yset);
 
          sa02Printf("->MIKRO_MoveTo (2, y);%d\n",posrec.yset);
 
        }
 
        SetCtrlVal (p2h, P2_Y, posrec.yset);
 
        SetCtrlVal (p2h, P2_IY, posrec.iy);
 
      }
 
      if (scanunitsx && scanunitsy) {
 
        SetCMon(runrec.x0+posrec.ix*runrec.dx,runrec.y0+posrec.iy*runrec.dy);
 
      }
 
      if (dsave) {
 
        if (fmax 
&& (ftell(gFp
) > fmax
)) {  
          fcount+=1;
 
          sprintf(dfile
,"%s_file%02d.dat",dfile0
,fcount
);  
          gFp 
= fopen (dfile
, "ab"); 
        }
 
        posrec.
time = (uint32_t) cas
; 
        status 
= (int) fwrite (&posrec
, 1, posrec.
len, gFp
); 
      }
 
 
 
      Sa02DaqMode (daqmode);
 
      Sa02SelectTriggerWithMaskAndLength (sendswtrg, mask, trglen);
 
 
 
      for (board=0; board<4; board++) {
 
        if (mask & (1<<board)) {
 
          sa02Cmd( board, FEB_VTH1, runrec.ped, 0,0,1,response);
 
          Sa02TestPulseEnable(board,tpenb); // Enable/disable test pulse
 
        }
 
      }
 
 
 
      Sa02SetNeve(runrec.nev);
 
 
 
      evtrec.nev=1;
 
 
 
 
 
      sa02Reset();
 
 
 
      if (ctrl_c) break;
 
 
 
      if ( (count+2+dsize)  >= maxsize) {
 
        maxsize*=2;
 
        sa02Printf("Increasing data buffer to %d elements\n", maxsize);
 
        rdata
=realloc(rdata 
,sizeof(uint32_t)*maxsize
); 
      }
 
 
 
      data = &rdata[count+2];
 
      do {
 
        //int k;
 
        //uint32_t inputtriggers;
 
        if (sendswtrg == 1) Sa02SoftwareTrigger();
 
        nb  = sa02Read(mask, &rdata[count+2] );
 
        /*
 
        for (k=0; k<4; k++)  c[k] = Sa02GetCounter ( k ,&e[k]);
 
        for (k=0; k<4; k++)  sa02Printf(" CNTR%d=%d (ERR=%d)\t",k,c[k],e[k]);
 
        sa02Printf("\nsa02Read bytes =  %d mask=%d neve=%d (%d # %d)\n", nb, mask, runrec.nev, Sa02GetNeve( &inputtriggers ) , inputtriggers);
 
        */
 
      } while  ( nb==0 && !ctrl_c);
 
 
 
 
 
 
 
      if (sa02TimerOut || nb==0) sa02Printf("sa02TimerOut || nb==0\n");
 
 
 
      for (ich=0; ich<144*4; ich++) {
 
        int brd = ich/144;
 
        int xch   = 143 - ich%144;
 
        //sa02Printf("[%d] = %d \n", ich, data[ich]);
 
        if (data[ich]> xyval[brd])   xyval[brd] = data[ich];
 
        if (mask & (1<<brd)) {
 
          H3DFillBin(hxy+ brd, posrec.ix,posrec.iy,xch,data[ich]);
 
          H2DFillBin(hxy+ brd, posrec.ix,posrec.iy,data[ich]);
 
        }
 
      }
 
      sa02Printf("max couts = %d %d %d %d\n", xyval[0],xyval[1],xyval[2],xyval[3]);
 
      if (nb>=0) {
 
        count+=module_header(0x3,&rdata[count],nb/sizeof(uint32_t));
 
      }
 
 
 
 
 
      /*
 
      for (ich=0; ich<144; ich++) {
 
 
 
      //          uint32_t mask=0xFF;
 
      //          id=(35-ich/4);
 
      //          shft=(ich%4)*8;
 
        uint32_t mask=0xF;
 
            id=(17-ich/8)+board*18;
 
        shft=(ich%8)*4;
 
        if ( data[id]  & (mask <<shft)  )  {
 
          H3DFillBin(hxy, posrec.ix,posrec.iy,ich,1);
 
          H2DFillBin(hxy, posrec.ix,posrec.iy,1);
 
        }
 
      }
 
      */
 
      if (dsave) {
 
        if (Random(0,1)<fraction) {
 
          writeevents=1;
 
        } else {
 
          writeevents=0;
 
        }
 
        if (writeevents) {
 
          evtrec.id = EVTREC_ID;
 
          evtrec.len=count*sizeof(uint32_t)+ sizeof(evtrec);
 
 
 
          evtrec.nev=i;
 
          status 
= (int) fwrite( &evtrec
,  1,  sizeof(evtrec
),gFp
); 
          if (count) {
 
            status 
= (int) fwrite(rdata
,1,count
*sizeof(uint32_t),gFp
);  //gzip 
          }
 
        }
 
        if (hvmon) {
 
          time_t thv0,thv1;
 
          GetHvMonitor();
 
          status 
= (int) fwrite( &monrec
,  1,  sizeof(monrec
),gFp
); 
          sa02Printf("HvMonitor dt= %d s\n", thv1-thv0 );
 
          hvmon =0;
 
        }
 
 
 
        ncount++;
 
      }
 
 
 
      if (t!=told ) {
 
        double done= (double) (posrec.ix+posrec.iy*runrec.nx)/(runrec.nx*runrec.ny);
 
        EstimatedFinish(p2h, P2_PROGRESS, P2_ETA, t0, done);
 
        GetCtrlVal(p2h,P2_CH, &ch);
 
        for (board=0; board<4; board++) {
 
          if (ch) {
 
            H3DDrawSliceXY(hxy+board,ch,p2h, p2graph[board], &p2plothandle[board]);
 
          } else {
 
            H2DDraw(hxy+board,p2h, p2graph[board], &p2plothandle[board]);
 
          }
 
        }
 
        ProcessSystemEvents ();
 
        SetCtrlVal(p2h,P2_CEVE, i);
 
        sa02Printf
("%d events in %2.2f min (%d s) %s",ncount
, (double)(t
-tstart
)/60.
,t
-tstart
, ctime(&t
)); 
 
 
      }
 
      told=t;
 
 
 
 
 
 
 
      if (ctrl_c) break;
 
 
 
      if (daqexe &0x1) {
 
        daq(NULL);
 
        sa02Cmd( board, FEB_VTH1, runrec.ped, 0,0,1,response);
 
      }
 
      if (daqexe &0x2) {
 
        V729_SetFilePointer(gFp);
 
        V729_daq(NULL);
 
      }
 
 
 
    }
 
  }
 
 
 
  if (gFp) {
 
    int ii=0, ison=0;
 
    for (ii=0; ii<4; ii++) {
 
      GetCtrlVal(p1h,hapd_onoff[ii], &ison);
 
      if (ison ) {
 
        H3DWrite2File(hxy+ii, gFp);
 
        H2DWrite2File(hxy+ii, gFp);
 
      }
 
    }
 
  }
 
  gFp=NULL;
 
 
 
  SetCtrlAttribute(p1h,P1_TRGHVMON,ATTR_ENABLED,0);
 
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK Testing(void *functionData) {
 
  int i;
 
  int N470mid   = 4;
 
  int SYS403mid = 2;
 
  unsigned short buf[256]= {0};
 
  int odg;
 
  int channels[]= {0,1,2,3,4,0,5,6,7,8,9,1,10,11,12,13,14,2,15,16,17,18,19,3}; //channel for  SYS403 , then for  N470
 
  time_t t0,t1;
 
 
 
  hvmonFirst=0;
 
 
 
  for (i=0; i<256; i++) buf[i]=0;
 
  for (i=0; i<=23; i++) {
 
    if (((i+1)%6)==0&&i!=0) {
 
      buf[0]=(unsigned short) (channels[i]<<8) | ReadOperationalParam;
 
      if (gCAEN_V288) {
 
        V288_Send(0,N470mid,1,buf);
 
        odg=V288_Receive(0,255,buf);
 
      }
 
      monrec.status[i] = buf[0];   //status
 
      monrec.vmon[i] = buf[1]*1000;//zapisano v mV
 
      monrec.imon[i] = buf[2]*1000;//zapisano v nA
 
      monrec.vset[i] = buf[3]*1000;//zapisano v mV
 
      monrec.iset[i] = buf[4]*1000;//zapisano v nA
 
    } else {
 
      buf[0]=(unsigned short) (channels[i]<<8) | ReadStatus;
 
      if (gCAEN_V288) {
 
        V288_Send(0,SYS403mid,1,buf);
 
        odg=V288_Receive(0,255,buf);
 
      }
 
      monrec.vmon[i] = buf[1]*10;//zapisano v mV
 
      monrec.imon[i] = buf[2]*10;//zapisano v nA
 
      monrec.status[i] = buf[3]; //status
 
      if(!hvmonFirst) {
 
        buf[0]=(unsigned short) (channels[i]<<8) | ReadParameters;
 
        if (gCAEN_V288) {
 
          V288_Send(0,SYS403mid,1,buf);
 
          odg=V288_Receive(0,255,buf);
 
        }
 
        vset[i] = monrec.vset[i] = buf[7]*10;//zapisano v mV
 
        iset[i] = monrec.iset[i] = buf[10]*10;//zapisano v nA
 
      }
 
      monrec.vset[i] = vset[i];//zapisano v mV
 
      monrec.iset[i] = iset[i];//zapisano v nA
 
    }
 
    sa02Printf("%04x \t %.02f V \t %d V \t\t %.02f muA \t %d muA *\n",monrec.status[i],(float)monrec.vmon[i]/1000,monrec.vset[i]/1000,(float)monrec.imon[i]/1000,monrec.iset[i]/1000);
 
  }
 
  sa02Printf
("Cas izvedbe:%g s.\n",difftime(t1
,t0
)); 
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK set_dac(int OnOff) {
 
  int val;
 
  char name[MAX_PATHNAME_LEN];
 
  if (OnOff) {
 
    GetCtrlVal (p5h, P5_DAC_ON, &val);
 
    sprintf(name 
,"%s -p %d",palaser
, val
);  
    sa02Printf("%s\n", name);
 
    GetCtrlVal (p5h, P5_FREQUENCY_ON, &val);
 
    sprintf(name 
,"%s -f %d",palaser
, val
);  
    sa02Printf("%s\n", name);
 
  } else {
 
    GetCtrlVal (p5h, P5_DAC_OFF, &val);
 
    sprintf(name 
,"%s -p %d",palaser
, val
);  
    sa02Printf("%s\n", name);
 
    GetCtrlVal (p5h, P5_FREQUENCY_OFF, &val);
 
    sprintf(name 
,"%s -f %d",palaser
, val
);  
    sa02Printf("%s\n", name);
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK set_hv(int OnOff) {
 
  int N470mid = 4;
 
  int channel = 0;
 
  int ret;
 
 
 
  unsigned short buf[256];
 
 
 
  buf[0]=(unsigned short) (channel<<8) | TurnChanelOff;
 
  if (OnOff) buf[0]=(unsigned short) (channel<<8) | TurnChanelOn;
 
  V288_Send(0,N470mid,1,buf);
 
  ret=V288_Receive(0,255,buf);
 
 
 
  buf[0]=(unsigned short) (channel<<8) | ReadOperationalParam;
 
  V288_Send(0,N470mid,1,buf);
 
  ret=V288_Receive(0,255,buf);
 
 
 
  while (((buf[0]&0x20)&&(buf[0]&0x1))||(buf[0]&0x40)) {
 
    if((buf[0]&0x20)&&(buf[0]&0x20)) sa02Printf("Channel is ramping up \t Vmon: %d V \t Vset: %d \t status: 0x%x\n",buf[1],buf[3],buf[0]);
 
    else if(buf[0]&0x40) sa02Printf("Channel is ramping down \t Vmon: %d V \t Vset: %d \t status: 0x%x\n",buf[1],buf[3],buf[0]);
 
    else if(buf[0]&0x1E) {
 
      sa02Printf("status: 0x%x\n",buf[0]);
 
      return -1;
 
    } else  sa02Printf("status: 0x%x\n",buf[0]);
 
    Delay(2);
 
    buf[0]=(unsigned short) (channel<<8) | ReadOperationalParam;
 
    V288_Send(0,N470mid,1,buf);
 
    ret=V288_Receive(0,255,buf);
 
  }
 
 
 
  buf[0]=(unsigned short) (channel<<8) | ReadOperationalParam;
 
  V288_Send(0,N470mid,1,buf);
 
  ret=V288_Receive(0,255,buf);
 
  if(buf[0]&0x1) sa02Printf("HV is ON \t status: 0x%x\n",buf[0]);
 
  else sa02Printf("HV is OFF \t status: 0x%x\n",buf[0]);
 
 
 
  return 0;
 
}
 
 
 
int CVICALLBACK changeGlobalParam(int paramID, int paramValue) {
 
  int state;
 
  int cid = P3_GREG;
 
  int scanpar = paramID; //ID of the parameter you are about to change
 
  int nch = 4; //4 ASIC chips
 
  int spar = scanpar-10;
 
  Rect save_range,trange;
 
  const int maxrange[20]= {0,0,8,16,16,16,2,2,2,0,4,4,4,2,256,4,512};
 
 
 
  trange.top=0;
 
  trange.left=0;
 
 
 
  state = GetTableSelection (p3h, cid, &save_range);
 
  trange = MakeRect (1, spar, nch, 1);
 
  state = SetTableSelection (p3h, cid, trange);
 
  if ((trange.top!=0)&&(trange.left!=0)) {
 
    if (scanpar!=1) {
 
      state = FillTableCellRange (p3h, cid, MakeRect (1, spar, nch, 1), paramValue%maxrange[scanpar-1]);
 
      if (maxrange[scanpar-1] && paramValue/maxrange[scanpar-1]) {
 
        state = FillTableCellRange (p3h, cid, MakeRect (1, spar-1, nch, 1), paramValue/maxrange[scanpar-1]);
 
      }
 
    }
 
    UploadGlobalParameters (p3h,cid,EVENT_COMMIT,NULL,0,0);
 
  }
 
  state = SetTableSelection (p3h, cid, save_range);
 
 
 
  return 0;
 
}
 
 
 
int CreateParamFile(char *filename) {
 
  int n,i,row,asic,ch;
 
  unsigned short val;
 
  time_t t;
 
  char buf[MAX_PATHNAME_LEN];
 
  FILE   *fp;
 
 
 
  sprintf(buf
,"..//parameters//%s",filename
);  
  if (fp) {
 
    //--------------------------------------------------- Parameters header
 
    fprintf(fp
, "#Parameter exported from CVI %s\n",ctime(&t
) );  
    //--------------------------------------------------- FPGA parameters
 
    GetNumTextBoxLines(p3h, P3_FPGAPAR,&n);
 
    for (i=0; i<n; i++) {
 
      GetTextBoxLine(p3h, P3_FPGAPAR, i, buf);
 
    }
 
    //--------------------------------------------------- Global parameters
 
    for (row=1; row<1+16; row++) {
 
      int irow = (row-1)%4;
 
      int iboard = (row-1)/4;
 
      fprintf(fp
, "param_board %d\n",iboard
);  
      fprintf(fp
, "## global parameter for chip %d\n",(row
-1)%4);  
      fprintf(fp
, "param_global %d 0x1ffff\n",irow
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (1,row), &val);
 
      fprintf(fp
, "phasecmps %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (2,row), &val);
 
      fprintf(fp
, "gain %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (3,row), &val);
 
      fprintf(fp
, "shapingtime %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (4,row), &val);
 
      fprintf(fp
, "comparator %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (5,row), &val);
 
      fprintf(fp
, "vrdrive %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (6,row), &val);
 
      fprintf(fp
, "monitor %d 0x%x\n",irow
,val
);  
      GetTableCellVal (p3h, P3_GREG, MakePoint (7,row), &val);
 
      fprintf(fp
, "id %d 0x%x\n",irow
,val
);  
 
 
      fprintf(fp
, "load_global  %d\n\n\n",irow
);  
    }
 
 
 
    //--------------------------------------------------- Channel parameters
 
    for (i=0; i<144*4; i++) {
 
      int board = i/144;
 
      int j= i%144;
 
      asic=(j/36);
 
      ch=j%36;
 
      row=(i+1);
 
      if (i%36==0) {
 
        fprintf(fp
, "# channel parameter for chip %d\n\n",asic
);  
      }
 
 
 
      fprintf(fp
, "param_board %d\n",board
);  
      fprintf(fp
, "param_ch       %d %d 0x0000\n",asic
,ch
);  
 
 
      GetTableCellVal (p3h, P3_CREG, MakePoint (3,row), &val);
 
      fprintf(fp
, "decaytime %d %d 0x%x\n",asic
,ch
,val
);  
      GetTableCellVal (p3h, P3_CREG, MakePoint (4,row), &val);
 
      fprintf(fp
, "offset %d %d 0x%x\n",asic
,ch
,val
);  
      GetTableCellVal (p3h, P3_CREG, MakePoint (5,row), &val);
 
      fprintf(fp
, "fineadj_unipol %d %d 0x%x\n",asic
,ch
,val
);  
      GetTableCellVal (p3h, P3_CREG, MakePoint (6,row), &val);
 
      fprintf(fp
, "fineadj_diff %d %d 0x%x\n",asic
,ch
,val
);  
      GetTableCellVal (p3h, P3_CREG, MakePoint (7,row), &val);
 
      fprintf(fp
, "tpenb %d %d 0x%x\n",asic
,ch
,val
);  
      GetTableCellVal (p3h, P3_CREG, MakePoint (8,row), &val);
 
      fprintf(fp
, "kill %d %d 0x%x\n",asic
,ch
,val
);  
      fprintf(fp
, "load_ch  %d %d\n\n\n",asic
,ch
);  
    }
 
  }
 
  sprintf(buf
,"Created file '..//parameters//%s'\n",filename
);  
  sa02Printf("%s",buf);
 
  return 0;
 
}
 
 
 
 
 
int StepOne(void) {
 
  char defaulParamFile[0xFF] = "..\\parameters\\default.param";            // path to default.param file
 
 
 
  char HAPDnum[0xFF];
 
  int HAPDnumberOnOff;
 
  int ActiveHAPDNo=0;
 
  int HAPDid[]= {P1_SERIAL_1,P1_SERIAL_2,P1_SERIAL_3,P1_SERIAL_4};
 
  int HAPDstatus[]= {P1_ONOFF_1,P1_ONOFF_2,P1_ONOFF_3,P1_ONOFF_4};
 
  char HAPDnumber[4][0xFF];
 
 
 
  FILE *fp;
 
  int ndim=400;
 
  char line[ndim];
 
  time_t t;
 
  uint32_t mask = GetConnectedFebMask();
 
  int current_run=1;
 
 
 
  char cmdCommand[ndim];
 
 
 
  int numberOfIterations = 1;  //change this when everything will be working...
 
 
 
  /****** Check if Serial numbers are filled in ******/
 
  for (int i=0; i<4; i++) {
 
    GetCtrlVal(p1h, HAPDid[i], HAPDnum);
 
    GetCtrlVal(p1h, HAPDstatus[i], &HAPDnumberOnOff);
 
    if(!strcmp(HAPDnum
, "noserial") && HAPDnumberOnOff
) {  
      printf("Fill in 'HAPD%d number' or disable 'HAPD%d'\n",i
,i
);  
      return -1;
 
    }
 
    strcpy(HAPDnumber
[i
],HAPDnum
);  
    ActiveHAPDNo+=HAPDnumberOnOff;
 
  }
 
  if(!ActiveHAPDNo) {
 
    sa02Printf("Turn on at least 1 HAPD.");
 
    return -1;
 
  }
 
  sa02Printf("HAPD0 serial: %s \nHAPD1 serial: %s \nHAPD2 serial: %s \nHAPD3 serial: %s \n",HAPDnumber[0],HAPDnumber[1],HAPDnumber[2],HAPDnumber[3]);
 
 
 
  /****** Loads param file and uploads it to FEB ******/
 
  SetCtrlVal(p3h, P3_INPUTFILE, defaulParamFile);               // write path to P3_INPUTFILE
 
  SetParametersFromFile(defaulParamFile);                       // write default.param to P3_CREG table
 
 
 
  LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);    // load parameters from defaul.param to FEB
 
  ProcessSystemEvents ();
 
  LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);    // load parameters from defaul.param to FEB
 
  ProcessSystemEvents ();
 
  LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);    // load parameters from defaul.param to FEB
 
  ProcessSystemEvents ();
 
 
 
  /****** MicroMini calibration ******/
 
  sa02Printf("Calibration *\n\n");
 
  SetHome(p2h, P2_HO,EVENT_COMMIT,NULL, 0, 0);
 
  SetCtrlVal(p2h,P2_XC,gCENTER_X);
 
  SetCtrlVal(p2h,P2_YC,gCENTER_Y);
 
 
 
  /****** Reads run number ******/
 
  fp 
= fopen ("CompleteScan_RunNumber.txt","r"); 
  if (fp) {
 
    if (fgets(line
,ndim
,fp
)!= NULL
) current_run 
= atoi(line
)+1;  
    fp = NULL;
 
  }
 
  ProcessSystemEvents ();
 
 
 
  /****** Slow Control ******/
 
  sprintf(line
,"%04d_SlowControl.xml",current_run
);  
 
 
  for (int board=0; board<4; board++) {
 
    if (mask &(1<<board)) {
 
      for (int k=0; k<10; k++) {
 
        Delay(0.1);
 
        SlowControl(board,fp);
 
        ProcessSystemEvents ();
 
        if (ctrl_c) break;
 
      }
 
    }
 
    if (ctrl_c) break;
 
  }
 
 
 
  fp = NULL;
 
 
 
  /****** Treshold scan, Calibration & Channel Param Upload (iterations) ******/
 
  for(int j=0; j<=numberOfIterations; j++) {
 
    if(!j) {
 
      //Treshold settings
 
      SetCtrlVal(p1h,P1_DATA, 400);
 
      SetCtrlVal(p1h,P1_DSTEP, 1);
 
      SetCtrlVal(p1h,P1_NEVE, 300);
 
      SetCtrlVal(p1h,P1_TOREAD, 1000);
 
      //Calibration settings
 
      SetCtrlVal (p3h, P3_FITMODE, 2);
 
      SetCtrlVal (p3h, P3_TARGETOFFSET, 550.);
 
      SetCtrlVal (p3h, P3_TARGETRMS, 3.);
 
    }
 
    sprintf(line
,"%04d_0_Treshold_%d.dat", current_run
, j
);  
    SetCtrlVal(p1h,P1_OUTPUTFILE, line);
 
    if(j==numberOfIterations) continue; //when everything will be working remove this one and uncoment the next one
 
 
 
    daq(NULL);
 
 
 
    sprintf(cmdCommand
,"cmd.exe /c ..\\sa02read -i .\\%s -o .\\%04d_0_Treshold_%d.root", line
, current_run
, j
);  
    LaunchExecutable(cmdCommand);
 
 
 
 
 
    ProcessSystemEvents ();
 
 
 
    //if(j==numberOfIterations) continue;
 
 
 
    sprintf(line
,"Coarse fit parameters, iteration %d *\n\n", j
);  
    sa02Printf(line);
 
 
 
    FitH2DCoarse(p3h, P3_CALIBRATION_2,EVENT_COMMIT,NULL,0,0);
 
    ProcessSystemEvents ();
 
 
 
    sprintf(line
,"%04d_Iteration_%d.param", current_run
, j
);  
    CreateParamFile(line);
 
 
 
    sa02Printf("Loading channel parameters *\n\n");
 
 
 
    sprintf(defaulParamFile
,"..\\parameters\\%s",line
);  
    SetCtrlVal(p3h, P3_INPUTFILE, defaulParamFile);                    // write path to P3_INPUTFILE
 
    SetParametersFromFile(defaulParamFile);                            // write default.param to P3_CREG table
 
 
 
    LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);         // load parameters to FEB
 
    ProcessSystemEvents ();
 
    LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);         // load parameters to FEB
 
    ProcessSystemEvents ();
 
    LoadParameters(p3h, P3_LOADPAR, EVENT_COMMIT, NULL, 0, 0);         // load parameters to FEB
 
    ProcessSystemEvents ();
 
 
 
 
 
  }
 
 
 
  /****** Increases run number in file for 1 ******/
 
  /*  fp = fopen ("CompleteScan_RunNumber.txt","w");
 
    fprintf(fp,"%d\n", current_run);
 
    fclose(fp);
 
  */
 
 
 
  return 0;
 
}
 
 
 
int ModuleTest(void) {
 
  int HAPDnumberOnOff;
 
  int ActiveHAPDNo=0;
 
  int HAPDid[]= {P1_SERIAL_1,P1_SERIAL_2,P1_SERIAL_3,P1_SERIAL_4};
 
  int HAPDstatus[]= {P1_ONOFF_1,P1_ONOFF_2,P1_ONOFF_3,P1_ONOFF_4};
 
  int ndim=400;
 
  int current_run=1;
 
  int ithr;
 
  double targetoffset;
 
  char line[ndim];
 
  char buf[0xFF];
 
  char cmdCommand[ndim];
 
  char HAPDnumber[4][0xFF];
 
  char HAPDnum[0xFF];
 
 
 
  FILE *fp;
 
 
 
 
 
  /****** Check if Serial numbers are filled in ******/
 
  for (int i=0; i<4; i++) {
 
    GetCtrlVal(p1h, HAPDid[i], HAPDnum);
 
    GetCtrlVal(p1h, HAPDstatus[i], &HAPDnumberOnOff);
 
    if(!strcmp(HAPDnum
, "noserial") && HAPDnumberOnOff
) {  
      printf("Fill in 'HAPD%d number' or disable 'HAPD%d'\n",i
,i
);  
      return -1;
 
    }
 
    strcpy(HAPDnumber
[i
],HAPDnum
);  
    ActiveHAPDNo+=HAPDnumberOnOff;
 
  }
 
  if(!ActiveHAPDNo) {
 
    sa02Printf("Turn on at least 1 HAPD.");
 
    return -1;
 
  }
 
  sa02Printf("HAPD0 serial: %s \nHAPD1 serial: %s \nHAPD2 serial: %s \nHAPD3 serial: %s \n",HAPDnumber[0],HAPDnumber[1],HAPDnumber[2],HAPDnumber[3]);
 
 
 
  /****** MicroMini calibration ******/
 
  sa02Printf("Calibration *\n\n");
 
  SetHome(p2h, P2_HO,EVENT_COMMIT,NULL, 0, 0);
 
  SetCtrlVal(p2h,P2_XC,gCENTER_X);
 
  SetCtrlVal(p2h,P2_YC,gCENTER_Y);
 
 
 
  /****** Reads run number ******/
 
  fp 
= fopen ("CompleteScan_RunNumber.txt","r"); 
  if (fp) {
 
    if (fgets(line
,ndim
,fp
)!= NULL
) current_run 
= atoi(line
)+1;  
    fp = NULL;
 
  }
 
  ProcessSystemEvents ();
 
 
 
  fp 
= fopen ("CompleteScan_RunNumber.txt","w"); 
 
 
  GetCtrlVal (p3h, P3_TARGETOFFSET, &targetoffset);   // Treshold
 
  ithr=(int)targetoffset+20;
 
  /****** Treshold + Waveform scan over 144x center ******/
 
  SetCtrlVal (p2h, P2_ZSET, 0);
 
  SetCtrlVal (p2h, P2_XC, (uint32_t)(gCENTER_KX*0+gCENTER_X));
 
  SetCtrlVal (p2h, P2_YC, (uint32_t)(gCENTER_KY*0+gCENTER_Y));
 
  Zset(p2h,P2_ZSET,EVENT_COMMIT,NULL,0,0);
 
  // Panel 1 setting
 
  SetCtrlVal (p1h, P1_TPENB, 0);                                    // disable test pulz
 
  SetCtrlVal (p1h, P1_SENDSWTRIG, 2);                               // set external trigger
 
  SendTriggerTypeCB (p1h, P1_SENDSWTRIG, EVENT_COMMIT,NULL,0,0);    // commit external trigger
 
 
 
  SetCtrlVal(p1h,P1_DATA, 500);    // Inital value
 
  SetCtrlVal(p1h,P1_DSTEP, 2);     // Step size
 
  SetCtrlVal(p1h,P1_NEVE, 101);    // Number of steps
 
  SetCtrlVal(p1h,P1_TOREAD, 1000);  // Number of events
 
 
 
  // Panel 4 setting
 
  //SetCtrlVal(p4h,P4_FRACTION, 0.);  // Fraction of waveforms to store (If you want to create charge accumulation graphs with sa02read set to 1.)
 
  SetCtrlVal(p4h,P4_NEVE, 4000);  // Number of events
 
 
 
  // Panel 2 settings
 
  SetCtrlVal (p2h, P2_SCANUNITSX, 1);   // Only over the channel centers   (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NX, 12);          // Noumber of steps = 12
 
  SetCtrlVal (p2h, P2_XSTEP, 1);        // Step size = 1
 
  SetCtrlVal (p2h, P2_XMIN, 0);         // Start position = 0
 
  SetCtrlVal (p2h, P2_SCANUNITSY, 1);   // Only over the channel centers   (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NY, 12);          // Noumber of steps = 12
 
  SetCtrlVal (p2h, P2_YSTEP, 1);        // Step size = 1
 
  SetCtrlVal (p2h, P2_YMIN, 0);         // Start position = 0
 
  SetCtrlVal (p2h, P2_DIRECTION, 1);    // Set Y then scan X = 1 (0 = Set X then scan X)
 
 
 
  SetCtrlVal (p2h, P2_NEVE, 100);        // Number of events for position scan (keep low so the scan is faster ... this is not the point of interest for this scan)
 
  SetCtrlVal (p2h, P2_PEDESTAL, ithr);   // Treshold
 
 
 
  SetCtrlVal (p2h, P2_DAQEXE, 3);       // Execute at each position: SA02 scan and CAEN V729a
 
 
 
  sprintf(buf
,"%04d_1_Treshold_Waveform",current_run
);  
  sprintf(line
,"..\\modules\\%s",buf
);  
  SetCtrlVal (p2h, P2_DFILE, line);
 
 
 
 
 
  daq_scan(NULL);
 
 
 
  sprintf(cmdCommand
,"cmd.exe /c mkdir ..\\modules\\%04d & ..\\sa02read -i %s_file01.dat -o ..\\modules\\%04d\\%s.root",  
          current_run, line, current_run, buf);
 
  LaunchExecutable(cmdCommand);
 
 
 
 
 
  
 
  /****** 2D v X ******/
 
  // Panel 2 settings
 
  SetCtrlVal (p2h, P2_SCANUNITSX, 0);   // Continuous scan over X  (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NX, 380/2);         // Noumber of steps = 380
 
  SetCtrlVal (p2h, P2_XSTEP, 2*500);      // Step size = 500
 
  SetCtrlVal (p2h, P2_XMIN, 83000);     // Start position = 8500
 
  SetCtrlVal (p2h, P2_SCANUNITSY, 1);   // Only over the channel centers   (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NY, 12);          // Noumber of steps = 12
 
  SetCtrlVal (p2h, P2_YSTEP, 1);        // Step size = 1
 
  SetCtrlVal (p2h, P2_YMIN, 0);         // Start position = 0
 
  SetCtrlVal (p2h, P2_DIRECTION, 1);    // Set Y then scan X = 1
 
 
 
  SetCtrlVal (p2h, P2_NEVE, 1000);       // Number of events for position scan
 
  SetCtrlVal (p2h, P2_PEDESTAL, ithr);   // Treshold
 
 
 
  SetCtrlVal (p2h, P2_DAQEXE, 0);       // Execute at each position: nothing
 
 
 
  sprintf(buf
,"%04d_2_2DX",current_run
);  
  sprintf(line
,"..\\modules\\%s", buf
);  
  SetCtrlVal (p2h, P2_DFILE, line);
 
 
 
 
 
  daq_scan(NULL);
 
 
 
  sprintf(cmdCommand
,"cmd.exe /c mkdir ..\\modules\\%04d & ..\\sa02read -i %s_file01.dat -o ..\\modules\\%04d\\%s.root ", current_run
, line
, current_run
, buf
);  
  LaunchExecutable(cmdCommand);
 
 
 
 
 
  /****** 2D v Y ******/
 
  // Panel 2 settings
 
  SetCtrlVal (p2h, P2_SCANUNITSX, 1);   // Only over the channel centers   (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NX, 12);          // Noumber of steps = 12
 
  SetCtrlVal (p2h, P2_XSTEP, 1);        // Step size = 1
 
  SetCtrlVal (p2h, P2_XMIN, 0);         // Start position = 0
 
  SetCtrlVal (p2h, P2_SCANUNITSY, 0);   // Continuous scan over Y  (1 Ch, 0 Step)
 
  SetCtrlVal (p2h, P2_NY, 380/2);          // Noumber of steps = 380
 
  SetCtrlVal (p2h, P2_YSTEP, 2*500);        // Step size = 500
 
  SetCtrlVal (p2h, P2_YMIN, 75000);         // Start position = 7500
 
  SetCtrlVal (p2h, P2_DIRECTION, 0);    // Set X then scan Y = 0
 
 
 
  SetCtrlVal (p2h, P2_NEVE, 1000);        // Number of events for position scan
 
  SetCtrlVal (p2h, P2_PEDESTAL, ithr);   // Treshold
 
 
 
  SetCtrlVal (p2h, P2_DAQEXE, 0);       // Execute at each position: nothing
 
 
 
  sprintf(buf
,"%04d_3_2DY",current_run
);  
  sprintf(line
,"..\\modules\\%s", buf
);  
  SetCtrlVal (p2h, P2_DFILE, line);
 
 
 
 
 
  daq_scan(NULL);
 
 
 
  sprintf(cmdCommand
,"cmd.exe /c mkdir ..\\modules\\%04d & ..\\sa02read -i %s_file01.dat -o ..\\modules\\%04d\\%s.root ", current_run
, line
, current_run
, buf
);  
  system(cmdCommand
); // wait here to finish to proceed to next step      
  
 
  sprintf(cmdCommand
,"cmd.exe /c ..\\thisroot.bat & cd analysis & root script.c(%d)",current_run
);  
  LaunchExecutable(cmdCommand);
 
 
 
  SetCtrlVal (p2h, P2_ZSET, 300000);
 
  SetCtrlVal (p2h, P2_XC, (uint32_t)(gCENTER_KX*0+gCENTER_X));
 
  SetCtrlVal (p2h, P2_YC, (uint32_t)(gCENTER_KY*0+gCENTER_Y));
 
  Zset(p2h,P2_ZSET,EVENT_COMMIT,NULL,0,0);
 
 
 
  return 0;
 
}
 
 
 
int StepThree(void) {
 
  //char cmdCommand[0xFF];
 
  //char line[0xFF];
 
  //char buf[0xFF];
 
  //int current_run = 11;
 
 
 
  return 0;
 
}
 
 
 
 
 
// map uir controls ....
 
#define MAX_UIRCTRLMAP_SIZE 1000
 
typedef struct {
 
  char name[32];
 
  int id;
 
  int handle;
 
} UirCtrlMap;
 
UirCtrlMap gUirCtrlMap[MAX_UIRCTRLMAP_SIZE];
 
int gNUirCtrlMap=0;
 
 
 
int GetControlID(const char *ctrl) {
 
  for (int i=0; i<gNUirCtrlMap; i++) {
 
    if (strcmp(ctrl
,gUirCtrlMap
[i
].
name)==0) return ctrl
,gUirCtrlMap
[i
].
id;  
  }
 
  return -1;
 
}
 
int GetPanelHandle(const char *ctrl) {
 
 
 
  if ( strstr(ctrl
, "P1_")!= NULL 
) return p1h
;  
  if ( strstr(ctrl
, "P2_")!= NULL 
) return p2h
;  
  if ( strstr(ctrl
, "P3_")!= NULL 
) return p3h
;  
  if ( strstr(ctrl
, "P4_")!= NULL 
) return p4h
;  
  if ( strstr(ctrl
, "P5_")!= NULL 
) return p5h
;  
 
 
  return -1;
 
}
 
 
 
int LoadUirHeader(const char *fname) {
 
  int ndim=MAX_PATHNAME_LEN;
 
  char line[MAX_PATHNAME_LEN];
 
  char cmd[MAX_PATHNAME_LEN];
 
  FILE *fp = NULL;
 
  ssize_t size;
 
  int n0= gNUirCtrlMap;
 
  if ( GetFileInfo
(fname
,&size
) ) fp 
= fopen(fname
,"r");  
  if (!fp) {
 
    sa02Printf("Error! Cannot open header file %s\n",fname);
 
    return -1;
 
  }
 
 
 
  while (fgets(line
,ndim
,fp
)!=NULL 
) {  
    char ctrl[32];
 
    int ctrlid;
 
    int nb 
= sscanf(line
,"%s%s%d",cmd
, ctrl
, &ctrlid
);  
    if (strstr(cmd
,"#define")!=NULL 
&& nb
==3) {  
      strcpy(gUirCtrlMap
[gNUirCtrlMap
].
name, ctrl 
);  
      if (gNUirCtrlMap<MAX_UIRCTRLMAP_SIZE) {
 
        gUirCtrlMap[gNUirCtrlMap].id     = ctrlid;
 
        gUirCtrlMap[gNUirCtrlMap].handle = GetPanelHandle(ctrl);
 
        gNUirCtrlMap++;
 
      } else {
 
        sa02Printf("ERROR: Increase gNUirCtrlMap\n");
 
      }
 
    }
 
  }
 
  sa02Printf("Number of Controls loaded from File %s = %d \n", fname,gNUirCtrlMap-n0);
 
  return 0;
 
}
 
 
 
 
 
char *str_replace(const char *str, const char *old, const char *new) {
 
 
 
  /* Adjust each of the below values to suit your needs. */
 
 
 
  /* Increment positions cache size initially by this number. */
 
  size_t cache_sz_inc = 16;
 
  /* Thereafter, each time capacity needs to be increased,
 
   * multiply the increment by this factor. */
 
  const size_t cache_sz_inc_factor = 3;
 
  /* But never increment capacity by more than this number. */
 
  const size_t cache_sz_inc_max = 1048576;
 
 
 
  char *pret, *ret = NULL;
 
  const char *pstr2, *pstr = str;
 
  size_t i, count = 0;
 
  ptrdiff_t *pos_cache = NULL;
 
  size_t cache_sz = 0;
 
  size_t cpylen
, orglen
, retlen
, newlen 
=0, oldlen 
= strlen(old
);  
 
 
  /* Find all matches and cache their positions. */
 
  while ((pstr2 
= strstr(pstr
, old
)) != NULL
) {  
    count++;
 
 
 
    /* Increase the cache size when necessary. */
 
    if (cache_sz < count) {
 
      cache_sz += cache_sz_inc;
 
      pos_cache 
= realloc(pos_cache
, sizeof(*pos_cache
) * cache_sz
); 
      if (pos_cache == NULL) {
 
        goto end_repl_str;
 
      }
 
      cache_sz_inc *= cache_sz_inc_factor;
 
      if (cache_sz_inc > cache_sz_inc_max) {
 
        cache_sz_inc = cache_sz_inc_max;
 
      }
 
    }
 
 
 
    pos_cache[count-1] = pstr2 - str;
 
    pstr = pstr2 + oldlen;
 
  }
 
 
 
  orglen 
= pstr 
- str 
+ strlen(pstr
); 
 
 
  /* Allocate memory for the post-replacement string. */
 
  if (count > 0) {
 
    retlen = orglen + (newlen - oldlen) * count;
 
  } else  retlen = orglen;
 
  if (ret == NULL) {
 
    goto end_repl_str;
 
  }
 
 
 
  if (count == 0) {
 
    /* If no matches, then just duplicate the string. */
 
  } else {
 
    /* Otherwise, duplicate the string whilst performing
 
     * the replacements using the position cache. */
 
    pret = ret;
 
    memcpy(pret
, str
, pos_cache
[0]);  
    pret += pos_cache[0];
 
    for (i = 0; i < count; i++) {
 
      pret += newlen;
 
      pstr = str + pos_cache[i] + oldlen;
 
      cpylen = (i == count-1 ? orglen : (size_t)pos_cache[i+1]) - pos_cache[i] - oldlen;
 
      pret += cpylen;
 
    }
 
    ret[retlen] = '\0';
 
  }
 
 
 
end_repl_str:
 
  /* Free the cache and return the post-replacement string,
 
   * which will be NULL in the event of an error. */
 
  return ret;
 
}
 
 
 
 
 
int CVICALLBACK run_script(void *functionData) {
 
  FILE *fp = NULL;
 
  FILE *fpout =NULL;
 
 
 
  
 
  char *line;
 
  char buf[MAX_PATHNAME_LEN];
 
  int status;
 
  char type[MAX_PATHNAME_LEN];
 
  char param[MAX_PATHNAME_LEN];
 
  char paramValue[MAX_PATHNAME_LEN];
 
  int scx,nx,xstep,xmin,scy,ny,ystep,ymin,direction,nevents,tresh;
 
  char test[256];
 
  char outputFileSuffix[128];
 
  char outputFile[MAX_PATHNAME_LEN];
 
  char HAPDserialNumber[128];
 
  ssize_t size;
 
  int data[2];
 
  int runno=0;
 
 
 
  char scriptname[MAX_PATHNAME_LEN];
 
  GetCtrlVal(p1h,P1_SCRIPTNAME, scriptname);
 
 
 
 
 
  if ( GetFileInfo
(scriptname
,&size
) ) fp 
= fopen(scriptname
,"r");  
  if (!fp) {
 
    sa02Printf("Error! Cannot open script file %s\n",scriptname);
 
    return -1;
 
  }
 
  while (fgets(buf
,MAX_PATHNAME_LEN
,fp
)!=NULL 
) {  
   
 
    if (buf
[0]!='#' && strlen(buf
)>2) {  
      if (strstr(buf
, "%RUN%")!=NULL
) {  
          char srun[16];
 
          line = str_replace(buf,"%RUN%", srun);
 
      } else {
 
          line = buf;
 
      }
 
      sa02Printf
("#[%d] %s",strlen(buf
),buf
);    
     
 
      
 
      if (strstr(type
,"SetCtrlVal")!=NULL
) {  
        int pID;  
 
        int rID;
 
        int datatype;
 
        sscanf(line
,"%*s%s%s",param
,paramValue
);  
    
 
        pID= GetPanelHandle(param);  
 
        rID= GetControlID(param);
 
        if (rID>0 && pID>0) {
 
          GetCtrlAttribute (pID, rID, ATTR_DATA_TYPE, &datatype);
 
        
 
          switch (datatype){
 
            case VAL_INTEGER
: SetCtrlVal 
(pID
, rID
, atoi(paramValue
)); break;  
            case VAL_UNSIGNED_INTEGER
: SetCtrlVal 
(pID
, rID
, strtoul(paramValue
,NULL
,0)); break;  
            case VAL_SHORT_INTEGER
: SetCtrlVal 
(pID
, rID
, atoi(paramValue
)); break;  
            case VAL_UNSIGNED_SHORT_INTEGER
: SetCtrlVal 
(pID
, rID
, strtoul(paramValue
,NULL
,0)); break;  
            case VAL_DOUBLE 
: SetCtrlVal 
(pID
, rID
, atof(paramValue
)); break;  
            case VAL_STRING : SetCtrlVal (pID, rID, paramValue      ); break;
 
            default: sa02Printf("[%s] ATTR_DATA_TYPE of the %s not supported datatype %d p4h=%d\n\n", type, param, datatype, p4h); 
 
          }
 
          //sa02Printf("[%s] SetCtrlVal %s %s panel=%d control=%d\n",type,param, paramValue,pID,rID);  
 
        } else {
 
           sa02Printf("[%s] Invalid Ctrl %s %s panel=%d control=%d\n",type,param, paramValue,pID,rID);
 
        }  
 
        
 
      } else if (strstr(type
,"2D")!=NULL
) {  
        sscanf(line
,"%*s%d%d%d%d%d%d%d%d%d%d%d%s",&scx
,&nx
,&xstep
,&xmin
,&scy
,&ny
,&ystep
,&ymin
,&direction
,&nevents
,&tresh
,outputFileSuffix
);  
        sprintf(test
,"%d %d %d %d %d %d %d %d %d %d %d %s *\n",scx
,nx
,xstep
,xmin
,scy
,ny
,ystep
,ymin
,direction
,nevents
,tresh
,outputFileSuffix
);  
        sa02Printf("%s *\n\n",test);
 
        SetCtrlVal (p2h, P2_SCANUNITSX, scx);
 
        SetCtrlVal (p2h, P2_NX, nx);
 
        SetCtrlVal (p2h, P2_XSTEP, xstep);
 
        SetCtrlVal (p2h, P2_XMIN, xmin);
 
        SetCtrlVal (p2h, P2_SCANUNITSY, scy);
 
        SetCtrlVal (p2h, P2_NY, ny);
 
        SetCtrlVal (p2h, P2_YSTEP, ystep);
 
        SetCtrlVal (p2h, P2_YMIN, ymin);
 
        SetCtrlVal (p2h, P2_DIRECTION, direction);
 
 
 
        SetCtrlVal (p2h, P2_NEVE, nevents);
 
        SetCtrlVal (p2h, P2_PEDESTAL, tresh);
 
 
 
        GetCtrlVal (p1h, P1_SERIAL_1, HAPDserialNumber);
 
        sprintf(outputFile
,"%s_%s", HAPDserialNumber
, outputFileSuffix
);  
        SetCtrlVal (p2h, P2_DFILE, outputFile);
 
 
 
 
 
        daq_scan(NULL);
 
 
 
      } else if (strstr(type
,"Delay")!=NULL
) {  
        int idelay=0;
 
        sscanf(line
,"%*s%s",paramValue
);  
        for (idelay
=atoi(paramValue
) ; idelay
>0; idelay
--) {  
          Delay(1);
 
          SetCtrlVal(p1h, P1_DELAY, idelay);
 
          ProcessSystemEvents();
 
          if (ctrl_c) break;
 
        }
 
      }  else if (strstr(type
,"ThresholdLinearity")!=NULL
) {  
        char *fname;
 
        uint16_t mask = GetConnectedFebMask();
 
 
 
        sscanf(line
,"%*s%s",paramValue
);  
        fname = paramValue;
 
        
 
 
 
        ThresholdLinearityCB (p1h, P1_THRVSADC, EVENT_COMMIT, NULL, 0, 0 );
 
        fpout 
= fopen(fname
,"ab"); 
        if(fpout) {
 
          for (int board=0; board<4; board++) if ( mask &(1<<board))  H1DWrite2File(board,fpout);
 
        }
 
 
 
      }  else if (strstr(type
,"LaunchExecutable")!=NULL
) {  
        int index = FindPattern (line, 0, -1, "LaunchExecutable", 0, 0) + 17;
 
       
 
        char *cmd = &line[index];
 
        sa02Printf("cmd %d=%s\n",index, cmd);
 
        if (strlen(cmd
)>0) LaunchExecutable
( cmd 
);  
      }  else if (strstr(type
,"CAEN_V729")!=NULL
) {     
        char *fname;
 
        //FILE *fpmon=NULL;
 
        
 
        sscanf(line
,"%*s%s",paramValue
);  
        fname=paramValue; 
 
        
 
        fpout 
= fopen(fname
,"ab"); 
        if (fpout) {
 
          
 
          V729_SetFilePointer(fpout);
 
          V729_daq(NULL);
 
        }
 
      } else if (strstr(type
,"HvMonitor")!=NULL
) {  
        int nrepetitions;
 
        int delaytime;
 
        int k=0;
 
        FILE *fpmon=NULL;
 
        sscanf(line
,"%*s%s%d%d",paramValue
, &delaytime
, &nrepetitions 
);  
        fpmon 
= fopen(paramValue
,"ab"); 
        
 
        if ( fpmon ) {
 
          hvmonFirst = 0;
 
          for (k=0; k<nrepetitions; k++) {
 
            double thv0,thv1;
 
            thv0 = Timer();
 
            GetHvMonitor();
 
            for (int board=0;board<4;board++){
 
              double sdata[12];
 
              for (int k=0;k<6;k++){
 
                 sdata[k] = monrec.imon[k+4*board];
 
                 sdata[k+6] = 0;
 
              }
 
             
 
              SetAxisScalingMode (p1h, chart_control[board], VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 1);
 
              SetAxisScalingMode (p1h, chart_control[board], VAL_RIGHT_YAXIS, VAL_AUTOSCALE, 0, 1);
 
              PlotStripChart (p1h, chart_control[board], sdata, 12, 0, 0, VAL_DOUBLE);
 
            }  
 
            monrec.id = MONREC_ID;
 
            monrec.len = sizeof(monrec);
 
            thv1=Timer();
 
            status 
= (int) fwrite( &monrec
,  1,  sizeof(monrec
),fpmon
); 
            sa02Printf("[%04d] HvMonitor dt= %f s status=%d\n", runno, thv1-thv0, status );
 
            for (int idelay=delaytime ; idelay>0; idelay--) {
 
              Delay(1);
 
              SetCtrlVal(p1h, P1_DELAY, idelay);
 
              ProcessSystemEvents();
 
              if (ctrl_c) break; 
 
            }
 
            if (ctrl_c) break; 
 
          }
 
        } else {
 
          sa02Printf("%s cannot open file %s\n",param, paramValue );
 
        }
 
 
 
      } else if (strstr(type
,"GetRunNumberFromFile")!=NULL
) {  
        sscanf(line
,"%*s%s",paramValue
);  
        runno = GetRunNumberFromFile(paramValue);
 
        SetCtrlVal(p1h, P1_RUNNO, runno);
 
        sa02Printf("%s %s run=>%d\n",type, paramValue, runno );
 
      } else if (strstr(type
,"IncreaseNumberInFile")!=NULL
) {  
        sscanf(line
,"%*s%s",paramValue
);  
        runno = IncreaseRunNumberInFile(paramValue);
 
        sa02Printf("%s %s run=>%d\n",type, paramValue, runno );
 
        SetCtrlVal(p1h, P1_RUNNO, runno);
 
      } else if (strstr(type
,"LoadParameters")!=NULL
) {  
        LoadParameters(p3h, P3_LOADPAR,EVENT_COMMIT,NULL,0,0);
 
        sa02Printf("Loading parameters *\n\n");
 
      } else if (strstr(type
,"QueueUserEvent")!=NULL 
|| strstr(type
,"ProcessUserEvent")!=NULL
) {  
        char scontrol[0xFF];
 
        int panelHandle=0;
 
        int controlID;
 
        sscanf(line
,"%*s%s",scontrol
);  
        panelHandle = GetPanelHandle(scontrol);
 
        controlID   = GetControlID(scontrol);
 
        sa02Printf("UserEvent %s panelHandle %d controlID %d\n",scontrol, panelHandle, controlID );
 
        if (panelHandle>=0 && controlID >=0 ) {
 
          if (strstr(type
,"ProcessUserEvent")!=NULL
) {   
            ProcessUserEvent(panelHandle, controlID,0);
 
          } else {
 
            data[1] = controlID;
 
            data[0] = panelHandle;
 
        
 
            status = CmtWriteTSQData (pTSQ, data, 1, TSQ_INFINITE_TIMEOUT, NULL);
 
          }  
 
        }
 
 
 
      }  else if (strstr(type
,"SetPositionAndMux")!=NULL
) {  
        int ix,iy;
 
        sscanf(line
,"%*s%d%d",&ix
,&iy
);  
        sa02Printf("SetPositionAndMux %d %d \n", ix,iy);
 
 
 
        SetCtrlVal (p2h, P2_CHX,  ix);
 
        SetCtrlVal (p2h, P2_CHY,  iy);
 
        SetPositionAndMux(  p2h,0, EVENT_COMMIT , NULL,0,0);
 
 
 
      }  else if (strstr(type
,"Treshold")!=NULL
) {  
        sscanf(line
,"%*s%s",outputFileSuffix
);  
 
 
        GetCtrlVal (p1h, P1_SERIAL_1, HAPDserialNumber);
 
        sprintf(outputFile
,"%s_%s.dat", HAPDserialNumber
, outputFileSuffix
);  
        SetCtrlVal (p1h, P1_OUTPUTFILE, outputFile);
 
 
 
        sprintf(test
,"Treshold scan to file %s",outputFile
);  
        sa02Printf("%s *\n\n", test);
 
 
 
        daq(NULL);
 
      } else if (strstr(type
,"Fitanje")!=NULL
) {  
        FitH2DCoarse(p3h, P3_CALIBRATION_2,EVENT_COMMIT,NULL,0,0);
 
        sa02Printf("Coarse fit parameters *\n\n");
 
      } else if (strstr(type
,"UploadChannelParameters")!=NULL
) {  
        UploadChannelParameters(p3h, P3_CPARLOAD,EVENT_COMMIT,NULL,0,0);
 
        sa02Printf("Loading channel parameters *\n\n");
 
      } else if (strstr(type
,"KalibracijaMizice")!=NULL
) {  
        SetHome(p2h, P2_HO,EVENT_COMMIT,NULL,0,0);
 
        SetCtrlVal(p2h,P2_XC,gCENTER_X);
 
        SetCtrlVal(p2h,P2_YC,gCENTER_Y);
 
        sa02Printf("Calibration *\n\n");
 
      } else if (strstr(type
,"LaserHVOn")!=NULL
) {  
        set_dac(1);
 
        sa02Printf("Low intensity laser *\n\n");
 
      } else if (strstr(type
,"LaserHVOff")!=NULL
) {  
        set_dac(0);
 
        sa02Printf("High intensity laser *\n\n");
 
      } else if (strstr(type
,"Gain")!=NULL
) {  
        sscanf(line
,"%*s%d",paramValue
);  
        sa02Printf("%s *\n\n", test);
 
        changeGlobalParam
(12, atoi(paramValue
)); // Global parameter Gain has ID 12 
      } else if (strstr(type
,"ShapingTime")!=NULL
) {  
        sscanf(line
,"%*s%s",paramValue
);  
        sa02Printf("%s *\n\n", test);
 
        changeGlobalParam
(13, atoi(paramValue
)); // Global parameter ShapingTime has ID 13 
      }
 
    }
 
    if (ctrl_c) {
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
/*
 
int CVICALLBACK StartPositionScan (int panel, int control, int event,
 
    void *callbackData, int eventData1, int eventData2)
 
{
 
  switch (event)
 
    {
 
    case EVENT_COMMIT:
 
        daq_scan(NULL);
 
      break;
 
    }
 
  return 0;
 
}
 
*/
 
 
 
int CVICALLBACK SetHome (int panel, int control, int event,
 
                         void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      SetWaitCursor (1);
 
      if (gMIKRO_X)  MIKRO_ReferenceMove (MIKRO_X);
 
      if (gMIKRO_Y)  MIKRO_ReferenceMove (MIKRO_Y);
 
      if (gMIKRO_Z)  MIKRO_ReferenceMove (MIKRO_Z);
 
      SetWaitCursor (0);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK CBTimer (int panel, int control, int event,
 
                         void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_TIMER_TICK:
 
//      ProcessSystemEvents();
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK GetPosition (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  int xpos=0,ypos=0,zpos=0;
 
  switch (event) {
 
 
 
    case EVENT_COMMIT:
 
 
 
      if (gMIKRO_X) {
 
        MIKRO_GetPosition(MIKRO_X,&xpos);
 
        Delay(0.01);
 
        SetCtrlVal (p2h, P2_X, xpos);
 
      }
 
 
 
      if (gMIKRO_Y) {
 
        MIKRO_GetPosition(MIKRO_Y,&ypos);
 
        Delay(0.01);
 
        SetCtrlVal (p2h, P2_Y, ypos);
 
      }
 
      if (gMIKRO_X) {
 
        MIKRO_GetPosition(MIKRO_Z,&zpos);
 
        Delay(0.01);
 
        SetCtrlVal (p2h, P2_Z, zpos);
 
        sa02Printf("x=%d y=%d z=%d\n",xpos,ypos,zpos);
 
      }
 
 
 
 
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK ReRead (int panel, int control, int event,
 
                        void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int status;
 
      char dfile[MAX_PATHNAME_LEN];
 
      FILE *fp;
 
 
 
      status = FileSelectPopup ("", "*.dat", ".dat",
 
                                "Izberi datoteko s podatki",
 
                                VAL_LOAD_BUTTON, 0, 0, 1, 0, dfile);
 
      if (status==1) {
 
        fp 
= fopen (dfile
, "rb"); 
        status 
= (int) fread (&runrec
, 1, sizeof(runrec
), fp
); 
        if (runrec.id==RUNREC_ID) {
 
          SetCtrlVal (p2h, P2_NX, runrec.nx);
 
          SetCtrlVal (p2h, P2_XSTEP, runrec.dx);
 
          SetCtrlVal (p2h, P2_XMIN, runrec.x0);
 
          SetCtrlVal (p2h, P2_NY, runrec.ny);
 
          SetCtrlVal (p2h, P2_YSTEP, runrec.dy);
 
          SetCtrlVal (p2h, P2_YMIN, runrec.y0);
 
          SetCtrlVal (p2h, P2_NEVE, runrec.nev);
 
          SetCtrlVal (p2h, P2_SCANUNITSX, runrec.fver%2);
 
          SetCtrlVal (p2h, P2_SCANUNITSY, runrec.fver/2);
 
          SetCtrlVal (p2h, P2_DIRECTION, runrec.direction);
 
        }
 
      }
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK Zset (int panel, int control, int event,
 
                      void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int zpos;
 
      GetCtrlVal (p2h, P2_ZSET, &zpos);
 
      if (gMIKRO_Z) MIKRO_MoveTo (MIKRO_Z, zpos);
 
 
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK HidePanelCB (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      HidePanel (panel);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int GetChannelPosition(int chip, int ch, int *chx, int *chy) {
 
 
 
  int i=0;
 
 
 
  for (i=0; i<144; i++) {
 
 
 
    if (eid2hapdxy[i].chip == chip && eid2hapdxy[i].ch == ch) {
 
      *chx   = eid2hapdxy[i].chx;
 
      *chy   = eid2hapdxy[i].chy  ;
 
      return 0;
 
    }
 
  }
 
  return -1;
 
 
 
}
 
 
 
int LoadElectronicMap(const char *fname) {
 
 
 
  FILE 
*fp 
= fopen(fname
,"r"); 
  int chip,ch,chx,chy,chxr,chyr;
 
  int nread=0;
 
  int ndim=400;
 
  char line[400];
 
  int  nr=0;
 
 
 
  while (fgets(line
,ndim
,fp
)!=NULL
) {  
 
 
    nr 
= sscanf(line
,"%d%d%d%d",&chip
,&ch
,&chxr
,&chyr
); 
    if (nr) {
 
// Orientation of HAPD in xy system - position of APD A:LR,UR,UL,LL and view:B,F
 
//LRB
 
//      chx=11-chxr;
 
//      chy=11-chyr;
 
//URB
 
      chx=chyr;
 
      chy=11-chxr;
 
//ULB
 
//      chx=chxr;
 
//      chy=chyr;
 
//LLB
 
//      chx=11-chyr;
 
//      chy=chxr;
 
      eid2hapdxy[nread].chip = chip;
 
      eid2hapdxy[nread].ch   = ch  ;
 
      eid2hapdxy[nread].chx  = chx ;
 
      eid2hapdxy[nread].chy  = chy ;
 
    }
 
    nread++;
 
  }
 
  sa02Printf("eid2hapdxy %d records read.\n",nread);
 
  return 0;
 
 
 
}
 
 
 
int CVICALLBACK SetParameters (int panel, int control, int event,
 
                               void *callbackData, int eventData1, int eventData2) {
 
  //uint32_t address;
 
  //char saddress[0xFF],
 
  char fname[0xFF];
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal(p3h, P3_INPUTFILE, fname);
 
      SetParametersFromFile(fname);
 
 
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK UploadGlobalParameters (int panel, int control, int event,
 
                                        void *callbackData, int eventData1, int eventData2) {
 
  uint32_t response[2]= {0,0};
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 1);
 
      {
 
        uint32_t gdata;
 
 
 
        int board,asic;
 
        int i=0,imin=0,imax=0;
 
        Rect trange;
 
        Point cell;
 
        int row=0;
 
        unsigned short val;
 
        sa02AsicGlobalRegister  *greg = (sa02AsicGlobalRegister *) &gdata ;
 
        uint16_t mask=GetConnectedFebMask();
 
//        GetCtrlVal(p1h,P1_BOARDNUMBER,&board);
 
        GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
 
 
        if (control== P3_SELGPARLOAD) {
 
          GetTableSelection (p3h, P3_GREG, &trange);
 
          if ((trange.top!=0)&&(trange.left!=0)) {
 
            imin= trange.top - 1;
 
            imax= imin + trange.height;
 
 
 
          } else {
 
            if (!GetActiveTableCell(p3h, P3_GREG, &cell)) {
 
              imin = cell.y-1;
 
              imax = imin;
 
            } else return 0;
 
          }
 
        } else {
 
          imin=0;
 
          imax=4*4;
 
        }
 
 
 
        for (i=imin; i<imax; i++) {
 
          row=i+1;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (1,row), &val);
 
          greg->phasecmps = val;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (2,row), &val);
 
          greg->gain = val;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (3,row), &val);
 
          greg->shapingtime = val;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (4,row), &val);
 
          greg->comparator = val;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (5,row), &val);
 
          greg->vrdrive = val;
 
          GetTableCellVal (p3h, P3_GREG, MakePoint (6,row), &val);
 
          greg->monitor = val;
 
          //GetTableCellVal (p3h, P3_GREG, MakePoint (7,row), &val); greg->id = val;
 
          greg->id = 0;
 
          greg->unused=0;
 
          board=i/4;
 
          asic=i%4;
 
 
 
          if (mask & (1<<board) ) sa02Cmd(board,SA0x_ASIC0_GREG, gdata, asic, 0,1,response);
 
          if (ctrl_c) {
 
            break;
 
          }
 
        }
 
      }
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 0);
 
      sa02Printf("Global Parameters Uploaded to the ASICs\n");
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK UploadChannelParameters (int panel, int control, int event,
 
    void *callbackData, int eventData1, int eventData2) {
 
  uint32_t response[2]= {0,0};
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 1);
 
      {
 
        uint32_t cdata;
 
        int state;
 
        Rect trange;
 
        Point cell;
 
 
 
        sa02AsicChannelRegister *creg = (sa02AsicChannelRegister *) &cdata ;
 
 
 
        unsigned int i=0,imin=0,imax=0;
 
        int row=0;
 
        uint32_t board;
 
        uint16_t mask=GetConnectedFebMask();
 
 
 
        unsigned short val,asic,ch;
 
 
 
//        GetCtrlVal(p1h,P1_BOARDNUMBER, &board);
 
        GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
 
 
        if ((panel==p3h)&&(control==P3_SELCPARLOAD)) {
 
          state = GetTableSelection (p3h, P3_CREG, &trange);
 
          if ((trange.top!=0)&&(trange.left!=0)) {
 
            imin= trange.top-1;
 
            imax= imin + trange.height;
 
 
 
          } else {
 
            if (!GetActiveTableCell(p3h, P3_CREG, &cell)) {
 
              imin = cell.y-1;
 
              imax = imin+1;
 
            } else return 0;
 
          }
 
        } else if ((panel==p1h)&&(control==P1_CHPARLOAD)) {
 
          GetCtrlVal(p1h,P1_NSLIX,&imin);
 
          imax=imin+1;
 
        } else {
 
          imin=0;
 
          imax=144*4;
 
        }
 
 
 
        for (i=imin; i<imax; i++) {
 
//          asic=(unsigned short )(i/36);
 
//          ch=(unsigned short )(i%36);
 
          int err = 0;
 
          row=i+1;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (1,row), &asic)) err=1;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (2,row), &ch)) err=1;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (3,row), &val)) err=1;
 
          creg->decaytime=val;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (4,row), &val)) err=1;
 
          creg->offset = val;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (5,row), &val)) err=1;
 
          creg->fineadj_unipol = val;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (6,row), &val)) err=1;
 
          creg->fineadj_diff = val;
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (7,row), &val)) err=1;
 
          creg->tpenb = val;
 
          //sa02Printf("===%d   %d\n",i, val);
 
          if (GetTableCellVal (p3h, P3_CREG, MakePoint (8,row), &val)) err=1;
 
          creg->kill = val;
 
          creg->unused=0;
 
          board=i/144;
 
          if (mask & (1<<board) ) sa02Cmd(board,SA0x_ASIC0_CREG, cdata, asic, ch,1,response);
 
          if (sa02Verbose >0) {
 
            sa02Printf("===%d\n",i);
 
          }
 
          if (err) sa02Printf("*** Table read error at row %d ***\n",row);
 
          if (ctrl_c) {
 
            break;
 
          }
 
        }
 
        sa02Printf("Channel Parameters Uploaded to the ASICs\n");
 
 
 
      }
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 0);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK UploadFPGAParameters (int panel, int control, int event,
 
                                      void *callbackData, int eventData1, int eventData2) {
 
 
 
  int n=0;
 
  int i=0;
 
  int nb=0;
 
#define NDIM 400
 
  int asic=0;
 
  char buf[NDIM];
 
  char cmd[NDIM];
 
  char sasic[NDIM];
 
  uint32_t sa02code;
 
  uint32_t board;
 
  uint32_t response[2]= {0,0};
 
 
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      uint16_t mask=GetConnectedFebMask();
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 1);
 
 
 
      GetNumTextBoxLines(p3h, P3_FPGAPAR,&n);
 
      for (i=0; i<n; i++) {
 
        GetTextBoxLine(p3h, P3_FPGAPAR, i, buf);
 
        nb 
= sscanf(buf
,"%s%s",cmd
,sasic
); 
        sa02code = sa02GetCmdCode(cmd);
 
        if (strcmp(cmd
,"MUXASIC")==0) {  
          asic = sa02MuxMap(asic);
 
        }
 
        for (board = 0; board < 4; board ++) if ( mask & (1 << board) ) sa02Cmd(board,sa02code, asic, 0, 0, 2,response);
 
        sa02Printf("%s\n",buf);
 
      }
 
      sa02Printf("FPGA Parameters Uploaded to FEBS\n");
 
      SetCtrlAttribute (panel, control, ATTR_DIMMED, 0);
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK SetSelectionToVal (int panel, int control, int event,
 
                                   void *callbackData, int eventData1, int eventData2) {
 
  int state, input_cid=-1,output_cid=-1;
 
  Rect trange;
 
  unsigned short value;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      switch (control) {
 
        case P3_SETSELCPAR:
 
          input_cid=P3_SETCPAR;
 
          output_cid=P3_CREG;
 
          break;
 
        case P3_SETSELGPAR:
 
          input_cid=P3_SETGPAR;
 
          output_cid=P3_GREG;
 
          break;
 
 
 
      }
 
      state = GetTableSelection (p3h, output_cid, &trange);
 
      if ((trange.top!=0)&&(trange.left!=0)) {
 
        GetCtrlVal(p3h,input_cid, &value);
 
        state = FillTableCellRange (p3h, output_cid, trange, value);
 
      }
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK SelectMux (int panel, int control, int event,
 
                           void *callbackData, int eventData1, int eventData2) {
 
  int cid[4]= {P3_MUX0,P3_MUX1,P3_MUX2,P3_MUX3};
 
  int id=0,i;
 
  uint32_t sa02code;
 
  uint32_t board;
 
  uint32_t response[2]= {0,0};
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
 
 
      switch (control) {
 
        case P3_MUX0:
 
          id=0;
 
          break;
 
        case P3_MUX1:
 
          id=1;
 
          break;
 
        case P3_MUX2:
 
          id=2;
 
          break;
 
        case P3_MUX3:
 
          id=3;
 
          break;
 
        default:
 
          id=0;
 
      }
 
      SetCtrlVal(panel,control,1);
 
      sa02code = sa02GetCmdCode("MUX");
 
      GetCtrlVal(p1h,P1_BOARDNUMBER,&board);
 
      sa02Cmd(board,sa02code, id, 0, 0, 2,response);
 
 
 
 
 
      for (i=0; i<4; i++) {
 
        if (id!= i) {
 
          SetCtrlVal(panel,cid[i],0);
 
        }
 
      }
 
      sa02Printf("MUX %d\n",id);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK UploadFromPanels (int panel, int control, int event,
 
                                  void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      UploadFPGAParameters(panel,control,event,callbackData,eventData1,eventData2);
 
      UploadChannelParameters(panel,control,event,callbackData,eventData1,eventData2);
 
      UploadGlobalParameters(panel,control,event,callbackData,eventData1,eventData2);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
double erf(double x, double par[], int npar) {
 
  double y=0;
 
  double x0= (x-par[0])*par[1];
 
  Erf(x0,&y);
 
  return (y);
 
}
 
 
 
int CVICALLBACK FitH2D (int panel, int control, int event,
 
                        void *callbackData, int eventData1, int eventData2) {
 
  char name[MAX_PATHNAME_LEN];
 
 
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      //sprintf(name ,"C:\\root\\bin\\root.exe");
 
      int status;
 
      char dfile[MAX_PATHNAME_LEN];
 
      char efile[MAX_PATHNAME_LEN];
 
 
 
      status = FileSelectPopup ("data", "*.th2d", ".th2d",
 
                                "Izberi datoteko s histogramom",
 
                                VAL_LOAD_BUTTON, 0, 0, 1, 0, efile);
 
      EscapeString(efile,dfile);
 
      sprintf(name 
,"C:/root/bin/root.exe ../macros/sa02fit.cxx(\\\"%s\\\")", dfile
);  
 
 
 
 
 
 
      sa02Printf("%s\n",name);
 
 
 
      LaunchExecutable(name);
 
 
 
 
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
double Round(double x) {
 
 
 
  int ix= (int)x;
 
  if (x>0) {
 
    if (x - ix > 0.5 ) {
 
      return ix+1;
 
    } else {
 
      return ix;
 
    }
 
  } else {
 
    if (x - ix < -0.5 ) {
 
      return ix-1;
 
    } else {
 
      return ix;
 
    }
 
  }
 
 
 
 
 
}
 
 
 
//const double ffine    = -1.45; //  dac steps/offset unit  (fine)
 
const double foffset  = -13.;  // dac steps/offset unit (coarse)
 
const double ffine    = foffset/16.; //  dac steps/offset unit  (fine)
 
 
 
double sa02getshift(int offset, int fineadj_unipol ) {
 
 
 
  int c=offset;
 
  int f=fineadj_unipol;
 
  if (c>7) {
 
    c-=16;
 
  }
 
  if (f>7) {
 
    f-=16;
 
  }
 
  return foffset*c+ffine*f;
 
}
 
 
 
double sa02getoffset(double x, double fx, int *dx) {
 
 
 
  *dx = (int) Round(x/ fx) ;
 
  if (*dx>7) {
 
    *dx=7;
 
  }
 
  if (*dx<-8) {
 
    *dx=-8;
 
  }
 
  x=x-(*dx)*fx;
 
  if (*dx<0) {
 
    *dx+=16;
 
  }
 
  return x;
 
}
 
 
 
//______________________________________________________________________________
 
double GetMean(int fNpoints, double *fX, double *fY) {
 
// Return mean value of X
 
  int i;
 
  double sumw  = 0;
 
  double sumwx = 0;
 
  if (fNpoints <= 0) {
 
    return 0;
 
  }
 
 
 
  for (i=0; i<fNpoints; i++) {
 
    sumw += fY[i];
 
    sumwx += fX[i]* fY[i];
 
  }
 
  return sumwx/sumw;
 
}
 
 
 
//______________________________________________________________________________
 
double GetRMS(int fNpoints, double *fX, double *fY) {
 
// Return RMS of X
 
 
 
  int i;
 
  double sumw = 0, sumwx = 0,mean,rms2;
 
  double sumwx2 = 0;
 
  if (fNpoints <= 0) {
 
    return 0;
 
  }
 
 
 
  for (i=0; i<fNpoints; i++) {
 
    sumwx += fX[i]* fY[i];
 
    sumw += fY[i];
 
    sumwx2 += fX[i]* fX[i]* fY[i];
 
 
 
  }
 
  if (sumw <= 0) {
 
    return 0;
 
  }
 
  mean = sumwx/sumw;
 
  rms2 
= fabs(sumwx2
/sumw 
-mean
*mean
); 
}
 
 
 
 
 
int FitGraph(int mode, int n, double *x, double *y, double *par) {
 
  const double threshold=0.5;
 
  ssize_t i,imax,imin;
 
  double dmax,dmin;
 
//  double rms=0;
 
//  double sum=0;
 
 
 
  MaxMin1D(y,n,&dmax,&imax,&dmin,&imin);
 
  switch (mode) {
 
    case 0:
 
      par[0]=x[imax];
 
      par[1]=0;
 
      break;
 
    case 1:
 
      for (i=0; i<n; i++)
 
        if (y[i]>threshold) {
 
          par[0]=x[i];
 
        }
 
      par[1]=0;
 
      break;
 
    case 2:
 
      par[0]=GetMean(n,x,y);
 
      par[1]=GetRMS(n,x,y);
 
      break;
 
    case 3:
 
      break;
 
    case 4: {
 
      int npar=2;
 
      double fitpar[2];
 
      double rms;
 
      NonLinearFit (y, x, datayfit,n, erf, fitpar, npar, &rms);
 
      par[0]=0;
 
      par[1]=0;
 
      break;
 
    }
 
    default:
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK FitH2DCoarse (int panel, int control, int event,
 
                              void *callbackData, int eventData1, int eventData2) {
 
  double mean[144*2*4];
 
  double rms[144*2*4];
 
  int ix,iy;
 
 
 
  double fpar[3]= {0,0,0};
 
  int h2=0;
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      unsigned short offsets[144*2*4];
 
      double x;
 
      int offset=0, fineadj_unipol=0;
 
      //unsigned short val;
 
      double mean0,rms0;
 
      uint16_t mask=GetConnectedFebMask();
 
      int nch = H2DGetNbinsX(h2);
 
      int npt = H2DGetNbinsY(h2);
 
      int fitmode  =0;
 
      double minx  =  H2DGetMinX(h2);
 
      double stepx =  H2DGetStepX(h2);
 
      GetCtrlVal(p3h,P3_FITMODE,&fitmode);
 
      GetCtrlVal(p3h,P3_TARGETOFFSET,&mean0);
 
      GetCtrlVal(p3h,P3_TARGETRMS,&rms0);
 
      for (iy=0; iy < npt; iy++ ) {
 
        datax[iy] = H2DGetYBinCenter(h2,iy);
 
      }
 
      GetTableCellRangeVals (p3h, P3_CREG, MakeRect (1, 4, 144*4, 2), offsets, VAL_ROW_MAJOR);
 
      for (ix=0; ix < nch; ix++ ) {
 
        if (!(mask & (1<<(ix/144)) )) {
 
          mean[ix] = datax[0];
 
          rms[ix]  = 0;
 
          continue;
 
        }
 
        for (iy=0; iy < npt; iy++ ) {
 
          datay[iy] = H2DGetBinContent(h2,ix,iy); // /H2DGetMax(h2);
 
        }
 
        FitGraph(fitmode, npt, datax , datay, fpar);
 
        mean[ix]=fpar[0];
 
        rms[ix] =fpar[1];
 
        offset         = offsets[ix*2];
 
        fineadj_unipol = offsets[ix*2+1];
 
 
 
        x =  sa02getshift(offset, fineadj_unipol);
 
        x += (mean0-(mean[ix]+rms0*rms[ix]));
 
        /*if (x<0) {
 
          sa02Printf(" ch. %d mean+%f*sigma %g above threshold %f \n",ix, rms0,mean[ix]+rms0*rms[ix],mean0);
 
        }*/
 
        x = sa02getoffset(x, foffset, &offset);
 
        x = sa02getoffset(x, ffine  , &fineadj_unipol);
 
        //sa02Printf("offsets ch. %d mean=%f rms %f  shift=%f calcshift=%f offset %d fineadj %d\n",ix, mean[ix],rms[ix], x, sa02getshift(offset, fineadj_unipol),offset, fineadj_unipol);
 
        offsets[ix*2]=(unsigned short) offset;
 
        offsets[ix*2+1]=(unsigned short) fineadj_unipol;
 
        ProcessSystemEvents();
 
      }
 
 
 
      SetTableCellRangeVals (p3h, P3_CREG, MakeRect (1, 4, 144*4, 2), offsets, VAL_ROW_MAJOR);
 
 
 
 
 
      if (nch>0) {
 
        if (plothandle2dfit) {
 
          DeleteGraphPlot (p1h, P1_GRAPH2D, plothandle2dfit, VAL_IMMEDIATE_DRAW);
 
        }
 
        plothandle2dfit = PlotWaveform (p1h, P1_GRAPH2D, mean, nch,
 
                                        VAL_DOUBLE, 1.0, 0.0, minx,
 
                                        stepx, VAL_FAT_LINE,
 
                                        VAL_EMPTY_SQUARE, VAL_SOLID, 1,
 
                                        VAL_YELLOW);
 
        if (plothandleslix) {
 
          DeleteGraphPlot (p1h, P1_GRAPHY, plothandleslix, VAL_IMMEDIATE_DRAW);
 
        }
 
 
 
        plothandleslix = PlotWaveform (p1h, P1_GRAPHY, rms, nch,
 
                                       VAL_DOUBLE, 1.0, 0.0, minx,
 
                                       stepx, VAL_FAT_LINE,
 
                                       VAL_EMPTY_SQUARE, VAL_SOLID, 1,
 
                                       VAL_BLUE);
 
        sa02Printf("offset calculated:\n");
 
      }
 
    }
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK LedCB (int panel, int control, int event,
 
                       void *callbackData, int eventData1, int eventData2) {
 
 
 
  if (!gBELLEPTS)return 0;
 
 
 
  switch (event) {
 
 
 
    case EVENT_COMMIT: {
 
      char saddress[0xFF];
 
      uint32_t address;
 
      uint32_t value=0;
 
      GetCtrlVal(p3h,P3_ADDRESS, saddress);
 
      address 
=  strtoul (saddress
,NULL
,0); 
      VME_A32D32_R(address+FEB_DEADBEEF, &value);
 
      sa02Printf("READ at FEB_DEADBEEF 0x%08x\n",  value);
 
 
 
 
 
      GetCtrlVal(p1h,P1_PTSLED,&value);
 
      value++;
 
      sa02Printf("LedCB ADDR 0x%08x VAL %d\n",address,  value);
 
      //VME_A24D32_W(address,&value);
 
 
 
      VME_A32D32_W(address,value);
 
      /*
 
      NIM standard level ports.
 
 
 
            You should write 0x7600 to address : baseaddress + 4 .
 
 
 
            0x7600 means the connection
 
            CLKOUT1 -> 7 -> CLK_VOUT1 (VOUT1 pin of FPGA)
 
            CLKOUT0 -> 6 -> CLK_VOUT0 (VOUT1 pin of FPGA)
 
            SCLK    -> 0 -> CLK_IN    (internal clock)
 
            PCLK    -> 0 -> CLK_IN    (internal clock)
 
      */
 
 
 
      if (value==2) {
 
        value=0x7600;
 
      } else {
 
        value=0;
 
      }
 
      VME_A32D32_W(address+4,value); // enable outputs
 
    }
 
    sa02Printf("SizeOf(Double)=%d\n",sizeof(double));
 
    break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK SetPositionAndMux (int panel, int control, int event,
 
                                   void *callbackData, int eventData1, int eventData2) {
 
  const float fx= (float)(1000./0.3595); // 4M scaling factor steps/mm
 
  int chx,x0,chy,y0;
 
  float gapx,gapy, dx , dy;
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal (p2h, P2_CHX,  &chx);
 
      GetCtrlVal (p2h, P2_CHY,  &chy);
 
      GetCtrlVal (p2h, P2_GAPX,  &gapx);
 
      GetCtrlVal (p2h, P2_GAPX,  &gapy);
 
      GetCtrlVal (p2h, P2_DX, &dx);
 
      GetCtrlVal (p2h, P2_DX, &dy);
 
      GetCtrlVal (p2h, P2_XC,  &x0);
 
      GetCtrlVal (p2h, P2_YC,  &y0);
 
      y0 = (int)(y0 - 5.5* fx * dy  - gapy * fx * 0.5);
 
      x0 = (int)(x0 - 5.5* fx * dx  - gapx * fx * 0.5);
 
      if (gMIKRO_Y) {
 
        posrec.yset =  (int32_t)(y0+dy *fx * chy);
 
        if (chy>5) {
 
          posrec.yset +=gapy * fx;
 
        }
 
        MIKRO_MoveTo (MIKRO_Y, posrec.yset);
 
        sa02Printf("->MIKRO_MoveTo (2, y);%d\n",posrec.yset);
 
      }
 
      if (gMIKRO_X) {
 
        posrec.xset=(int32_t)(x0+dx*fx*chx);
 
        if (chx>5) {
 
          posrec.xset +=gapx * fx;
 
        }
 
        MIKRO_MoveTo (MIKRO_X, posrec.xset);
 
        sa02Printf("->MIKRO_MoveTo (1, x);%d\n",posrec.xset);
 
      }
 
//      GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
      SetCMon(chx,chy);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK SetCenter (int panel, int control, int event,
 
                           void *callbackData, int eventData1, int eventData2) {
 
  int x0,y0;
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal (p2h, P2_XC,  &x0);
 
      GetCtrlVal (p2h, P2_YC,  &y0);
 
      if (gMIKRO_X)  MIKRO_MoveTo (MIKRO_X, x0);
 
      if (gMIKRO_Y)  MIKRO_MoveTo (MIKRO_Y, y0);
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle,
 
                               CmtThreadFunctionID functionID, unsigned int event,
 
                               int value, void *callbackData  ) {
 
 
 
  daq_on=0;
 
  SetDimming(0);
 
  sa02Printf("End of Thread \n");
 
  return ;
 
 
 
}
 
 
 
int Asic_TENB_Shift( void ) {
 
 
 
  int i,stanje;
 
  unsigned short inmask[144], outmask[144], tmp;
 
  for (int board = 0; board<4; board++) {
 
    stanje = GetTableCellRangeVals (p3h, P3_CREG, MakeRect (1+board*144, 7, 144, 1),
 
                                    inmask, VAL_COLUMN_MAJOR);
 
    tmp = inmask[143];
 
    for (i=0; i<143; i++) {
 
      outmask[i+1]=inmask[i];
 
    }
 
    outmask[0]=tmp;
 
 
 
    stanje = SetTableCellRangeVals (p3h, P3_CREG, MakeRect (1+board*144, 7, 144, 1),
 
                                    outmask, VAL_COLUMN_MAJOR);
 
 
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK daq_scanpar (void *functionData) {
 
 
 
 
 
  char filename[0xFF];
 
  int scanpar=0;
 
  int ix, x0,dx,nx;
 
  int value,state;
 
  Rect save_range,trange;
 
  int cid=0;
 
  int daqexe;
 
  time_t t,told=0, tstart;
 
  FILE *fp;
 
  int spar;
 
  int nch;
 
  const int maxrange[20]= {0,0,8,16,16,16,2,2,2,0, 4,4,4,2,256,4,512};
 
 
 
  trange.top=0;
 
  trange.left=0;
 
 
 
  GetCtrlVal(p3h,P3_SCANPAR, &scanpar);
 
  sa02Printf("%d\n",scanpar);
 
  GetCtrlVal(p3h,P3_X0, &x0);
 
  GetCtrlVal(p3h,P3_DX, &dx);
 
  GetCtrlVal(p3h,P3_NX, &nx);
 
  GetCtrlVal(p3h,P3_DAQEXE,&daqexe);
 
  GetCtrlVal(p1h,P1_OUTPUTFILE, filename);
 
 
 
 
 
  if (!scanpar) {
 
    return 0;
 
  }
 
  if (scanpar>10) {
 
    cid=P3_GREG;
 
    spar=scanpar-10;
 
    nch=4*4;
 
 
 
  } else {
 
    cid=P3_CREG;
 
    spar=scanpar;
 
    nch=144*4;
 
 
 
  }
 
  if (spar==1) {
 
    spar=7;
 
  }
 
  sa02Printf("Range:%d\n",maxrange[scanpar-1]);
 
  state = GetTableSelection (p3h, cid, &save_range);
 
 
 
  trange = MakeRect (1, spar, nch, 1);
 
  state = SetTableSelection (p3h, cid, trange);
 
  if ((trange.top!=0)&&(trange.left!=0)) {
 
 
 
 
 
 
 
    tstart=t;
 
    if (daqexe) {
 
      iteratorrec.id = ITERATORREC_ID;
 
      iteratorrec.len = sizeof(iteratorrec);
 
      iteratorrec.value = x0;
 
      iteratorrec.n     = nx;
 
      iteratorrec.step  = dx;
 
      iteratorrec.level = 2;
 
      fp 
= fopen(filename
, "ab"); 
      if(fp) {
 
        fwrite (&datrec
, 1, datrec.
len, fp
);  
      }
 
      sa02Printf("new ITERATORREC recid=0x%x\n", iteratorrec.id);
 
    }
 
 
 
 
 
    for (ix=0; ix<nx; ix++) {
 
      value = ix*dx + x0;
 
      if (scanpar!=1) {
 
        state = FillTableCellRange (p3h, cid, MakeRect (1, spar, nch, 1), value%maxrange[scanpar-1]);
 
        if (maxrange[scanpar-1] && value/maxrange[scanpar-1]) {
 
          state = FillTableCellRange (p3h, cid, MakeRect (1, spar-1, nch, 1), value/maxrange[scanpar-1]);
 
        }
 
      }
 
      switch (cid) {
 
        case P3_CREG:
 
          UploadChannelParameters(p3h,cid,EVENT_COMMIT,functionData,0,0);
 
          break;
 
        case P3_GREG:
 
          UploadGlobalParameters (p3h,cid,EVENT_COMMIT,functionData,0,0);
 
          break;
 
      }
 
      if (scanpar==1) {
 
        Asic_TENB_Shift();
 
      }
 
      if (t!=told  ) {
 
        ProcessSystemEvents ();
 
      }
 
      if (ctrl_c) {
 
        break;
 
      }
 
 
 
      if (daqexe) {
 
        datrec.id = DATREC_ID;
 
        datrec.len = sizeof(datrec);
 
        datrec.cmd    =0xBEEF0000+ scanpar;
 
        datrec.data   =value;
 
        datrec.chip   =-1;
 
        datrec.channel=-1;
 
        datrec.retval =value;
 
 
 
        fp 
= fopen(filename
, "ab"); 
        if(fp) {
 
          fwrite (&datrec
, 1, datrec.
len, fp
);  
        }
 
        sa02Printf("new DATREC recid=0x%x  datrec->cmd=0x%x\n", datrec.id , datrec.cmd);
 
        daq(NULL);
 
        sa02Printf("H2D image saved as %s\n", filename);
 
 
 
      }
 
      if (ctrl_c) {
 
        break;
 
      }
 
 
 
      if (t!=told  ) {
 
        ProcessSystemEvents ();
 
      }
 
      told=t;
 
 
 
    }
 
  }
 
  state = SetTableSelection (p3h, cid, save_range);
 
 
 
 
 
 
 
 
 
 
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK ExportParameters (int panel, int control, int event,
 
                                  void *callbackData, int eventData1, int eventData2) {
 
  int status;
 
  char filename[MAX_PATHNAME_LEN];
 
  switch (event) {
 
    case EVENT_COMMIT:
 
 
 
      status = FileSelectPopup ("./parameters/", "*.param", "*.param",
 
                                "Export Parameters to file", VAL_SAVE_BUTTON, 0,
 
                                0, 1, 1, filename);
 
      sa02Printf("ExportParameters to %d\n",MAX_PATHNAME_LEN);
 
      switch (status) {
 
        case 1:
 
          MessagePopup ("Warning", "File exist. Remove it first or choose another file");
 
          break;
 
        case 2: {
 
          int n,i,row,asic,ch;
 
          unsigned short val;
 
          time_t t;
 
          char buf[MAX_PATHNAME_LEN];
 
          FILE   
*fp 
= fopen(filename
, "w"); 
          if (fp) {
 
            //--------------------------------------------------- Parameters header
 
            fprintf(fp
, "#Parameter exported from CVI %s\n",ctime(&t
) );  
            //--------------------------------------------------- FPGA parameters
 
            GetNumTextBoxLines(p3h, P3_FPGAPAR,&n);
 
            for (i=0; i<n; i++) {
 
              GetTextBoxLine(p3h, P3_FPGAPAR, i, buf);
 
            }
 
            //--------------------------------------------------- Global parameters
 
            for (row=1; row<1+16; row++) {
 
              int irow = (row-1)%4;
 
              int iboard = (row-1)/4;
 
              if ( (row
-1)%4 == 0 ) fprintf(fp
, "param_board %d\n",iboard
);  
              fprintf(fp
, "## global parameter for chip %d\n",(row
-1)%4);  
              fprintf(fp
, "param_global %d 0x1ffff\n",irow
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (1,row), &val);
 
              fprintf(fp
, "phasecmps %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (2,row), &val);
 
              fprintf(fp
, "gain %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (3,row), &val);
 
              fprintf(fp
, "shapingtime %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (4,row), &val);
 
              fprintf(fp
, "comparator %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (5,row), &val);
 
              fprintf(fp
, "vrdrive %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (6,row), &val);
 
              fprintf(fp
, "monitor %d 0x%x\n",irow
,val
);  
              GetTableCellVal (p3h, P3_GREG, MakePoint (7,row), &val);
 
              fprintf(fp
, "id %d 0x%x\n",irow
,val
);  
 
 
              fprintf(fp
, "load_global  %d\n\n\n",irow
);  
            }
 
 
 
            //--------------------------------------------------- Channel parameters
 
            for (i=0; i<144*4; i++) {
 
              int board = i/144;
 
              int j= i%144;
 
              asic=(j/36);
 
              ch=j%36;
 
              row=(i+1);
 
              if (i%36==0) {
 
                fprintf(fp
, "# channel parameter for chip %d\n\n",asic
);  
              }
 
 
 
              if (i
%144 == 0) fprintf(fp
, "param_board %d\n",board
);  
              fprintf(fp
, "param_ch       %d %d 0x0000\n",asic
,ch
);  
 
 
              GetTableCellVal (p3h, P3_CREG, MakePoint (3,row), &val);
 
              fprintf(fp
, "decaytime %d %d 0x%x\n",asic
,ch
,val
);  
              GetTableCellVal (p3h, P3_CREG, MakePoint (4,row), &val);
 
              fprintf(fp
, "offset %d %d 0x%x\n",asic
,ch
,val
);  
              GetTableCellVal (p3h, P3_CREG, MakePoint (5,row), &val);
 
              fprintf(fp
, "fineadj_unipol %d %d 0x%x\n",asic
,ch
,val
);  
              GetTableCellVal (p3h, P3_CREG, MakePoint (6,row), &val);
 
              fprintf(fp
, "fineadj_diff %d %d 0x%x\n",asic
,ch
,val
);  
              GetTableCellVal (p3h, P3_CREG, MakePoint (7,row), &val);
 
              fprintf(fp
, "tpenb %d %d 0x%x\n",asic
,ch
,val
);  
              GetTableCellVal (p3h, P3_CREG, MakePoint (8,row), &val);
 
              fprintf(fp
, "kill %d %d 0x%x\n",asic
,ch
,val
);  
              fprintf(fp
, "load_ch  %d %d\n\n\n",asic
,ch
);  
            }
 
 
 
 
 
          }
 
          break;
 
        }
 
      }
 
 
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
 
 
int ProcessUserEvent(int pID, int rID,int mode){    
 
    ThreadFunctionPtr mythread = NULL; 
 
    if (pID ==p1h && rID == P1_DAQ            ) mythread=daq;
 
    if (pID ==p1h && rID == P1_READOUT        ) mythread=daq_readonly;
 
    if (pID ==p1h && rID == P1_FPGAWRITE      ) mythread=MultiFpgaWrite;
 
    if (pID ==p1h && rID == P1_MULTIFPGAWRITE ) mythread=MultiFpgaWrite;
 
    if (pID ==p1h && rID == P1_TESTING        ) mythread=Testing;
 
    if (pID ==p2h && rID == P2_DAQ            ) mythread=daq_scan;
 
    if (pID ==p6h && rID == MINIRICH_START    ) mythread=daq; 
 
    if (pID ==p2h && rID == P2_RUNSCRIPT      ) {
 
      char scriptname[MAX_PATHNAME_LEN] ;
 
 
 
      int status = FileSelectPopup ("./scripts/", "*.txt", "*.txt",
 
                                    "Select Script file", VAL_LOAD_BUTTON, 0, 0,
 
                                    1, 0, scriptname);
 
      if (status) {
 
        SetCtrlVal(p1h, P1_SCRIPTNAME, scriptname );
 
        mythread=run_script;
 
      }
 
    }
 
    if (pID ==p1h && rID == P1_RUNSCRIPT      ) mythread=run_script;
 
    if (pID ==p3h && rID == P3_DAQ            ) mythread=daq_scanpar;
 
    if (pID ==p4h && rID == P4_DAQ            ) mythread=V729_daq;
 
    if (mythread!=NULL) {
 
      sa02Printf("New Thread panel=%d button=%d\n", pID, rID);
 
      ctrl_c=0;
 
      daq_on = 1;
 
      SetDimming(1); 
 
      if (mode){
 
        CmtScheduleThreadPoolFunctionAdv (poolHandle, mythread, &rID,
 
                                        DEFAULT_THREAD_PRIORITY,
 
                                        EndOfThread,
 
                                        EVENT_TP_THREAD_FUNCTION_END,
 
                                        NULL, RUN_IN_SCHEDULED_THREAD,
 
                                        &tfID);
 
      } else {
 
        mythread(NULL);
 
      }  
 
    }
 
 
 
    if ( pID==p1h && rID == P1_SLOWC ) {
 
      uint32_t board;
 
      GetCtrlVal(p1h,P1_BOARDNUMBER, &board);
 
      SlowControl(board, NULL);
 
    }
 
    // if ( pID==p1h && rID == P1_STEPONE )       StepOne();
 
    if ( pID==p1h && rID == P1_FEBTESTANA ) FebTestAna();
 
    if ( pID==p1h && rID == P1_TEST )       FebTest();
 
    if ( pID==p1h && rID == P1_MODULETEST ) ModuleTest();
 
 
 
    if ( pID==p1h && rID == P1_GET_FPGA_SERIAL ) {
 
      int ison=0;
 
      GetCtrlVal(p1h,P1_BOARDTYPE,&sa02BoardType);
 
      for (int board=0; board<4; board++) {
 
        char saddress[0xff]="";
 
        GetCtrlVal(p1h, hapd_onoff[board], &ison);
 
        sa02GetSerial(board, saddress);
 
        sa02Printf("SERIAL FPGA = %s \n", saddress);
 
        SetCtrlVal(p1h,fpga_serials[board],saddress);
 
      }
 
    };
 
 
 
    if ( ( pID==p1h && rID == P1_STOP )
 
         || ( pID==p2h && rID == P2_STOP )
 
         || ( pID==p3h && rID == P3_STOP )  
 
         || ( pID==p6h && rID == MINIRICH_STOP )  
 
         || ( pID==p4h && rID == P4_STOP ) ) {
 
      sa02Printf("Stopping the  Thread %d\n", tfID);
 
      ctrl_c=1;
 
    }
 
    if (pID ==p5h) {
 
      if (rID == P5_SET_DAC_HV_ON) set_dac(1);
 
      if (rID == P5_SET_DAC_HV_OFF) set_dac(0);
 
      if (rID == P5_SET_HV_ON) set_hv(1);
 
      if (rID == P5_SET_HV_OFF) set_hv(0);
 
    }
 
    return 0;
 
}
 
 
 
 
 
 
 
void CVICALLBACK QueueUserEventCallback (CmtTSQHandle queueHandle, unsigned int event, int value, void *callbackData) {
 
  //int *data= (int *)  callbackData;
 
  int mdata[2];
 
  CmtReadTSQData (queueHandle, mdata, 1, 0, 0);
 
  sa02Printf("QueueUserEvent --->TSQ  %d %d\n", mdata[0],mdata[1]);
 
  QueueUserEvent (1001, mdata[0], mdata[1]);
 
}
 
 
 
/*************************** MAIN ***************************/
 
 
 
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
                       LPSTR lpszCmdLine, int nCmdShow) {
 
 
 
  char title[0xFF];
 
  char saddress[0xff]="";
 
  //uint32_t board;
 
  int i; 
 
  int status=0;
 
 
 
  if (InitCVIRTE (hInstance, 0, 0) == 0) {
 
    return -1;  /* out of memory */
 
  }
 
 
 
  SetSleepPolicy(VAL_SLEEP_MORE);
 
  CmtNewThreadPool (MAX_THREADS,  &poolHandle);
 
 
 
  if ( (status = CmtNewTSQ (1, 2*sizeof(int), OPT_TSQ_AUTO_FLUSH_ALL, &pTSQ)) <0)
 
    printf("CmtNewTSQ cannot be installed\n");  
  if ( (status = CmtInstallTSQCallback (pTSQ, EVENT_TSQ_ITEMS_IN_QUEUE, EVENT_TSQ_QUEUE_SIZE,
 
                                       QueueUserEventCallback, pTSQData, CmtGetCurrentThreadID(), NULL))  <0)
 
    printf("CmtInstallTSQCallback cannot be installed\n");  ;  
 
 
  SetStdioPort (CVI_STDIO_WINDOW );
 
 
 
  readIni("febdaq.ini");
 
 
 
  VME_START(gVME_CONTROLLER);
 
  if ( gCAEN_V288 ) {
 
    V288_Map(0,gCAEN_V288);
 
    V288_Init(0);
 
  }
 
 
 
  if (gMIKRO_PORT) {
 
    MIKRO_Open (gMIKRO_PORT);
 
    if (gMIKRO_X) MIKRO_Init (gMIKRO_X,0);
 
    if (gMIKRO_Y) MIKRO_Init (gMIKRO_Y,0);
 
    if (gMIKRO_Z) MIKRO_Init (gMIKRO_Z,0);
 
  }
 
 
 
  if ((p1h = LoadPanel (0, "sa02_CVI.uir", P1)) < 0) return -1;
 
  if ((p2h = LoadPanel (0, "sa02_CVI.uir", P2)) < 0) return -1;
 
  if ((p3h = LoadPanel (0, "sa02_CVI.uir", P3)) < 0) return -1;
 
  if ((p4h = V729_LoadPanel (0, "CAEN_V729\\CAEN_V729_CVI.uir", P4)) < 0) return -1;
 
  if ((p5h = LoadPanel (0, "sa02_CVI.uir", P5)) < 0) return -1;
 
  if ((p6h = LoadPanel (0, "ICFA\\minirich.uir", MINIRICH)) < 0) return -1; 
 
  if ((pm1 = LoadMenuBar (p1h, "sa02_CVI.uir", MENU)) < 0)  return -1;
 
 
 
  SetPanelMenuBar(p1h, pm1);
 
  DisplayPanel (p1h);
 
 
 
  LoadUirHeader("sa02_CVI.h");
 
  LoadUirHeader("CAEN_V729\\CAEN_V729_CVI.h");
 
 
 
  SetCtrlVal(p2h,P2_XC,gCENTER_X);
 
  SetCtrlVal(p2h,P2_YC,gCENTER_Y);
 
 
 
  SetCtrlVal(p3h, P3_INPUTFILE,gFEBParam);
 
  SetParametersFromFile(gFEBParam);
 
 
 
  SetCtrlAttribute (p1h, P1_GRAPH2D, ATTR_CALLBACK_DATA, (void *)integer_val);
 
  SetCtrlAttribute (p1h, P1_SLIY, ATTR_CALLBACK_DATA, (void *)integer_val);
 
  SetCtrlAttribute (p1h, P1_SLIX, ATTR_CALLBACK_DATA, (void *)integer_val);
 
  SetCtrlAttribute (p1h, P1_NSLIY, ATTR_CALLBACK_DATA, (void *)integer_val);
 
  SetCtrlAttribute (p1h, P1_NSLIX, ATTR_CALLBACK_DATA, (void *)integer_val);
 
 
 
  for (i=0; i<12; i++) {
 
    SetTraceAttributeEx (p1h, chart_control[0], i+1, ATTR_TRACE_LG_TEXT, (char *) slowcname[i]);
 
  }
 
 
 
  GetPanelAttribute (p1h, ATTR_TITLE, title );
 
  if (gVME_CONTROLLER 
== WIENER_VMEMM
) sprintf( title
, "%s + WIENER_VMEMM", title 
);  
  if (gVME_CONTROLLER 
== WIENER_VMUSB
) sprintf( title
, "%s + WIENER_VMUSB", title 
);  
  if (gVME_CONTROLLER 
== CAEN_V1718
) sprintf( title
, "%s + CAEN_V1718", title 
);  
  if (gCAEN_V1495
) sprintf( title
, "%s + CAEN_V1495", title 
);  
  if (gCAEN_V288 
) sprintf( title
, "%s + CAEN_V288", title 
);  
 
 
  if (gBELLEPTS) {
 
    sprintf( title
, "%s + BELLEPTS", title 
);  
    sprintf(saddress
,"0x%08x", gBELLEPTS 
);  
    SetCtrlVal(p3h,P3_ADDRESS,saddress );
 
  }
 
  if (gMIKRO_PORT)
 
    sprintf( title
, "%s + USE_MIKRO", title 
);  
  else
 
    sprintf( title
, "%s + MIKRO not used", title 
);  
  SetPanelAttribute (p1h, ATTR_TITLE, title );
 
 
 
  for (i=0; i<4; i++)
 
    SetCtrlVal(p1h,hapd_onoff[i],gFEBMask&(1<<i));
 
  SetCtrlVal(p1h,P1_SENDSWTRIG,gTriggerType);
 
  SetCtrlVal(p1h,P1_TPENB,CHECK_BIT(uInterf,0));
 
 
 
  sa02SetAddress
(strtoul (saddress
,NULL
,0)); 
 
 
  LedCB(p1h,P1_PTSLED,EVENT_COMMIT, NULL,0,0);
 
 
 
 
 
  StdIo2FileCB (p1h, P1_STDIOLOG, EVENT_COMMIT, NULL,0,0);
 
  InitColors();
 
  sa02Printf("Panels=%d %d %d %d\n", p1h, p2h,p3h,p4h);
 
  GetCtrlVal(p1h,P1_VERBOSE,&sa02Verbose);
 
 
 
  LoadElectronicMap("eid2hapdxy.map");
 
  icfa_Init();
 
  
 
  
 
  loop_on=1;
 
  do {
 
    GetUserEvent (1, &pID, &rID);   
 
    ProcessUserEvent(pID,rID,1);
 
  } while (loop_on);
 
 
 
  CmtDiscardThreadPool (poolHandle);
 
  DiscardPanel (p4h);
 
  DiscardPanel (p3h);
 
  DiscardPanel (p2h);
 
  DiscardPanel (p1h);
 
 
 
  if (gMIKRO_PORT) MIKRO_Close ();
 
 
 
 
 
  VME_STOP();
 
  return 0;
 
}
 
 
 
int CVICALLBACK ResetStdOut (int panel, int control, int event,
 
                             void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      ResetTextBox (p1h,P1_STDIO,"");
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK TrgHvMon (int panel, int control, int event,
 
                          void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_TIMER_TICK:
 
      hvmon=1;
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
//---------------------------------------------------------------------
 
 
 
int Pts_write(uint32_t addr, uint32_t data ) {
 
  VME_A32D32_W(addr,data);
 
  return 0;
 
}
 
 
 
int Pts_Mwrite(uint32_t addr, uint32_t data ) {
 
  VME_MW(VME_A32, VME_D32, addr,data);
 
  return 0;
 
}
 
 
 
int Pts_read(uint32_t addr, uint32_t *data ) {
 
  VME_A32D32_R(addr,data);
 
  return 0;
 
}
 
 
 
int Pts_Mread(uint32_t addr, uint32_t *data ) {
 
  VME_MRRST();
 
  VME_MR(VME_A32, VME_D32,addr, data);
 
  VME_MREXEC(data);
 
  return 0;
 
}
 
 
 
 
 
int Pts_erase( uint32_t addr, int verbose ) {
 
  uint32_t dum;
 
 
 
  Pts_write( addr + ADR_CSR1, 0 );
 
  Delay(0.1);
 
  Pts_read( addr +ADR_CSR1, &dum);
 
  if( verbose ) {
 
    sa02Printf( "CSR1(0x%02x) = 0x%04x\n", ADR_CSR1,dum & 0xffff );
 
 
 
  }
 
  Pts_write( addr +ADR_CSR1, CSR1_PROGRAM_ );
 
  Delay(0.1);
 
  Pts_read( addr +ADR_CSR1, &dum);
 
  if( verbose ) {
 
    sa02Printf( "CSR1(0x%02x) = 0x%04x\n", ADR_CSR1, dum & 0xffff );
 
 
 
  }
 
  return 1;
 
}
 
 
 
int Pts_configure_bit(uint32_t addr, const char *filename, int mode, int verbose ) {
 
  int c,j;
 
  int dummyword;
 
  FILE *fp;
 
  const long byte_per_dot = BYTE_PER_DOT;
 
  unsigned long nchar = 0;
 
 
 
  fp 
= fopen(filename
, "rb"); 
  if( fp == NULL ) {
 
    if( verbose ) {
 
      sa02Printf(  "cannot open \"%s\"\n", filename );
 
    }
 
    return -1;
 
  }
 
  if(verbose) sa02Printf(  "file \"%s\" opened.\n", filename );
 
 
 
  /* ------------------------------------------------------------ *\
 
    The data for the configuration start from 0xffff_ffff_aa99_aa66
 
    ( cf. xapp138; we don't know the definition of the BIT file )
 
  \* ------------------------------------------------------------ */
 
  dummyword = 0;
 
  do {
 
    if( (c 
= getc( fp 
)) == EOF 
) {  
      if(verbose) {
 
        sa02Printf( "EOF detected. Exit.\n");
 
 
 
 
 
      }
 
      return -1;
 
    }
 
    (c == 0xff) ? dummyword++ : (dummyword=0);
 
  } while( dummyword < 4 );
 
 
 
  if( mode == SLAVESERIAL_MODE ) {
 
    if(verbose)  sa02Printf("slave serial mode");
 
    Pts_write( addr +ADR_MODE, mode );
 
    Pts_erase( addr, verbose );
 
    for( j=0; j<32; j++ ) Pts_write( addr + ADR_CFG, 0x1 );
 
    while( (c
=getc(fp
))!=EOF 
) {  
      for( j=0; j<8; j++ ) Pts_write( addr + ADR_CFG, (c>>(7-j))&0x1 );
 
      nchar++;
 
      if( verbose && nchar%byte_per_dot==0 ) {
 
        sa02Printf( "#");
 
      }
 
    }
 
  } else if( mode == SELECTMAP_MODE ) {
 
    if( verbose ) sa02Printf("select map mode\n");
 
    Pts_write( addr + ADR_MODE, SELECTMAP_MODE );
 
    Pts_erase( addr, verbose );
 
    VME_MWRST();
 
    for( j=0; j<4; j++ ) Pts_Mwrite( addr + ADR_CFG, 0xff );
 
    VME_MWEXEC();
 
 
 
    VME_MWRST();
 
    while( (c
=getc(fp
))!=EOF 
) {  
      int cc = 0;
 
      for(j=0; j<8; j++) cc |= ((c&(1<<j))>>j)<<(7-j);
 
      Pts_Mwrite( addr + ADR_CFG, cc );
 
      nchar++;
 
      if( verbose && nchar%byte_per_dot==0 ) {
 
        VME_MWEXEC();
 
        VME_MWRST();
 
        sa02Printf( "#");
 
 
 
      }
 
    }
 
    VME_MWEXEC();
 
  } else {
 
    if(verbose) {
 
      sa02Printf( "\nIllegal mode\n");
 
 
 
    }
 
    return -1;
 
  }
 
  if(verbose) {
 
    sa02Printf("\ntotal %ld bits\n", nchar);
 
  }
 
  return Pts_check_configure( addr, verbose );
 
}
 
 
 
int Pts_check_configure( uint32_t addr ,int verbose ) {
 
  uint32_t csr1_value;
 
  Pts_read(addr + ADR_CSR1,&csr1_value);
 
  if(verbose) {
 
    sa02Printf("CSR1(0x%02x)=0x%04x\n",ADR_CSR1,csr1_value&0xffff);
 
  }
 
  if(csr1_value&CSR1_DONE) {
 
    if(verbose) sa02Printf("configure complete.\n");
 
    return 1;
 
  } else {
 
    if(verbose)  sa02Printf("configure not complete.");
 
    return -1;
 
  }
 
}
 
 
 
 
 
int CVICALLBACK PtsDownloadCB (int panel, int control, int event,
 
                               void *callbackData, int eventData1, int eventData2) {
 
  char filename[254];
 
  int mode=0;
 
  char saddress[0xFF];
 
  uint32_t addr;
 
 
 
 
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal(p3h,P3_ADDRESS, saddress);
 
      GetCtrlVal(p3h,P3_PTSFIRMWARE,filename);
 
      GetCtrlVal(p3h,P3_PTSMODE,&mode);
 
      if(VME_CONNECTED() >=0 ) {
 
        Pts_configure_bit( addr , filename, mode,  1 );
 
      } else {
 
        MessagePopup ("Warning", "Connect VME!!");
 
      }
 
      break;
 
  }
 
  return 0;
 
}
 
 
 
 
 
 
 
int CVICALLBACK SelectPtsOutputCB (int panel, int control, int event,
 
                                   void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      unsigned short value;
 
      GetCtrlVal(panel,control,&value);
 
      sa02Printf("Selecting Pts Output Channel %d\n",value);
 
      Sa02SetPtsOutput(value);
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK SendTriggerTypeCB (int panel, int control, int event,
 
                                   void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT: {
 
      int trglen, trg;
 
      uint16_t mask;
 
      //int ison;
 
      GetCtrlVal(p1h,P1_SENDSWTRIG,&trg);
 
      GetCtrlVal(p1h,P1_INTTRGLEN, &trglen);
 
      mask=GetConnectedFebMask();
 
      sa02Printf("Selecting Trigger %d length of the internal triger %d mask =%04x\n", trg, trglen);
 
      Sa02SelectTriggerWithMaskAndLength (trg, mask, trglen);
 
 
 
      break;
 
    }
 
  }
 
  return 0;
 
}
 
 
 
int CVICALLBACK StdIo2FileCB (int panel, int control, int event,
 
                              void *callbackData, int eventData1, int eventData2) {
 
  switch (event) {
 
    case EVENT_COMMIT:
 
      GetCtrlVal(p1h,P1_STDIOLOG, &gLog);
 
      break;
 
  }
 
  return 0;
 
}