//#define XXDLL
 
//#include "vme.h"
 
 
 
 
 
 
 
typedef unsigned short ADDRESS_MODIFIER;
 
#define Std_NoPriv_Data     (ADDRESS_MODIFIER)0x39
 
 
 
#include "wusbvme_dll.h"
 
#include "toolbox.h"
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <string.h>
 
 
 
 
 
#include <errno.h>
 
#include <ctype.h>
 
#include <time.h>
 
 
 
 
 
#include <signal.h>
 
 
 
 
 
#include "CAENV965_DEF.h"
 
 
 
#include "petdemo_uir.h"  
 
#include "daq.h"
 
 
 
extern int p1;  
 
extern int ctrl_c;
 
 
 
 
 
#define VERSION 1.0
 
#define TIMEOUT 3
 
 
 
int *fThreshold = NULL;
 
 
 
/* VME modules */
 
 
 
#define CAEN_V792      0x340000  // IJS V792
 
#define CAEN_V792_1    0x530000  // FMF1 V792
 
#define CAEN_V792_2    0x630000  // FMF2 V792
 
#define CAEN_V965      0x350000  // IJS  V965
 
int addr[3]= {CAEN_V792,CAEN_V792_1,CAEN_V965  };
 
const int nadc=2;
 
#define BUFF_L 2048
 
static  int stackwrite[10000];
 
static  int stackdata[10000],stackdump[27000];
 
 
 
 
 
/************************************************/
 
int weight_while(int num) {
 
        int i, tmp;
 
 
 
        for ( i =0; i <num; i++ ) tmp = 0;
 
        return 0;
 
}
 
#define WWHILE weight_while(0)
 
 
 
#define TRUE 1
 
#define FALSE 0
 
 
 
int timer_out;
 
 
 
void timerast (int signumber) {
 
        timer_out = TRUE;
 
}
 
 
 
void tmlnk (int tout) {
 
 
 
}
 
 
 
void tmulk () {
 
 
 
}
 
 
 
int fexist( char *path) {
 
 
 
 
 
        if(!path || !*path) return 0;
 
        ssize_t fileSize;
 
        int res = FileExists (path, &fileSize);
 
 
 
 
 
        if (res>0) {
 
                return 1;
 
        } else {
 
                return 0;
 
        }
 
}
 
 
 
 
 
 
 
 
 
