/* Program l2d.c za testiranje povrsinske obcutljivosti
 
 
 
Avtor: Samo Korpar
 
Verzija:
 
  1.00 3.5.2007
 
    -
 
*/
 
 
 
#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 "camac.h"
 
//#  ifdef SISVME
 
//#    include "sisvme_dll.h"
 
//#  endif
 
#  ifdef WIENVME
 
#    include "wienvme_dll.h"
 
#  endif
 
#  define VME_START(NODE) WIENVME_VME_START((NODE))
 
#  define VME_STOP() WIENVME_VME_STOP()
 
#  include "CAENV965.h"
 
#endif
 
 
 
#ifdef USE_MIKRO
 
#  include "MIKRO.h"
 
#endif
 
 
 
#include <userint.h>
 
#include <ansi_c.h>
 
#include <utility.h>
 
#include <analysis.h>
 
 
 
#include "l2d_ui.h"
 
 
 
#ifdef USE_DAQ
 
//#  define VTDC_ADDR 0x330000
 
#  define VADC_ADDR 0x350000
 
//#  define VTDC 0
 
#  define VADC 1
 
//#  define IO1_ADDR 0x100200
 
//#  define NTDCP 20
 
#  define NTDCJ 20
 
#  define NGL 23
 
#endif
 
 
 
#ifdef USE_MIKRO
 
#  define MIKRO_COM 3
 
#endif
 
 
 
#define MAXCH 0x1000
 
#define MAX_THREADS 10
 
 
 
#define IWAIT 2000
 
 
 
#  define NCH 2
 
static int p1h, pID, rID, tfID;
 
static int ph_tdc, ph_adc;
 
static int dtdc[NCH][2][MAXCH];
 
static int dadc[NCH][2][MAXCH];
 
static int daq_on;
 
static int poolHandle = 0;
 
static int ntics,dummy;
 
//              0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 
static int tdcmap[16]= { 0, 1, 2, 3, 4, 5, 6, 7,99,99,99,99,99,99,99,99};
 
static int adcmap[16]= {99,99,99,99,99,99,99,99, 0, 1, 2, 3, 4, 5, 6, 7};
 
static int ctdcmap[16]= { 0, 1, 2, 3, 4, 5, 6, 7,99,99,99,99,99,99,99,99};
 
 
 
/************************************************************/
 
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, &dadc[ch][irange], MAXCH, VAL_INTEGER,
 
                  VAL_VERTICAL_BAR, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_BLUE);
 
  return (0);
 
}
 
 
 
int CVICALLBACK daq_run(void *functionData) {
 
  int i,j;
 
  int ndat,dtype,ch,rg,adc,cres;
 
  unsigned long a,b,ec1,ec2;
 
  unsigned long data[100];
 
  unsigned short aa[NCH][4];
 
 
 
  int dsave,status,fmax,fcount,fev;
 
  char dfile[MAX_PATHNAME_LEN],dfile0[MAX_PATHNAME_LEN];
 
  int supr0,tdcmin,fseed,esave;
 
  float frac;
 
  double fracg;
 
 
 
  FILE *fp=NULL;
 
#define RUNREC_ID 1
 
#define ENDREC_ID 2
 
#define POSREC_ID 3
 
#define EVTREC_ID 4
 
 
 
  typedef struct {
 
    unsigned long id,len;
 
    unsigned long nev,nch,ped,xy;
 
    long nx,x0,dx,ny,y0,dy;
 
  } RUNREC;
 
  RUNREC runrec;
 
 
 
  typedef struct {
 
    unsigned long id,len;
 
  } ENDREC;
 
  ENDREC endrec;
 
 
 
  typedef struct {
 
    unsigned long id,len;
 
    long ix,x,xset,iy,y,yset;
 
  } POSREC;
 
  POSREC posrec;
 
 
 
  typedef struct {
 
    unsigned long id,len;
 
    unsigned long nev;
 
    unsigned short data[NCH*2];
 
  } EVTREC;
 
  EVTREC evtrec;
 
 
 
  runrec.id = RUNREC_ID;
 
  runrec.len = sizeof(runrec);
 
  runrec.fver = 0x10000;
 
  runrec.nch = NCH;
 
  runrec.xy = 1;
 
  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_DSAVE, &dsave);
 
  if (dsave) {
 
    GetCtrlVal (p1h, P1_DFILE, dfile0);
 
 
 
    fev=0;
 
    fcount=1;
 
    GetCtrlVal (p1h, P1_NEWF, &fmax);
 
  }
 
  GetCtrlVal (p1h, P1_SUPR, &supr0);
 
  if (supr0) {
 
    GetCtrlVal (p1h, P1_TDCMIN, &tdcmin);
 
    GetCtrlVal (p1h, P1_FRAC, &frac);
 
  }
 
 
 
