Subversion Repositories f9daq

Rev

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

#define USE_DAQ
#define USE_MIKRO

// Izberi ustrezni interface v meniju projektnega okna
//  Options->CompilerDefines (dodaj /DSISVME ali /DWIENVME)
#ifdef USE_DAQ
#  define USE_CAMAC
#  include "c:\HOME\dino\sipmScan\include\camac.h"
#  ifdef SISVME
#    include "sisvme_dll.h"
#  endif
#  ifdef WIENVME
#    include "wienvme_dll.h"
#  endif
# include "CAENV673A.h"
# include "CAENV462.h"
#endif

#ifdef USE_MIKRO
#  include "MIKRO.h"
#endif

#include <userint.h>
#include <ansi_c.h>
#include <utility.h>
#include <analysis.h>

#include "c:\HOME\dino\sipmScan\include\sipmScan_ui.h"

#ifdef USE_DAQ
#  define USE_CAMAC
#  include "camac.h"
#  define NDAC 1
#    define ASD8 0 // channels
#    define AMPDISSH 1
#    define SIPM 2
//#  define CAEN_V673A   0x10110000 // FMF
#  define CAEN_V673A   0x22220000 // IJS
#  define CAEN_V462    0x100300
#endif

#ifdef USE_MIKRO
#  define MIKRO_COM 5
#  define MIKRO_X 1
#  define USE_MIKRO_Y
#  define MIKRO_Y 2
#  define USE_MIKRO_Z
#  define MIKRO_Z 3
#  define STEP_TOLERANCE 1  
#endif

#define MAXCH 512
#define MAX_THREADS 10

#define IWAIT 200

#define POWERSUPPLY 66 // Power supply voltage for SiPM bias
#define NCH 64

static int p1h, pID, rID, tfID;
static int ph_tdc, ph_adc;
static int dtdc[NCH][2][MAXCH];
static int something[NCH][2][MAXCH];

static int daq_on;
static int poolHandle = 0;
static int ntics,dummy;

/************************************************************/
void wait_loop(unsigned long iloop)

{
  int i;
 
  for (i=0;i<iloop;i++);
  return;
}

int CVICALLBACK cb_timer (int panel, int control, int event, void *callbackData,
                           int eventData1, int eventData2)
{
  QueueUserEvent (9000, p1h, P1_TIMER);
  return (0);
}

int update_plots (void)
{
  int irange, ch;
 
  GetCtrlVal (p1h, P1_PLCH, &ch);
 
  if (ph_tdc>0) DeleteGraphPlot (p1h, P1_TDC, ph_tdc, VAL_DELAYED_DRAW);
  GetCtrlVal (p1h, P1_TDCHL, &irange);
  ph_tdc = PlotY (p1h, P1_TDC, &dtdc[ch][irange], MAXCH, VAL_INTEGER,
                  VAL_VERTICAL_BAR, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);

  if (ph_adc>0) DeleteGraphPlot (p1h, P1_ADC, ph_adc, VAL_DELAYED_DRAW);
  GetCtrlVal (p1h, P1_ADCHL, &irange);
  ph_adc = PlotY (p1h, P1_ADC, &something[ch][irange], MAXCH, VAL_INTEGER,
                  VAL_VERTICAL_BAR, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_BLUE);
  return (0);
}


int module_header(int recid,unsigned long *data,int len){
   data[0] = recid;
   data[1] = (len >0)? len : 0 ;
   return data[1]+2;
}