int init() {
 
 
 
        xxusb_register_write(WUSB_udev,1,0x0); // Stop DAQ mode
 
        while (xxusb_usbfifo_read(WUSB_udev,(int *) stackdump,BUFF_L,100)>0);
 
 
 
 
 
        int rate=1000;
 
        int freq=80000000/rate-40; // 80 MHz
 
        if (freq<72) freq=72;
 
        // Set DGG channel A as a pulser, output on O1,
 
        //     with delay =500 x 12.5ns,
 
        //     and width =  500 x 12.5ns,
 
        //     not latching or inverting
 
        //  VME_DGG(udev,0,6,0,24000,6000,0,0);
 
        VME_DGG(WUSB_udev,0,6,0,freq,40,0,0);
 
        // Set DGG channel B to trigger on NIM1, output on O2,
 
        //     with delay =200 x 12.5ns,
 
        //     and width =  200 x 12.5ns,
 
        //     not latching or inverting
 
        VME_DGG(WUSB_udev,1,1,1,0,10,0,1);
 
        printf("CAEN V965 Pedestal set to %d\n", fPedestal
);  
 
 
// INIT stackdata
 
        int fPedestal=255;
 
        WIENER_VMUSB_StackInit();
 
 
 
        for (int i=0; i<nadc; i++) {
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_CRN , 0x0);
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_GEO , i);
 
                WIENER_VMUSB_StackReadA24D16(addr[i] + CAENV965_GEO);
 
                for (int j=0; j<32; j++) {
 
                        WIENER_VMUSB_StackWriteA24D16(addr[i] + CAENV965_THM + 0x02*j, fThreshold[j+i*32]); // threshold/kill for 32 channels
 
                }
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_BS1, 0x80 ); // soft reset
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_BC1, 0x80 ); // soft reset
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_PED, fPedestal ); // pedestal
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_BS2,0x5000);
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_BS2,0x4);  // clear module
 
                WIENER_VMUSB_StackWriteA24D16( addr[i] + CAENV965_BC2,0x4);
 
        }
 
        WIENER_VMUSB_StackMarker(0xFAFC);
 
        //WIENER_VMUSB_StackPrint();
 
 
 
 
 
        VME_LED_settings(WUSB_udev, 0,0,0,0); // Set Yellow LED to light with with USB out buffer not empty
 
        VME_LED_settings(WUSB_udev, 1,1,0,0); // Set Red LED to light with NIM1
 
        VME_LED_settings(WUSB_udev,2,0,0,0); // Set Green LED to light when stack is not empty
 
 
 
        unsigned int  vmereg;
 
        VME_register_read(WUSB_udev,0x00,&vmereg);
 
        printf("VMUSB Firmware ID -> 0x%08X\n",vmereg
);  
 
 
        VME_register_read(WUSB_udev,0x04,&vmereg);
 
        printf("VMUSB Global Mode -> 0x%08X\n",vmereg
);  
 
 
        vmereg=(vmereg&0xF000)|0x0004;
 
        VME_register_write(WUSB_udev,0x04,vmereg);
 
        VME_register_write(WUSB_udev,0x08,0x00000080);
 
        VME_register_write(WUSB_udev,0x28,0x0);
 
        VME_register_write(WUSB_udev,0x2C,0x0);
 
        VME_register_write(WUSB_udev,0x30,0x0);
 
        VME_register_write(WUSB_udev,0x34,0x0);
 
        VME_register_write(WUSB_udev,0x3C,0x000);
 
 
 
        int nb = WIENER_VMUSB_StackGetUint32(10000,stackdata);
 
        int ret= xxusb_stack_execute(WUSB_udev,(uint32_t *)stackdata);
 
        printf("Init::%d ret=%d\n",nb
,ret
);  
        if (ret
>0) for (int k
=0; k
<ret
/2; k
++) printf ("stackdata=0x%08X\n",stackdata
[k
]);  
 
 
 
 
        WIENER_VMUSB_StackClear();
 
        WIENER_VMUSB_StackMarker(0xFFAB);
 
        for (int j=0; j<36; j++) WIENER_VMUSB_StackReadA24D32(addr[0] + CAENV965_OB);
 
        WIENER_VMUSB_StackMarker(0xFAFB);
 
        for (int k0=0; k0<nadc; k0++) {
 
                WIENER_VMUSB_StackWriteA24D16(addr[k0] + CAENV965_BS2,0x4);  // clear module
 
                WIENER_VMUSB_StackWriteA24D16(addr[k0] + CAENV965_BC2,0x4);
 
        }
 
 
 
        int nb0= WIENER_VMUSB_StackGetUint32(10000,&stackwrite[0]);
 
        if (nb0>768) {
 
                fprintf(stderr
,"nb0=%d > 768 error xxusb_stack_write\n", nb0
);  
        }
 
        nb =xxusb_stack_write(WUSB_udev,0x2,(uint32_t *) stackwrite);
 
        nb0=xxusb_stack_read(WUSB_udev,0x2,(uint32_t *) stackdata);
 
        for (int k1=0; k1<stackwrite[0]+1; k1++) {
 
                if (stackdata
[k1
]!=stackwrite
[k1
]) printf("%d %d init err %x %x\n",nb
,nb0
,  
                                        stackwrite[k1], stackdata[k1]);
 
        }
 
 
 
        if (fMode==2) xxusb_register_write(WUSB_udev,1,0x1); // Start DAQ mode
 
 
 
        return 0;
 
}
 
 
 
int vmconnect() {
 
        WIENER_VMUSB_VME_START("VM0120");
 
        //VME_START(WIENER_VMUSB);
 
 
 
        return 0;
 
}
 
 
 
int vmdisconnect() {
 
        /* zakljuci */
 
        WIENER_VMUSB_VME_STOP();
 
        printf("daq::disconnect()\n");  
        return 0;
 
}
 
 
 
