Blame |
Last modification |
View Log
| RSS feed
//
// test.c
//
// Description : test program for V729
//
// Author : S. Korpar
// Date : 2005/07/15
// adapted to CAEN V1719 by R. Pestotnik 2012/09/07
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <vector>
#include <sys/time.h>
#include <sys/stat.h>
#include <signal.h>
#include <string>
#include "vme.h"
#include "CAEN_V729_DEF.h"
#define V729_OFFSET 0x880000
#define IREG_OFFSET 0x2000
#define V729_WAIT 1
#define TRUE 1
#define FALSE 0
uint32_t V729_module
=0;
int timer_out
;
struct sigaction oact
;
//---------------------------------------------------------
void SigInt
(int sig
)
{
timer_out
=1;
}
//---------------------------------------------------------
void timerast
(int signumber
)
{
timer_out
= TRUE
;
fprintf(stderr
,"TIMEOUT !!!\n");
}
//---------------------------------------------------------
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)
{
perror ("sigaction(tmlnk)");
exit (EXIT_FAILURE
);
}
if (setitimer
(ITIMER_REAL
, &tdelay
, NULL
) < 0)
{
perror ("setitimer(tmlnk)");
exit (EXIT_FAILURE
);
}
}
//---------------------------------------------------------
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)
{
perror ("setitimer(tmulk)");
exit (EXIT_FAILURE
);
}
if (sigaction
(SIGALRM
, &oact
, NULL
) < 0)
{
perror ("sigaction(tmulk)");
exit (EXIT_FAILURE
);
}
}
//---------------------------------------------------------
int wait_while
(int num
){
int i
, tmp
;
for ( i
=0; i
<num
; i
++ ) tmp
= 0;
return tmp
;
}
//---------------------------------------------------------
void V729_map
( uint32_t addr
)
{
V729_module
= addr
;
return;
}
//---------------------------------------------------------
void V729_info
(FILE
*kam
)
{
unsigned short code
, mid
, ver
;
VME_A24D16_R
(V729_module
+0xFA,&code
);
VME_A24D16_R
(V729_module
+0xFC,&mid
);
VME_A24D16_R
(V729_module
+0xFE,&ver
);
fprintf(kam
, "code/mid/ver = 0x%04X/0x%04X/0x%04X\n", code
, mid
, ver
);
fprintf(kam
, "Fixed code (0xFAF5) = 0x%04X\n", code
);
fprintf(kam
, "Manufacturer/Type = 0x%02X/0x%03X\n",
(mid
& 0xFC00)>>10, mid
& 0x3FF);
fprintf(kam
, "Version/Serial = %d/%d\n",
(ver
& 0xF000)>>12, ver
& 0xFFF);
return;
}
//---------------------------------------------------------
void V729_reg
( uint32_t val
){
uint32_t push
=0;
VME_A24D16_W
(V729_module
+V729_FSR
, &val
);
VME_A24D16_W
(V729_module
+V729_UFSR
, &push
); //push
usleep
(V729_WAIT
);
}
//---------------------------------------------------------
void V729_reset
(int nall
,int nbefore
,int obae
,int obaf
)
{
uint32_t cbl
;
// cbl=4096+12-100;
cbl
=4096+12-nbefore
;
uint32_t val
=0;
VME_A24D16_W
(V729_module
+V729_RR
, &val
); // reset
printf("nbefore=%d\t", nbefore
);
printf("nall=%d\t", nall
);
printf("obae=%d\t", obae
);
printf("obaf=%d\n", obaf
);
// set AE
V729_reg
( (obae
& 0xFF)<<8 ) ; //
V729_reg
( (obae
& 0xF00) ) ; //
// set AF and CBL
V729_reg
( ((obaf
& 0xFF)<<8) + (cbl
& 0xFF) );
V729_reg
( (obaf
& 0xF00) + ((cbl
& 0xF00)>>8) );
VME_A24D16_W
(V729_module
+V729_SR
,&nall
); //total number of samples
return;
}
//---------------------------------------------------------
void V729_set_bias
(int range
, int bias1
, int bias2
)
{
int i
;
uint32_t bias
;
switch (range
) {
case 0: //User
for (i
=0x18;i
<0x27;i
+=4){
VME_A24D16_W
(V729_module
+i
, &bias1
); //bias
usleep
(V729_WAIT
);
VME_A24D16_W
(V729_module
+i
+2, &bias2
); //bias
usleep
(V729_WAIT
);
}
printf("Bias + %x - %x\n", bias1
, bias2
);
break;
case 1: //Single Ended +
for (i
=0x18;i
<0x27;i
+=4){
bias
= 0xCC; VME_A24D16_W
(V729_module
+i
, &bias
); //bias
usleep
(V729_WAIT
);
bias
=0x733; VME_A24D16_W
(V729_module
+i
+2, &bias
); //bias
usleep
(V729_WAIT
);
}
break;
case 2: //Single Ended -
for (i
=0x18;i
<0x27;i
+=4){
bias
=0x733; VME_A24D16_W
(V729_module
+i
, &bias
); //bias
usleep
(V729_WAIT
);
bias
= 0xD99 ; VME_A24D16_W
(V729_module
+i
+2, &bias
); //bias
usleep
(V729_WAIT
);
}
break;
case 4: //Differential Unipolar
for (i
=0x18;i
<0x27;i
+=4){
bias
= 0x400; VME_A24D16_W
(V729_module
+i
,&bias
); //bias
usleep
(V729_WAIT
);
bias
= 0xA66; VME_A24D16_W
(V729_module
+i
+2, &bias
); //bias
usleep
(V729_WAIT
);
}
break;
case 3: //Single Ended Bipolar
case 5: //Differential Bipolar
default:
for (i
=0x18;i
<0x27;i
+=2){
bias
=0x733; VME_A24D16_W
(V729_module
+i
, &bias
); //bias
usleep
(V729_WAIT
);
}
break;
}
return;
}
//---------------------------------------------------------
void V729_aquisition_mode
(uint32_t mode
) // mode 0 aqusition mode, 0x30 buffers programming
{
#ifdef V729_DEBUG
int status
;
VME_A24D16_R
(V729_module
+V729_CSR
, &status
);
usleep
(V729_WAIT
);
fprintf(stderr
, "0x0E = 0x%04X\n", status
);
#endif
VME_A24D16_W
(V729_module
+V729_CSR
, &mode
); //aquisition mode
usleep
(V729_WAIT
);
#ifdef V729_DEBUG
VME_A24D16_W
(V729_module
+V729_CSR
, &status
);
usleep
(V729_WAIT
);
fprintf(stderr
, "0x0E = 0x%04X\n", status
);
#endif
return;
}
//---------------------------------------------------------
void V729_soft_stop
()
{
uint32_t sw
=1;
VME_A24D16_W
(V729_module
+0x16,&sw
);
// usleep(V729_WAIT);
sw
=0;
VME_A24D16_W
(V729_module
+0x16,&sw
);
// usleep(V729_WAIT);
return;
}
//---------------------------------------------------------
void V729_clear_buffer
()
{
const int tout
=100; /* 1/100 of a second */
tmlnk
(tout
);
uint32_t data1
,data2
;
do {
VME_A24D32_R
(V729_module
+V729_OBR1
, &data1
);
if (timer_out
) break;
} while (data1
& (0x3<<29));
do {
VME_A24D32_R
(V729_module
+V729_OBR2
, &data2
);
if (timer_out
) break;
} while (data2
& (0x3<<29));
tmulk
();
return;
}
void V729_get_buffer
(uint32_t *data1
, uint32_t *data2
)
{
VME_A24D32_R
(V729_module
+V729_OBR1
, data1
);
// usleep(V729_WAIT);
VME_A24D32_R
(V729_module
+V729_OBR2
, data2
);
// usleep(V729_WAIT);
return;
}
int V729_status
()
{
uint32_t status
;
VME_A24D16_R
(V729_module
+V729_CSR
, &status
);
return status
;
}
//---------------------------------------------------------
void V729_init
(uint32_t addr
, int nall
, int cbl
, uint32_t bias1
, uint32_t bias2
){
V729_map
(addr
);
V729_info
(stderr
);
V729_reset
(nall
,cbl
,nall
,0xC00);
V729_set_bias
(0,bias1
,bias2
);
V729_aquisition_mode
(0);
CAENVME_SetFIFOMode
(udev
,1);
sleep
(1);
}
//---------------------------------------------------------
int V729_event
(int mask
, int nall
, uint32_t *data
,uint32_t *data1
,uint32_t *data2
){
uint32_t status
;
const int tout
=100; /* 1/100 of a second */
tmlnk
(tout
);
int count
=0;
//status= 0x80 ; VME_A16D16_W(IREG_OFFSET+0x8,&status); // pulse ch 8
status
= 0x1a ; VME_A16D16_W
(IREG_OFFSET
+0xC,&status
); // clr1 enable1 .... clear busy1 flag
do {
//usleep(1);
VME_A24D16_R
(V729_module
+V729_CSR
, &status
);
// fprintf(stderr,"0x%X, 0x%X\n",status,(status & 0x5) ^ 0x5);
count
++;
if (timer_out
) {
tmulk
();
printf("[%d] daq=%x status AE01=%d AE23=%d Waiting for DATA TRG bit... at line %d\n",count
, (status
>>4)&0x3, status
&0x1,(status
>>2)&0x1 , __LINE__
);
V729_clear_buffer
();
return -1;
}
} while ((status
& 0x5) ^ 0x5);
tmulk
();
int nb
;
const int blt
=1;
if (blt
){
VME_A24D32_FIFOBLTR
(V729_module
+V729_OBR1
,data1
,(nall
+5)*sizeof(uint32_t),&nb
);
VME_A24D32_FIFOBLTR
(V729_module
+V729_OBR2
,data2
,(nall
+5)*sizeof(uint32_t),&nb
);
for (int i
=0;i
<nall
+5;i
++){
data
[2*i
] = data1
[i
];
data
[2*i
+1] = data2
[i
];
}
nb
*=2;
} else {
VME_MRRST
(); // MultiReadReset
int nc
=0;
for (int i
=0;i
<nall
+5;i
++){
//if (mask & 0x3)
VME_A24D32_MR
(V729_module
+V729_OBR1
, &data
[nc
++]);
//if (mask & 0xc)
VME_A24D32_MR
(V729_module
+V729_OBR2
, &data
[nc
++]);
}
int j
= VME_MREXEC
(data
); // MultiReadExecute
nb
=j
*sizeof(uint32_t);
}
return nb
;
}
//---------------------------------------------------------
int V729_decode
(uint32_t mask
, int nall
, uint32_t *data
, uint16_t *dadc
, int debug
){
uint16_t *adc
[4];
for (int i
=0;i
<4;i
++) adc
[i
] = &dadc
[4+i
*(nall
+2)];
int nc
=0;
int narrays
=0;
if (mask
& 0x3) narrays
++;
if (mask
& 0xc) narrays
++;
int indx
[4] ={0,0,0,0};
int shft
[4] ={0,0,0,0};
int ashft
[4]={0,0,0,0};
int nmask
=0;
for (int i
=0;i
<4;i
++) if (mask
& (1<<i
) ) {
indx
[nmask
] = i
;
shft
[nmask
] = (i
%2)*12;
if (( (mask
& 0x3) > 0 ) && (i
>1)) ashft
[nmask
]=1 ;
else ashft
[nmask
]=0;
nmask
++;
}
for (int j
=0;j
<nmask
;j
++){
nc
=0;
for (int i
=0;i
<nall
+5;i
++){
int ii
=narrays
*i
+ashft
[j
];
uint32_t data1
= data
[ii
];
if (data1
& (1<<31)) {
if (debug
) fprintf(stdout
,"data1: empty flags: 0x%X, time tag: 0x%06X\n", (data1
>>29) & 0x3, data1
& 0xFFFFFF);
} else if ((data1
>>29) & 0x3){
if (nc
<nall
){
adc
[j
][nc
] = (data1
>>shft
[j
]) & 0xFFF;
if (debug
) printf("[%d/%d] ADC%d adc0=%d\n", i
,nc
,indx
[j
], adc
[j
][nc
]);
nc
++;
}
} else {
if (debug
) fprintf(stdout
,"Data(%4d) %d indx=%d %d nc=%d(%d) %d 0x%08X\n", i
, indx
[j
],narrays
*i
+ashft
[j
],j
,nc
,nmask
,narrays
, data1
);
}
}
}
return nc
;
}
//---------------------------------------------------------
// test program
#ifdef V729_MAIN
int ctrlc
=0;
void CatchSig
(int i
){
ctrlc
= 1;
}
int main
(int argc
,char **argv
){
if (argc
== 1) {
printf ("*********************************************************************************:\n");
printf ("Usage: %s <arguments> ......... CAEN V729A data aquisition:\n\n", argv
[0]);
printf ("Arguments: \n");
printf ("-d <debuglevel> \n");
printf ("-b <bias+> \n");
printf ("-e <bias-> \n");
printf ("-a <VME address> \n");
printf ("-c <n samples before stop> \n");
printf ("-n <number of events> \n");
printf ("-l <nall> number of samples \n");
printf ("-m <channel mask: 4bits (1 bit/ch)> \n");
printf ("-o <output file name> \n");
printf ("*********************************************************************************:\n");
exit (-1);
}
uint32_t mask
=0xF;
int cbl
=13;
int nall
=1330;
char filename
[0xFF]="";
int verbose
= 0;
int neve
= 1;
uint32_t addr
= V729_OFFSET
;
uint32_t bias1
= 0x600; // vecje vrednosti povzročajo težave in zacno kanali oscilirat ....
uint32_t bias2
= 0x200;
int append
=0;
int c
=0;
while ((c
= getopt
(argc
, argv
, "b:e:a:d:c:l:n:o:m:f:")) != -1)
switch (c
){
case 'd':
verbose
=atoi(optarg
);
break;
case 'c':
cbl
=atoi(optarg
);
break;
case 'l':
nall
=atoi(optarg
);
if (nall
%16) {
printf ("buffer length should be multiple of 16 , modulo = %d\n",nall
%16);
// exit(-1);
}
break;
case 'n':
neve
=atoi(optarg
);
break;
case 'a':
addr
=strtoul (optarg
,NULL
,0);
break; // address
case 'b':
bias1
=strtoul (optarg
,NULL
,0);
break; // bias
case 'e':
bias2
=strtoul (optarg
,NULL
,0);
break; // bias
case 'm':
mask
=strtoul (optarg
,NULL
,0);
break; // mask
case 'o':
sprintf(filename
,"%s", optarg
);
append
=0;
break; // output
case 'f':
sprintf(filename
,"%s", optarg
);
append
=1;
break; // output
}
// intercept routine
if (signal
(SIGINT
, CatchSig
) == SIG_ERR
) perror ("sigignore");
// reset timers
time_t t
,told
=0, tstart
;
time(&t
);
tstart
=t
;
// open file
FILE
*fp
=NULL
;
int output
=0;
if (strlen(filename
)>0) {
if (verbose
) printf("Data in the file:%s\n", filename
);
if (append
) fp
=fopen(filename
,"a");
else fp
=fopen(filename
,"w");
output
=1;
}
// alloocate storage
uint32_t *data
= new
uint32_t[2*(nall
+5)];
uint32_t *data1
= new
uint32_t[2*(nall
+5)];
uint32_t *data2
= new
uint32_t[2*(nall
+5)];
int nmask
=0;
for (int i
=0;i
<4;i
++) if (mask
& (1<<i
)) nmask
++;
int adclen
= nall
+2;
int len
= nmask
* adclen
+2;
uint16_t *adc
= new
uint16_t[len
]; // 4 channels + 4 ch header + 1 event hdr
// write headers
uint16_t *evhdr
= &adc
[0];
evhdr
[0] = 0;
evhdr
[1] = len
*sizeof(uint16_t);
int imask
=0;
for (int ch
=0;ch
<4;ch
++){
if ( mask
& (1<<ch
) ) {
uint16_t *chhdr
= &adc
[2+imask
*adclen
];
chhdr
[0] = ch
+1;
chhdr
[1] = adclen
*sizeof(uint16_t);
imask
++;
}
}
// start
int ncount
=0;
int nerrors
=0;
int nball
=0;
// open VME and initialize board
char *serial
= new
char[100];
VME_START
(serial
);
printf("CAEN V1718 BoardFWRelease %s\n", serial
);
V729_init
(addr
, nall
, cbl
, bias1
,bias2
);
// event loop
for (int j
=0; j
<neve
; j
++) {
if (ctrlc
) break;
int nb
= V729_event
(mask
,nall
,data
, data1
,data2
);
if (nb
<0) { // timeout
j
--;
nerrors
++;
} else {
V729_decode
(mask
,nall
,data
,adc
, verbose
);
// V729_clear_buffer();
if (output
) nball
+= fwrite(adc
, 1, sizeof(uint16_t)*len
, fp
);
ncount
++;
}
time(&t
);
if (t
/4!=told
) printf("%d events in %2.2f min (%d s) USBerr=%d TIMEOUTS=%d %s",ncount
, (double)(t
-tstart
)/60.
,int(t
-tstart
), VMEerrors
, nerrors
, ctime(&t
));
told
=t
/4;
}
// end
if (output
) fclose(fp
);
VME_STOP
();
time(&t
);
printf("%d events in %2.2f min (%d s) USBerr=%d TIMEOUTS=%d %s\n",ncount
, (double)(t
-tstart
)/60.
,int(t
-tstart
),VMEerrors
, nerrors
, ctime(&t
));
return 0;
}
#endif //V729_MAIN