int CVICALLBACK daq_run(void *functionData)
{
        // ***
        // variable declarations
        int i,j;
        int dtype,ch,rg,adc,cres,bsr;
       
        //unsigned short aa[NCH][4];
        unsigned long tdc[NCH];
        unsigned long step_minutes, end_time_s, cur_time_s;
        int start_hours, start_minutes, start_seconds;

        int status,fmax,fcount,fev;
        int popupret;

  char dfile[MAX_PATHNAME_LEN],dfile0[MAX_PATHNAME_LEN];
  int supr0,tdcmin,fseed;
  float frac;
  double fracg;
  unsigned short dum16;
  int count;
  int print = 0;
  int timer_out = 0;
  //time_t t,told, tstart;
  int ntrig;  
  int chip, len;
  unsigned long *pdata;

  FILE *fp;
  #define RUNREC_ID 1
  #define ENDREC_ID 2
  #define POSREC_ID 3
  #define EVTREC_ID 4

  typedef struct {
    unsigned long id,len;
    unsigned long fver,time;
    unsigned long nev,nch,ped,xy;
    long nx,x0,dx,ny,y0,dy;
    } RUNREC;
        RUNREC runrec;
       
  typedef struct {
    unsigned long id,len;
    unsigned long time;
    } ENDREC;
        ENDREC endrec;
       
  typedef struct {
    unsigned long id,len;
    unsigned long time;
    long ix,x,xset,iy,y,yset;
    } POSREC;
        POSREC posrec;
        long mikroX;
        long mikroY;

  typedef struct {
    unsigned long id,len;
    unsigned long nev;
    //unsigned short data[NCH];
    } EVTREC;
        EVTREC evtrec;
#define BSIZE 20000
       
        int maxn = BSIZE-4; // 2 words x 2 headers
        int tdcdata, edge_type, overflow, tdc_num, channel, ev_dat, last_dat, nval_dat;
        // end of declarations
        // ***
       
        runrec.id = RUNREC_ID;
        runrec.len = sizeof(runrec);
        //runrec.fver = 0x10000;
        runrec.nch = NCH;
        GetCtrlVal(p1h, P1_ADCHLSAVE, &runrec.xy);//runrec.xy = 1;
        GetCtrlVal(p1h, P1_DEBUG, &print);
        endrec.id = ENDREC_ID;
        endrec.len = sizeof(endrec);
        posrec.id = POSREC_ID;
        posrec.len = sizeof(posrec);
        evtrec.id = EVTREC_ID;
        evtrec.len = sizeof(evtrec);
       
       
        cres = 0;
       
        GetCtrlVal (p1h, P1_NEVE, &runrec.nev);
        GetCtrlVal (p1h, P1_PEDESTAL, &runrec.ped);
       
        GetCtrlVal (p1h, P1_NX, &runrec.nx);
        GetCtrlVal (p1h, P1_XSTEP, &runrec.dx);
        GetCtrlVal (p1h, P1_XMIN, &runrec.x0);
        GetCtrlVal (p1h, P1_NY, &runrec.ny);
        GetCtrlVal (p1h, P1_YSTEP, &runrec.dy);
        GetCtrlVal (p1h, P1_YMIN, &runrec.y0);
       
        GetCtrlVal (p1h, P1_NMIN, &step_minutes);
        GetSystemTime(&start_hours, &start_minutes, &start_seconds);
        //cur_time_s = start_hours*3600 + start_minutes*60 + start_seconds;
        time(&cur_time_s);
        end_time_s = cur_time_s + step_minutes*60;
        printf("START:%2d-%2d-%2d (cur_time = %u s, end_time = %u s)\n", start_hours, start_minutes, start_seconds, cur_time_s, end_time_s);

        //GetCtrlVal (p1h, P1_DSAVE, &dsave);
  //if (dsave) {
          GetCtrlVal (p1h, P1_DFILE, dfile0);
         
          fev=0;
          fcount=1;
          GetCtrlVal (p1h, P1_NEWF, &fmax);
          fmax*=1000000;//fmax in Mega Bytes
  //}
        GetCtrlVal (p1h, P1_SUPR, &supr0);
        if (supr0) {
          GetCtrlVal (p1h, P1_TDCMIN, &tdcmin);
          GetCtrlVal (p1h, P1_FRAC, &frac);
        }

#ifdef USE_DAQ
        V673A_map(0,CAEN_V673A,0);
        V673A_init(0);
 
        V462_map(0,CAEN_V462,0);
        V462_set0(0,1);
#endif

  //if (dsave) {
    sprintf(dfile,"%s_file%02d.dat",dfile0,fcount);
 
    fp = fopen (dfile, "wb");
    time (&runrec.time);
    status = fwrite (&runrec, 1, runrec.len, fp);
        //}
        if (supr0) {
          fseed = runrec.time & 0x7fffffff;
          Uniform (1, fseed, &fracg);
        }

  for (posrec.ix=0; posrec.ix<runrec.nx; posrec.ix++) {
                posrec.xset = runrec.x0 + posrec.ix*runrec.dx;
#ifdef USE_MIKRO
      do {
        if (print) printf("MIKRO_MoveTo (1, x);%d\n",posrec.xset);
        MIKRO_MoveTo (MIKRO_X, posrec.xset);
        MIKRO_GetPosition(MIKRO_X, &mikroX);
        if (print) printf("%d\n", abs(posrec.xset - mikroX));
        } while (abs(posrec.xset - mikroX) > STEP_TOLERANCE);
#endif
    posrec.xset = mikroX; // true value
          SetCtrlVal (p1h, P1_X, posrec.xset);
          SetCtrlVal (p1h, P1_IX, posrec.ix);
          for (posrec.iy=0; posrec.iy<runrec.ny; posrec.iy++) {
      posrec.yset = runrec.y0 + posrec.iy*runrec.dy;
#ifdef USE_MIKRO_Y
      if (print) printf("MIKRO_MoveTo (2, y);%d\n",posrec.yset);
      do {      
        MIKRO_MoveTo (MIKRO_Y, posrec.yset);
        MIKRO_GetPosition(MIKRO_Y, &mikroY);
        if (print) printf("%d\n", abs(posrec.yset - mikroY));
        } while (abs(posrec.yset - mikroY) > STEP_TOLERANCE);
          if (print) printf("->MIKRO_MoveTo (2, y);%d\n",posrec.yset);
#endif
      posrec.yset = mikroY;
      SetCtrlVal (p1h, P1_Y, posrec.yset);
      SetCtrlVal (p1h, P1_IY, posrec.iy);
      //if (dsave) {
      if (fmax && (ftell(fp) > fmax)) {
        fcount+=1;
        sprintf(dfile,"%s_file%02d.dat",dfile0,fcount);
        fclose(fp);
        fp = fopen (dfile, "wb");
      }
         
      time (&posrec.time);
            status = fwrite (&posrec, 1, posrec.len, fp);
            if (print) printf("POSREC status %d len %d\n", status, posrec.len);
                  //}
                 
// clear the plots
      for (j=0;j<NCH;j++) {
       for (i=0;i<MAXCH;i++){
          dtdc[j][0][i]=0;
          dtdc[j][1][i]=0;
        }
      }

          evtrec.nev=1;  
      //time(&t);
      //tstart=t;
      if (print) printf("RUN START.\n");
       
      do {
        unsigned long word[BSIZE];
            count=0;
            ntics=0;
            if (print) printf("Event counter: %d\n", evtrec.nev);
           
                //if (t!=told ) printf("%d in %2.2f min daq::event() %s\n",i, (double)(t-tstart)/60., ctime(&t));
             
#ifdef USE_DAQ
#ifdef CAEN_V673A

   
        V462_start0(0);
                //tmlnk (tout);
        do {  
          ntrig  = V673A_ntrig(0);
        } while (ntrig==0 &&(ntics<2));
        //tmulk();
        //if (timer_out) {
        //   fprintf(stderr,"-----------------> V673a timeout !!!\n");
        //   V673A_clallb(0);
        //   continue;
        //}
     
        if (ntics>=2) {
           fprintf(stderr,"-----------------> V673a timeout !!!\n");
           printf("Timer tics %d\n", ntics);
           ntics = 0;
           evtrec.nev--;
           V673A_clallb(0);
           continue;
          }

        if (ntrig>0){
          // chip readout
          for (chip=0;chip<2;chip++){
            if (chip) len = V673A_read1 (0, &word[count+2],maxn-count-2);
            else          len = V673A_read0 (0, &word[count+2],maxn-count-2);
         
            if (len>16*32*4){
              if (print) printf("Length > 2048 per chip!\n");
              chip=2;
              V673A_clallb(0);
              evtrec.nev--;
              continue;
            }
            pdata=&word[count+2];
            for(i=0;i< len;i++){
              tdcdata   =  pdata[i] & 0xFFFF ;
              edge_type = (pdata[i]>>16)&0x1  ;
              overflow  = (pdata[i]>>17)&0x1  ;
              tdc_num   = (pdata[i]>>25)&0x1  ;
              channel   = ((pdata[i]>>18)&0x1F) |tdc_num<<5 ;
              ev_dat    = (pdata[i]>>23)&0x1  ;    
              last_dat  = (pdata[i]>>30)&0x1  ;
              nval_dat  = (pdata[i]>>31)&0x1  ;
              if (ev_dat) {
                if(print) printf("Event %d\n",tdcdata);
              } else {
                dtdc[channel][edge_type][tdcdata]++;
             
              if (print) printf
                       ("ch=%d edge=%d ev=%d data=%d last=%d nval=%d\n",channel, edge_type,ev_dat,tdcdata,last_dat,nval_dat);
              }
            }
            if (count+2 < maxn) count+=module_header(0x140+chip,&word[count],len);
                  }
                  if (print) printf("Received triggers: %d \n", ntrig);
        } else {
          if (ntrig==0) {
                fprintf(stderr,"-----------------> no trigger");
                break;
          } else {
                if (print) fprintf(stderr,"-----------------> wrong number of triggers in chips V673a  !!!\n");
          }
          V673A_clallb(0);
          evtrec.nev--;
          continue;
        }
       
        V673A_clallb(0);
#endif
#endif
       

        GetCtrlVal(p1h, P1_ADCHLSAVE, &runrec.xy);
        evtrec.len = count*sizeof(unsigned long) + sizeof(evtrec);      
        status = fwrite (&evtrec, 1, sizeof(evtrec), fp);
        status = fwrite (&word, 1, count*sizeof(unsigned long), fp);
                   
             
            if (!(evtrec.nev%1000)) SetCtrlVal (p1h, P1_CEVE, evtrec.nev);
             
            if (!((evtrec.nev+1)%1000)) {                                                            
            if (fmax && (ftell(fp) > fmax)) {
              time (&endrec.time);
                      status = fwrite (&endrec, 1, endrec.len, fp);
              fcount+=1;
                  sprintf(dfile,"%s_file%02d.dat",dfile0,fcount);
                  fclose(fp);
                  fp = fopen (dfile, "wb");
            }
        }
         
        if(step_minutes > 0) {
                                  GetSystemTime(&start_hours, &start_minutes, &start_seconds);
                                  //cur_time_s = start_hours*3600 + start_minutes*60 + start_seconds;
                                  time(&cur_time_s);
                                  if(cur_time_s >= end_time_s) {
                                          end_time_s = cur_time_s + step_minutes*60;
                                          printf("STEP (nev):%2d-%2d-%2d @ %d\n", start_hours, start_minutes, start_seconds, posrec.xset);
                        break;
                }
        }
        //told=t;
       
        GetCtrlVal(p1h, P1_DAQ, &daq_on);
         
            } while (evtrec.nev++<runrec.nev && daq_on);
            if (!daq_on) break;
          } // x loop
          if (!daq_on) break;
        } // y loop
       
  //if (dsave) {
    time (&endrec.time);
    status = fwrite (&endrec, 1, endrec.len, fp);
    if (print) printf("ENDREC status %d len %d\n", status, endrec.len);
    fclose(fp);
        //}
        GetSystemTime(&start_hours, &start_minutes, &start_seconds);
        printf("STOP:%2d-%2d-%2d (start_time = %u s, end_time = %u s)\n", start_hours, start_minutes, start_seconds, runrec.time, endrec.time);
        printf("Elapsed time: %u s.\n", endrec.time-runrec.time);
       
    daq_on=0;  
        SetCtrlVal (p1h, P1_DAQ, daq_on);
        SetCtrlVal (p1h, P1_CEVE, evtrec.nev);
        if (print) printf("RUN END. \n\n");

        return 0;
}