#ifdef USE_DAQ
 
//  V965_map (VTDC, VTDC_ADDR, 1);
 
//  V965_init (VTDC, pedestal);
 
 
 
  V965_map (VADC, VADC_ADDR, 1);
 
  V965_init (VADC, runrec.ped);
 
 
 
#  ifdef USE_CAMAC
 
  BZ(&cres);
 
  CCCZ(&cres);
 
  CCCC(&cres);
 
  CREM_I(&cres);
 
  CSSA_R(NGL,0,25,&cres);
 
  Delay(0.01);
 
#    ifdef NTDCJ
 
  CSSA_R(NTDCJ,0,9,&cres);
 
  printf("CSSA_R(NTDCJ,0,9,&cres)=0x%0x\n", cres
);  
  CSSA_R(NTDCJ,0,26,&cres);
 
  printf("CSSA_R(NTDCJ,0,26,&cres)=0x%0x\n", cres
);  
#    endif
 
#    ifdef NTDCP
 
  CSSA_R(NTDCP,0,9,&cres);
 
  CSSA_R(NTDCP,0,11,&cres);
 
  CSSA_R(NTDCP,0,26,&cres);
 
  printf("CSSA_R(NTDCP,0,26,&cres)=0x%0x\n", cres
);  
#    endif
 
#  endif
 
