#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
#include <zlib.h>
#include "CAENV965_DEF.h"
#include "VmUsbStack.h"
#include "vme.h"
#include "daq.h"
#define VERSION 1.0
#define TIMEOUT 3
/* 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 };
int nadc=3;
int gPedestal = 255;
#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;
struct sigaction oact;
void timerast (int signumber)
{
timer_out = TRUE;
}
void tmlnk (int tout)
{
timer_out = FALSE;
struct sigaction act;
struct itimerval tdelay;
act.sa_handler = timerast;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
tdelay.it_value.tv_sec = tout / 100;
tdelay.it_value.tv_usec = 10000 * (tout % 100);
tdelay.it_interval.tv_sec = 0;
tdelay.it_interval.tv_usec = 0;
if (sigaction (SIGALRM, &act, &oact) < 0)
{
}
if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
{
}
}
void tmulk ()
{
struct itimerval tdelay;
tdelay.it_value.tv_sec = 0;
tdelay.it_value.tv_usec = 0;
tdelay.it_interval.tv_sec = 0;
tdelay.it_interval.tv_usec = 0;
if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
{
}
if (sigaction (SIGALRM, &oact, NULL) < 0)
{
}
}
int fexist( char * path){
struct stat sbuf;
int res;
if(!path || !*path) return 0;
res=stat(path,&sbuf);
if (res){
if (errno==ENOENT) {
return 0;
} else {
return -1;
}
}
return 1;
}
int daq::init(){
xxusb_register_write(udev,1,0x0); // Stop DAQ mode
while (xxusb_usbfifo_read(udev,(int *) stackdump,BUFF_L,100)>0);
int rate=1000;
int i=80000000/rate-40; // 80 MHz
if (i<72) i=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(udev,0,6,0,i,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(udev,1,1,1,0,10,0,1);
// INIT stackdata
int fPedestal=gPedestal;
printf("CAEN V965 Pedestal set to %d\n", fPedestal
);
if (fInit != NULL ) delete fInit;
fInit=new VmUsbStack();
for (int i=0;i<nadc;i++){
fInit->WriteA24D16( addr[i] + CAENV965_CRN , 0x0);
fInit->WriteA24D16( addr[i] + CAENV965_GEO , i);
fInit->ReadA24D16(addr[i] + CAENV965_GEO);
for (int j=0;j<32;j++){
fInit->WriteA24D16(addr[i] + CAENV965_THM + 0x02*j, fThreshold[j+i*32]); // threshold/kill for 32 channels
}
fInit->WriteA24D16( addr[i] + CAENV965_BS1, 0x80 ); // soft reset
fInit->WriteA24D16( addr[i] + CAENV965_BC1, 0x80 ); // soft reset
fInit->WriteA24D16( addr[i] + CAENV965_PED, fPedestal ); // pedestal
fInit->WriteA24D16( addr[i] + CAENV965_BS2,0x5000);
fInit->WriteA24D16( addr[i] + CAENV965_BS2,0x4); // clear module
fInit->WriteA24D16( addr[i] + CAENV965_BC2,0x4);
}
fInit->Marker(0xFAFC);
// fInit->Print();
// READOUT stackdata
if (fStack != NULL ) delete fStack;
fStack=new VmUsbStack();
fStack->Marker(0xFFAB);
//fStack->ConditionalRead(addr[i] + CAENV965_SR1,0x1); // TRG wait : loop until bit 0 is on
// fStack->RepeatRead( CMD_A24, CMD_D32, addr[i] + CAENV965_OB,34,0); // repead read
//fStack->ConditionalRead(addr[i] + CAENV965_OB ,0x4000000) ; // loop until bit 26 is on, read data
for (int j=0;j<36;j++) fStack->ReadA24D32(addr[0] + CAENV965_OB);
for (int j=0;j<36;j++) fStack->ReadA24D32(addr[1] + CAENV965_OB);
for (int j=0;j<8;j++) fStack->ReadA24D32(addr[2] + CAENV965_OB);// 4 channels connected
fStack->Marker(0xFAFB);
for (int i=0;i<nadc;i++){
fStack->WriteA24D16(addr[i] + CAENV965_BS2,0x4); // clear module
fStack->WriteA24D16(addr[i] + CAENV965_BC2,0x4);
}
//fStack->Print();
VME_LED_settings(udev, 0,0,0,0); // Set Yellow LED to light with with USB out buffer not empty
VME_LED_settings(udev, 1,1,0,0); // Set Red LED to light with NIM1
VME_LED_settings(udev,2,0,0,0); // Set Green LED to light when stack is not empty
Uint32_t vmereg;
VME_register_read(udev,0x00,&vmereg);
printf("VMUSB Firmware ID -> 0x%08X\n",vmereg
);
VME_register_read(udev,0x04,&vmereg);
printf("VMUSB Global Mode -> 0x%08X\n",vmereg
);
vmereg=(vmereg&0xF000)|0x0004;
VME_register_write(udev,0x04,vmereg);
VME_register_write(udev,0x08,0x00000080);
VME_register_write(udev,0x28,0x0);
VME_register_write(udev,0x2C,0x0);
VME_register_write(udev,0x30,0x0);
VME_register_write(udev,0x34,0x0);
VME_register_write(udev,0x3C,0x000);
int nb = fInit->Get(10000,stackdata);
int ret= xxusb_stack_execute(udev,(Uint32_t *)stackdata);
printf("Init::%d ret=%d\n",nb
,ret
);
if (ret
>0) for (int i
=0;i
<ret
/2;i
++) printf ("stackdata=0x%08X\n",stackdata
[i
]);
int nb0= fStack->Get(10000,&stackwrite[0]);
if (nb0>768) {
fprintf(stderr
,"nb0=%d > 768 error xxusb_stack_write\n", nb0
);
}
nb =xxusb_stack_write(udev,0x2,(Uint32_t *) stackwrite);
nb0=xxusb_stack_read(udev,0x2,(Uint32_t *) stackdata);
for (int i=0;i<stackwrite[0]+1;i++){
if (stackdata
[i
]!=stackwrite
[i
]) printf("%d %d init err %x %x\n",nb
,nb0
,stackwrite
[i
], stackdata
[i
]);
}
if (fMode==2) xxusb_register_write(udev,1,0x1); // Start DAQ mode
return 0;
}
int daq::connect(){
VME_START(NULL);
return 0;
}
int daq::disconnect(){
/* zakljuci */
VME_STOP();
printf("daq::disconnect()\n");
return 0;
}
int daq:: clear(){
return 0;
}
inline int module_header(int recid,Uint32_t *data,int len){
data[0] = recid;
data[1] = (len >0)? len : 0 ;
return data[1]+2;
}
int daq::event(unsigned int *data, int maxn, int *ctr, int print){
int tout=200; /* 1/100 of a second */
const int lsize=sizeof(unsigned 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<2;i++){
// wait for trg
tmlnk (tout);
do VME_A24D16_R( addr[i] + CAENV965_SR1, &status); while ( (status&0x1)==0 && timer_out==0 );
tmulk();
// readout data
if (timer_out) return 0;
int len=0;
do {
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
VME_A24D16_W( addr[i] + CAENV965_BS2, &clr);
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
{
fStack->Get(10000,(int *)data);
int ret=xxusb_stack_execute(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(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 (0 && print && ret>0) {
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
8 fifodata=0x00000010
9 fifodata=0x00004052
10 fifodata=0x00000001
11 fifodata=0x0000405C
12 fifodata=0x00000011
13 fifodata=0x0000405D
14 fifodata=0x00000002
15 fifodata=0x0000405E
16 fifodata=0x00000012
17 fifodata=0x0000401C
18 fifodata=0x00000003
19 fifodata=0x0000402F
20 fifodata=0x00000013
21 fifodata=0x00004024
22 fifodata=0x00000004
23 fifodata=0x00004076
24 fifodata=0x00000014
25 fifodata=0x0000412F
26 fifodata=0x00000005
27 fifodata=0x0000404C
28 fifodata=0x00000015
29 fifodata=0x00004132
30 fifodata=0x00000006
31 fifodata=0x00004044
32 fifodata=0x00000016
33 fifodata=0x0000404A
34 fifodata=0x00000007
35 fifodata=0x0000409B
36 fifodata=0x00000017
37 fifodata=0x000040F1
38 fifodata=0x00000008
39 fifodata=0x00004087
40 fifodata=0x00000018
41 fifodata=0x00004173
42 fifodata=0x00000009
43 fifodata=0x0000404C
44 fifodata=0x00000019
45 fifodata=0x0000406C
46 fifodata=0x0000000A
47 fifodata=0x00004070
48 fifodata=0x0000001A
49 fifodata=0x0000406E
50 fifodata=0x0000000B
51 fifodata=0x00004014
52 fifodata=0x0000001B
53 fifodata=0x000040B7
54 fifodata=0x0000000C
55 fifodata=0x000040A9
56 fifodata=0x0000001C
57 fifodata=0x00004048
58 fifodata=0x0000000D
59 fifodata=0x00004118
60 fifodata=0x0000001D
61 fifodata=0x0000409D
62 fifodata=0x0000000E
63 fifodata=0x0000405B
64 fifodata=0x0000001E
65 fifodata=0x00004285
66 fifodata=0x0000000F
67 fifodata=0x00004159
68 fifodata=0x0000001F
69 fifodata=0x00000035
70 fifodata=0x00000400
71 fifodata=0x00000035
72 fifodata=0x00000600
73 fifodata=0x00000035
74 fifodata=0x0000FAFB
*/
}
if (print
) printf("------------------ret=%d data[0]=%d\n",ret
,(int)data
[0]);
count= ret/lsize;
ctr[2]+=data[0];
ctr[3]+=count;
}
}
break;
}
return count*lsize;
}
int daq::end(){
xxusb_register_write(udev,1,0x0); // Stop DAQ mode
while (xxusb_usbfifo_read(udev,(int *) stackdata,BUFF_L,30)>0);
return 0;
}
daq::daq(){
fMode = 2;
fPedestal=255;
for (int i=0;i<128;i++){
if (i<72) fThreshold.push_back(0);
else fThreshold.push_back(0x1<<8); // samo 4 kanali na zadnjem modulu so enablani
}
fThresholdEnable=0;
fStop=0;
fInit=NULL;
fStack=NULL;
connect();
}
daq::~daq(){
disconnect();
}
#ifdef MAIN
/* ------------------- CatchSig ----------------- */
int ctrlcflag=0;
void SigInt (int sig)
{
ctrlcflag = 1;
timer_out=1;
}
int main (int argc, char **argv){
// intercept routine
if (signal (SIGINT, SigInt) == SIG_ERR) {
}
// print welcome message
time_t t,told, tstart, tstop;
fprintf(stdout
,"#############################################\n");
fprintf(stdout
,"Program %s version %2.1f\n",argv
[0], VERSION
);
fprintf(stdout
,"Compiled on %s %s\n",__DATE__
, __TIME__
);
fprintf(stdout
,"#############################################\n");
int neve=-1;
char cfname[100]="test.dat";
char *fname=cfname;
char *fpedname=NULL;
#define BSIZE 10000
Uint32_t data[10000];
daq *d= new daq();
int c;
while ((c = getopt (argc, argv, "p:n:t:o:")) != -1)
switch (c)
{
case 'o':
if (fexist(fname)==1){
fprintf(stdout
,"File %s already exist. Appending ....\n",fname
);
//fprintf(stdout,"Remove the file and restart !!!\n");
//exit(0);
}
break; // input file
case 'n':
neve
= atoi(optarg
); // negative argument time ( in s )limited event loop
break;
case 't':
{
FILE
*fped
=fopen(fpedname
,"r");
int j=0;
int ndim=400;
char line[ndim];
int val=0;
while (fgets(line
,ndim
,fped
)!=NULL
){
d->fThreshold[j++]=val;
}
d->fThresholdEnable=1;
//fclose(fped);
break;
}
case 'p':
gPedestal
= atoi(optarg
); // injected charge to the qdc
break;
}
if (argc==1) {
fprintf(stdout
,"Usage: %s -o [filename] -n [number of events] -t [thresholdfile] -p <qdc inject charge>\n negative number of events = acq time in seconds\n",argv
[0]);
}
//FILE *fp=fopen(fname,"a");
gzFile fp=gzopen(fname,"a");
d->init();
d->clear();
int hdr[4]={2}; // recid od run 11 naprej
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=t;
tstop=tstart+360000;
if (neve<-1) {
tstop=tstart-neve;
neve=-1;
}
for (i=0;i!=neve && !ctrlcflag && t<tstop;i++){
if (t
!=told
) printf("%d in %2.2f min daq::event() %s\n",i
, (double)(t
-tstart
)/60.
, ctime(&t
));
int nb=d->event(data,BSIZE, counters,t!=told);
if (nb>0){
// zapis v datoteko
hdr[1]=nb+4*sizeof(int);
hdr[3]=i;
//fwrite(hdr, sizeof(int),4 , fp);
gzwrite(fp, hdr, sizeof(int)*4); //gzip
// recid=1 do runa 10. ntotal += fwrite(data, sizeof(int),nb, fp);
//ntotal += fwrite(data, 1,nb, fp);
ntotal += gzwrite(fp, data, nb);
told=t;
} else i--;
}
d->end();
delete d;
printf("Number of Events: %d\n",i
);
if (ctrlcflag
) printf("User Program termination CTRL-C\n");
if (t
>tstop
) printf("Timeout termination tstart# t>tstop: %d# %d >%d\n",(int)t
, (int)tstart
, (int) tstop
);
//fclose(fp);
gzclose(fp);
fprintf(stdout
,"%d bytes written to %s\nCounts:\n", (int) (ntotal
*sizeof(int)),fname
);
for (i
=0;i
<2;i
++) fprintf(stdout
,"%s\t%d\t%d\n",names
[i
],counters
[2*i
],counters
[2*i
+1]) ;
return 0;
}
#endif