int SetDac(int ch, double val){
       
        const unsigned int maxdac=0xFFF;
        const double RANGE = +9.9976; //V
        unsigned int dac;
       
        if ((val > RANGE) || (val < 0)) {
                printf("DAC value OUT OF RANGE!!!\n");
                return(-1);
        }
       
        dac = (val/RANGE)*maxdac;
        CSSA_W(NDAC,ch,16,&dac);
        printf("DAC ch %d set to %f V dac=%d\n", ch, val, dac);
        return 0;
}

int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpszCmdLine, int nCmdShow)
{
  int i,j,status,refon;
  long int xpos, ypos, zpos;
  char dfile[300];
  FILE *fp;
 
  typedef struct {
  unsigned long id,len;
  unsigned long fver,time;
  unsigned long nev,nch,ped,xy;
  long nx,x0,dx,ny,y0,dy;
  } RUNREC;
  RUNREC runrec;

  if (InitCVIRTE (hInstance, 0, 0) == 0)
        return -1;      /* out of memory */

  SetSleepPolicy(VAL_SLEEP_MORE);
  CmtNewThreadPool (MAX_THREADS, &poolHandle);

  SetStdioWindowOptions (1000, 0, 0);
  SetStdioWindowSize (200, 560);
  SetStdioWindowPosition (825, 250);

#ifdef USE_DAQ
  VME_START(NULL);
#endif

#ifdef USE_MIKRO
  MIKRO_Open (MIKRO_COM);
  MIKRO_Init (MIKRO_X,0);
#ifdef USE_MIKRO_Y
  MIKRO_Init (MIKRO_Y,0);
#endif
#ifdef USE_MIKRO_Z
  MIKRO_Init (MIKRO_Z,0);
#endif
#endif

  if ((p1h = LoadPanel (0, "include/sipmScan_ui.uir", P1)) < 0) return -1;
  DisplayPanel (p1h);
  SetCtrlAttribute (p1h, P1_PLCH, ATTR_MAX_VALUE, NCH-1);
 
  GetCtrlVal(p1h, P1_ADCHLSAVE, &runrec.xy);
  SetCtrlVal(p1h, P1_ADCHL, runrec.xy-2);

  QueueUserEvent (1000, p1h, P1_RESET);
  QueueUserEvent (1000, p1h, P1_ASD8THR);
  QueueUserEvent (1000, p1h, P1_AMPDISSHTHR);
  QueueUserEvent (1000, p1h, P1_BIAS);
 
  printf("BIAS offset set to: %d\n", POWERSUPPLY);
 
  do {
    GetUserEvent (1, &pID, &rID);
        switch (rID) {
      case P1_TIMER:
        ntics+=1;
        GetCtrlVal (p1h, P1_REFON, &refon);
                    if (refon) update_plots();
            break;
      case P1_REFRESH:
                update_plots();
            break;
          case P1_DAQ:
                GetCtrlVal (p1h, P1_DAQ, &daq_on);
                if (daq_on) {
                  CmtScheduleThreadPoolFunction (poolHandle, daq_run, (void *)&dummy, &tfID);
                } else {
          CmtWaitForThreadPoolFunctionCompletion (poolHandle, tfID,
                                                                        OPT_TP_PROCESS_EVENTS_WHILE_WAITING);
              CmtReleaseThreadPoolFunctionID (poolHandle, tfID);
            }
            break;
           
          case P1_ZSET:
            if (!daq_on) {
              GetCtrlVal (p1h, P1_ZSET, &zpos);
#ifdef USE_MIKRO_Z
          MIKRO_MoveTo (MIKRO_Z, zpos);
#endif
        }
            break;
          case P1_REREAD:
            if (!daq_on) {
          status = FileSelectPopup ("", "*.dat", ".dat",
                                    "Izberi datoteko s podatki",
                                    VAL_LOAD_BUTTON, 0, 0, 1, 0, dfile);
          if (status==1) {
            fp = fopen (dfile, "rb");
                        status = fread (&runrec, 1, sizeof(runrec), fp);
                        fclose(fp);
                        if (runrec.id==1) {
                          SetCtrlVal (p1h, P1_NX, runrec.nx);
                          SetCtrlVal (p1h, P1_XSTEP, runrec.dx);
                          SetCtrlVal (p1h, P1_XMIN, runrec.x0);
                          SetCtrlVal (p1h, P1_NY, runrec.ny);
                          SetCtrlVal (p1h, P1_YSTEP, runrec.dy);
                          SetCtrlVal (p1h, P1_YMIN, runrec.y0);
                          SetCtrlVal (p1h, P1_NEVE, runrec.nev);
            }
              }
        }
            break;
          case P1_MGET:
          #ifdef USE_MIKRO
                MIKRO_GetPosition(MIKRO_X,&xpos);
                Delay(0.01);
                SetCtrlVal (p1h, P1_X, xpos);  
          #ifdef USE_MIKRO_Y   
                MIKRO_GetPosition(MIKRO_Y,&ypos);
                Delay(0.01);
                SetCtrlVal (p1h, P1_Y, ypos);
          #endif
          #ifdef USE_MIKRO_Z   
                MIKRO_GetPosition(MIKRO_Z,&zpos);
                Delay(0.01);
                SetCtrlVal (p1h, P1_Z, zpos);
          #endif
          #endif
                break;
          case P1_HO:
            if (!daq_on) {
                  SetWaitCursor (1);
#ifdef USE_MIKRO
                  MIKRO_ReferenceMove (MIKRO_X);
                #ifdef USE_MIKRO_Y     
                  MIKRO_ReferenceMove (MIKRO_Y);
                #endif
                #ifdef USE_MIKRO_Z
                  MIKRO_ReferenceMove (MIKRO_Z);
                #endif
#endif
                  SetWaitCursor (0);
            }
            break;
          case P1_RESET:
        for (j=0;j<NCH;j++) {
          for (i=0;i<MAXCH;i++){
            dtdc[j][0][i]=0;
            dtdc[j][1][i]=0;
           
          }
        }
                update_plots();
            break;
          case P1_TDCLOG:
            GetCtrlVal (p1h, P1_TDCLOG, &status);
        SetCtrlAttribute (p1h, P1_TDC, ATTR_YMAP_MODE, status);
                update_plots();
            break;
          case P1_ADCLOG:
            GetCtrlVal (p1h, P1_ADCLOG, &status);
        SetCtrlAttribute (p1h, P1_ADC, ATTR_YMAP_MODE, status);
                update_plots();
            break;
          case P1_ASD8THR:
            {
              double value;
              GetCtrlVal (p1h, P1_SASD8THR, &value);
              SetDac(ASD8, value);
             
            }
            break;
          case P1_AMPDISSHTHR:
            {
              double value;
              GetCtrlVal (p1h, P1_SAMPDISSHTHR, &value);
              SetDac(AMPDISSH, value);

            }  
            break;
          case P1_BIAS:
                {
                  double value;
                  GetCtrlVal (p1h, P1_SBIAS, &value);
                  value -= POWERSUPPLY;
                  SetDac(SIPM, value);
                }
                break;
             
        }
       
  } while ((rID != P1_EXIT)||daq_on);
           
  CmtDiscardThreadPool (poolHandle);
  DiscardPanel (p1h);

#ifdef USE_MIKRO
  MIKRO_Close ();
#endif

#ifdef USE_DAQ
  VME_STOP();
#endif  
  return 0;
               
}