#endif
 
 
 
  if (dsave) {
 
    sprintf(dfile
,"%s_file%02d.dat",dfile0
,fcount
);  
    fp 
= fopen (dfile
, "wb"); 
    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
 
//      printf("MIKRO_MoveTo (1, x);%d\n",x);
 
    MIKRO_MoveTo (1, posrec.xset);
 
//    printf("->MIKRO_MoveTo (1, x);%d\n",x);
 
#endif
 
 
 
    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
 
//        printf("MIKRO_MoveTo (2, y);%d\n",y);
 
      MIKRO_MoveTo (2, posrec.yset);
 
//      printf("->MIKRO_MoveTo (2, y);%d\n",y);
 
#endif
 
 
 
      SetCtrlVal (p1h, P1_Y, posrec.yset);
 
      SetCtrlVal (p1h, P1_IY, posrec.iy);
 
 
 
      if (dsave) {
 
        status 
= fwrite (&posrec
, 1, posrec.
len, fp
); 
      }
 
 
 
// 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;
 
          dadc[j][0][i]=0;
 
          dadc[j][1][i]=0;
 
        }
 
      }
 
 
 
      evtrec.nev=1;
 
      do {
 
        for (j=0; j<NCH; j++)
 
          for (i=0; i<4; i++)
 
            aa[j][i]=0;
 
//          if((neve%1000)==0) printf("Events %ld\n",neve);
 
 
 
#ifdef USE_DAQ
 
        ndat = 0;
 
//          a = 0x0001;
 
//          VME_A24D16_W(IO1_ADDR + 0x000008, &a);   //poslje laserski sunek
 
 
 
        ntics=0;
 
#  ifdef USE_CAMAC
 
        CSSA_R(NGL,0,10,&cres);
 
//          do {
 
//            wait_loop(IWAIT);
 
//            Delay(0.1);
 
#    ifdef NTDCJ
 
//        CSSA_R(NTDCJ,0,8,&cres);
 
#    endif
 
#    ifdef NTDCP
 
//        CSSA_R(NTDCP,0,8,&cres);
 
#    endif
 
//        if (!(cres&0x8000)) printf("CSSA_R(NTDCJ,0,8,&cres)=0x%0x\n", cres) ;
 
//          } while ((!(cres&0x8000))&&(ntics<2)&&daq_on);
 
#  endif
 
//          wait_loop(2000);
 
        while((!(V965_status(VADC)&0x1))&&(ntics<2)&&daq_on);
 
        if (!daq_on) break;
 
        if (ntics>=2) {
 
          ndat=V965_read (VADC, &data[0]);
 
          continue;
 
        } else {
 
#  ifdef USE_CAMAC
 
#    ifdef NTDCJ
 
          wait_loop(20000);
 
//          ntics=0;
 
//          do {
 
//            wait_loop(IWAIT);
 
            CSSA_R(NTDCJ,0,8,&cres);
 
//            if (!(cres&0x8000)) printf("CSSA_R(NTDCJ,0,8,&cres)=0x%0x\n", cres) ;
 
//          } while ((!(cres&0x8000))&&(ntics<2)&&daq_on);
 
//          if (!daq_on) break;
 
//          if (ntics>=2) {
 
          if (!(cres&0x8000)) {
 
            CSSA_R(NGL,0,25,&cres);
 
            ndat=V965_read (VADC, &data[0]);
 
            CSSA_R(NTDCJ,0,9,&cres);
 
            CSSA_R(NTDCJ,0,26,&cres);
 
            continue;
 
          }
 
#    endif
 
#  endif
 
        }
 
        /*
 
                ndat=V965_read (VTDC, &data[0]);
 
                for (i=0; i<ndat; i++) {
 
                  dtype=(data[i]>>25)&0x3;
 
                if (dtype==0) {
 
                  ch=tdcmap[(data[i]>>17)&0xf];
 
                  if (ch<NCH) {
 
                    rg=(data[i]>>16)&0x1;
 
                    adc=data[i]&0xfff;
 
                    aa[ch][rg]=adc;
 
                    dtdc[ch][rg][adc]+=1;
 
                      }
 
                  }
 
                  }
 
        */
 
        for (i=0; i<NCH; i++) {
 
            wait_loop(IWAIT);
 
#  ifdef USE_CAMAC
 
#    ifdef NTDCJ
 
          CSSA_R(NTDCJ,ctdcmap[i],0,&adc);
 
#    endif
 
#    ifdef NTDCP
 
          CSSA_R(NTDCP,ctdcmap[i],0,&adc);
 
#    endif
 
#  endif
 
//        printf("TDC=0x%04X\n",adc);
 
//          adc=adc&0xfff;
 
          if (adc&0x1000) adc=0xfff; else adc&=0xfff;
 
          aa[i][0]=adc;
 
          dtdc[i][0][adc]+=1;
 
        }
 
 
 
        ndat=V965_read (VADC, &data[0]);
 
        for (i=0; i<ndat; i++) {
 
          dtype=(data[i]>>25)&0x3;
 
          if (dtype==0) {
 
            ch=adcmap[(data[i]>>17)&0xf];
 
            if (ch<NCH) {
 
              rg=(data[i]>>16)&0x1;
 
              adc=data[i]&0xfff;
 
              aa[ch][rg+2]=adc;
 
              dadc[ch][rg][adc]+=1;
 
            }
 
          }
 
        }
 
 
 
#  ifdef USE_CAMAC
 
        wait_loop(IWAIT);
 
#    ifdef NTDCJ
 
        CSSA_R(NTDCJ,0,9,&cres);
 
#    endif
 
#    ifdef NTDCP
 
        CSSA_R(NTDCP,0,9,&cres);
 
        CSSA_R(NTDCP,0,26,&cres);
 
        // printf("2 CSSA_R(NTDCP,0,26,&cres)=0x%0x\n", cres);
 
#    endif
 
//         Delay(0.001);
 
//          wait_loop(IWAIT);
 
//          CSSA_R(NGL,0,10,&cres);
 
#  endif
 
 
 
#else /* generate test data */
 
        if (!daq_on) break;
 
        for (i=0; i<NCH; i++) {
 
          adc=100+evtrec.nev%200;
 
          dtdc[i][1][adc]+=1;
 
          dadc[i][1][adc]+=1;
 
          aa[i][0]=adc;
 
          aa[i][2]=adc;
 
          adc=200+evtrec.nev%400;
 
          dtdc[i][0][adc]+=1;
 
          dadc[i][0][adc]+=1;
 
          aa[i][1]=adc;
 
          aa[i][3]=adc;
 
        }
 
#endif
 
        esave=dsave;
 
        if (supr0 && esave) {
 
          Uniform (1, -1, &fracg);
 
          if (fracg > frac) {
 
            esave=0;
 
            for (i=0; i<NCH; i++) {
 
              if ((aa[i][0] >= tdcmin) && (aa[i][0] < 4000)) esave=1;
 
            }
 
          }
 
        }
 
        if (esave) {
 
//          time (&evtrec.time);
 
          for (i=0; i<NCH; i++) {
 
            evtrec.data[i] = aa[i][0];
 
            evtrec.data[i+NCH] = aa[i][2];
 
          }
 
          status 
= fwrite (&evtrec
, 1, evtrec.
len, fp
); 
        }
 
 
 
        if (!(evtrec.nev%1000)) SetCtrlVal (p1h, P1_CEVE, evtrec.nev);
 
      } while (evtrec.nev++<runrec.nev);
 
      if (!daq_on) break;
 
    }
 
    if (!daq_on) break;
 
  }
 
 
 
  if (dsave) {
 
    status 
= fwrite (&endrec
, 1, endrec.
len, fp
); 
  }
 
 
 
  daq_on=0;
 
  SetCtrlVal (p1h, P1_DAQ, daq_on);
 
  SetCtrlVal (p1h, P1_CEVE, evtrec.nev);
 
 
 
  return 0;
 
}
 
 
 
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
                       LPSTR lpszCmdLine, int nCmdShow) {
 
  int i,j,status,refon;
 
  long int zpos;
 
  char dfile[300];
 
  FILE *fp;
 
 
 
  typedef struct {
 
    unsigned long id,len;
 
    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 (150, 600);
 
  SetStdioWindowPosition (825, 20);
 
 
 
#ifdef USE_DAQ
 
  VME_START(NULL);
 
#endif
 
 
 
#ifdef USE_MIKRO
 
  MIKRO_Open (MIKRO_COM);
 
  MIKRO_Init (1,0);
 
  MIKRO_Init (2,0);
 
  MIKRO_Init (3,0);
 
#endif
 
 
 
  if ((p1h = LoadPanel (0, "l2d_ui.uir", P1)) < 0) return -1;
 
  DisplayPanel (p1h);
 
  SetCtrlAttribute (p1h, P1_PLCH, ATTR_MAX_VALUE, NCH-1);
 
 
 
  QueueUserEvent (1000, p1h, P1_RESET);
 
 
 
  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
 
          MIKRO_MoveTo (3, 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
); 
            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_HO:
 
        if (!daq_on) {
 
          SetWaitCursor (1);
 
#ifdef USE_MIKRO
 
          MIKRO_ReferenceMove (1);
 
          MIKRO_ReferenceMove (2);
 
          MIKRO_ReferenceMove (3);
 
#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;
 
            dadc[j][0][i]=0;
 
            dadc[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;
 
    }
 
 
 
  } while ((rID != P1_EXIT)||daq_on);
 
 
 
  CmtDiscardThreadPool (poolHandle);
 
  DiscardPanel (p1h);
 
 
 
#ifdef USE_MIKRO
 
  MIKRO_Close ();
 
#endif
 
 
 
#ifdef USE_DAQ
 
  VME_STOP();
 
#endif
 
  return 0;
 
 
 
}