int clear() {
 
        return 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 event(unsigned int *data, int maxn, int *ctr, int print) {
 
        int tout=200; /* 1/100 of a second */
 
        const int lsize=sizeof(uint32_t);
 
 
 
 
 
        ctr[0]++;
 
        ctr[1]++;
 
 
 
        int count=0;
 
        switch (fMode) {
 
                case 0: { // normal calls
 
                        unsigned short clr= 0x4;
 
                        unsigned int status=0;
 
                        uint32_t mdata;
 
 
 
                        for (int i=0; i<nadc; i++) {
 
                                // wait for trg
 
                                tmlnk (tout);
 
                                do WIENER_VMUSB_VME_A24D16_R( addr[i] + CAENV965_SR1, &status);
 
                                while ( (status&0x1)==0 && timer_out==0 && ctrl_c==0 );
 
                                tmulk();
 
                                // readout data
 
                                if (timer_out) return 0;
 
                                if (ctrl_c) return 0;
 
                                int len=0;
 
 
 
                                do {
 
                                        WIENER_VMUSB_VME_A24D32_R(addr[i]  + CAENV965_OB, &mdata);
 
                                        mdata=data[count++];
 
                                        len++;
 
                                } while  ( (mdata & 0x4000000)==0 && timer_out==0) ; // bit 26 EOB or not valid datum
 
                                // clear
 
                                WIENER_VMUSB_VME_A24D16_W( addr[i] + CAENV965_BS2, &clr);
 
                                WIENER_VMUSB_VME_A24D16_W( addr[i] + CAENV965_BC2, &clr);
 
 
 
                                if (count+2<maxn) {
 
                                        if (print
)  printf("V965 %3d\n",len
);  
                                        count+=module_header(0x130+i,&data[count],len);
 
                                        ctr[2]++;
 
                                        ctr[3]+=len;
 
                                }
 
 
 
                                timer_out=0;
 
                        }
 
                }
 
                break;
 
                case 1: { // stack execute
 
                        WIENER_VMUSB_StackGetUint32(10000,(int *)data);
 
                        int ret=xxusb_stack_execute(WUSB_udev,(uint32_t *) data); //The first element of the array is the number of bytes.
 
                        if (ret< 0 ) {
 
                                printf ("xxusb_stack_execute error err=%d\n",ret
);      \
  
                                count = 0;
 
                        } else count= ret/lsize;
 
 
 
                }
 
                break;
 
                case 2: { // stack load
 
                        int ret=xxusb_usbfifo_read(WUSB_udev,(int *) data,BUFF_L,100);
 
                        if (ret< 0 ) {
 
                                if (ret!=-110) {
 
                                        printf ("xxusb_usbfifo_read error err=%d\n",ret
);  
                                        end();
 
                                        init();
 
                                }
 
                                count = 0;
 
                        } else {
 
                                if (debug) {
 
                                        for (int i=0; i<100; i++) {
 
                                                printf ("%4d fifodata=0x%08X\n",i
, data
[i
]);  
                                                if (data[i]==0xFAFB) break;
 
                                        }
 
                                        /*
 
 
 
                                        0 fifodata=0x0000000D
 
                                        1 fifodata=0x00000049
 
                                        2 fifodata=0x0000FFAB
 
                                        3 fifodata=0x00002000
 
                                        4 fifodata=0x00000200
 
                                        5 fifodata=0x00004141
 
                                        6 fifodata=0x00000000
 
                                        7 fifodata=0x00004057
 
                                        
 
                                        70 fifodata=0x00000400
 
                                        71 fifodata=0x00000035
 
                                        72 fifodata=0x00000600
 
                                        73 fifodata=0x00000035
 
                                        74 fifodata=0x0000FAFB
 
 
 
 
 
                                        */
 
                                }
 
                                static double t0=0;
 
                                static int nc =0;
 
                                nc += data[0]; 
 
                                if (print) { 
 
                                        //printf("##------------------ret=%d data[0]=%d\n",ret,(int)data[0]);
 
                                        double t1 = Timer();
 
                                        double dt = t1-t0;
 
                                        t0 = t1;
 
                                        float rate = (dt>0)?nc/dt:0;
 
                                        
 
                                        //printf("--------ret=%d data[0]=%f nc=%d dt=%f\n",ret,rate,nc,dt);
 
                                  PlotStripChart (p1, P1_DAQRATE, &rate, 1, 0, 0,VAL_FLOAT);
 
                                  nc =0; 
 
                                }       
 
                                count= ret/lsize;
 
                                ctr[2]+=data[0];
 
                                ctr[3]+=count;
 
                        }
 
                }
 
                break;
 
        }
 
        return count*lsize;
 
}
 
 
 
int end() {
 
 
 
        xxusb_register_write(WUSB_udev,1,0x0); // Stop DAQ mode
 
        while (xxusb_usbfifo_read(WUSB_udev,(int *) stackdata,BUFF_L,30)>0);
 
        return 0;
 
}
 
 
 
 
 
 
 
 
 
int vmacquire (int neve,FILE *fp, char *fpedname) {
 
        // neve   .... negative argument time ( in s )limited event loop      
 
        if (fThreshold
== NULL
) fThreshold 
= (int *) malloc (sizeof(int)*128);  
        // print welcome message
 
        time_t t, told;
 
        double tstart, tstop;
 
        fThresholdEnable=0;
 
 
 
#define BSIZE 10000
 
        uint32_t data[10000];
 
        
 
        fMode = 2;
 
        fPedestal=255;
 
        for (int ki=0; ki<128; ki++) {
 
                if (ki<72) fThreshold[ki]=0;
 
                else      fThreshold[ki]=0x1<<8; // samo 4 kanali na zadnjem modulu so enablani
 
        }
 
        fThresholdEnable=0;
 
        fStop=0;
 
 
 
 
 
 
 
        if (fpedname !=NULL) {
 
 
 
                FILE 
*fped
=fopen(fpedname
,"r"); 
 
 
                int j=0;
 
                int ndim=400;
 
                char line[ndim];
 
                int val=0;
 
                while (fgets(line
,ndim
,fped
)!=NULL
) {  
                        fThreshold[j++]=val;
 
                }
 
                fThresholdEnable=1;
 
 
 
        }
 
 
 
 
 
        
 
        init();
 
        
 
 
 
        int hdr[4]= {2}; // recid 
 
        int i=0;
 
        int ntotal=0;
 
        int counters[30]= {0,0,0,0,0, 0,0,0,0,0,0,0};
 
        char names[10][20]= {"TRG","CAEN V965"};
 
        tstart=Timer();
 
        told  =t;
 
        tstop=tstart+360000;
 
        if (neve<-1) {
 
                tstop=tstart-neve;
 
                neve=-1;
 
        }
 
        for (i=0; i!=neve && !ctrl_c && Timer()<tstop; i++) {
 
                if (t
!=told 
) printf("%d in %2.2f min daq::event() %s\n",i
, (double)(Timer
()-tstart
)/60.
, ctime(&t
));  
                int nb=event(data,BSIZE, counters,t!=told);
 
                analyse(nb, data);
 
                if (nb>0) {
 
                        // zapis v datoteko
 
                        hdr[1]=nb+4*sizeof(int);
 
                        hdr[3]=i;
 
 
 
                        fwrite(hdr
,  1, sizeof(int)*4, fp
); //gzip  
                        ntotal 
+= fwrite(data
,1,  nb
, fp
); 
                        told=t;
 
                } else i--;
 
        }
 
 
 
        end();
 
 
 
        printf("Number of Events: %d\n",i
);  
        if (ctrl_c
) printf("User Program termination CTRL-C\n");  
        if (Timer
()>tstop  
) printf("Timeout termination tstart# t>tstop: %d# %d >%d\n",(int)t
, (int)tstart
, (int) tstop
);  
 
 
 
 
        printf("%d bytes written to file\nCounts:\n", (int) (ntotal
*sizeof(int)));  
        for (i
=0; i
<2; i
++) printf("%s\t%d\t%d\n",names
[i
],counters
[2*i
],counters
[2*i
+1]) ;  
 
 
 
 
        return 0;
 
}