Blame |
Last modification |
View Log
| RSS feed
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <unistd.h>
#ifdef MRP
#include <rp.h>
#else
#include "calib.h"
#endif
#include "fpga_osc.h"
#define TRUE -1
#define FALSE 0
int timer_out
; struct sigaction oact
;
int ctrl_c
=0;
void SigInt
(int sig
) {
ctrl_c
= 1;
}
void timerast
(signumber
, code
, context
) int signumber
, code
; struct sigcontext context
; {
fprintf(stderr
, "Timeout\n");
timer_out
= TRUE
;
}
void tmlnk
(tout
) int tout
; {
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
);
}
}
#ifndef MRP
rp_calib_params_t rp_calib_params
; /** Pointer to externally defined calibration parameters. */ rp_calib_params_t
*gen_calib_params
= NULL
;
#endif
int daq_init
(char * buff
) {
#ifdef DEBUG
fprintf (stderr
, "Server: init\n");
#endif
int * hdr
= (int *) buff
;
int delay
= hdr
[0];
int decimation
= hdr
[1];
float threshold_voltage
= hdr
[2]/1000.
;
fprintf(stderr
, "delay = %d\tdecimation = %d\tthreshold = %f\n", delay
, decimation
, threshold_voltage
);
/*
rp_default_calib_params(&rp_calib_params);
gen_calib_params = &rp_calib_params;
if(rp_read_calib_params(gen_calib_params) < 0) {
fprintf(stderr, "rp_read_calib_params() failed, using default"
" parameters\n");
}
*/
// use this to acquire calibrated offset: int offset = gen_calib_params->fe_ch1_dc_offs;
#ifdef MRP
if(rp_Init
() != RP_OK
){
fprintf(stderr
, "Rp api init failed!\n");
}
rp_AcqReset
();
const int rpdecimation
[6]={RP_DEC_1
,RP_DEC_8
,RP_DEC_64
,
RP_DEC_1024
,RP_DEC_8192
,RP_DEC_65536
};
rp_AcqSetDecimation
(rpdecimation
[decimation
%6]);
const int c
[2] = {RP_CH_1
, RP_CH_2
};
rp_AcqSetTriggerLevel
(c
[0],threshold_voltage
); //Trig level is set in Volts while in SCPI
rp_AcqSetTriggerLevel
(c
[1],threshold_voltage
);
rp_AcqSetTriggerDelay
(delay
);
return 0;
#else
// initialization
int start
= osc_fpga_init
();
if(start
)
{
printf("osc_fpga_init didn't work, retval = %d",start
);
return -1;
}
// set acquisition parameters
osc_fpga_set_trigger_delay
(delay
);
g_osc_fpga_reg_mem
->data_dec
= decimation
;
osc_fpga_reset
();
g_osc_fpga_reg_mem
->chb_thr
= osc_fpga_cnv_v_to_cnt
(threshold_voltage
); //sets trigger voltage
#endif
fprintf(stderr
, "%s : %d\n", __FILE__
, __LINE__
);
return 0;
}
int daq_end
() {
#ifdef DEBUG
fprintf (stderr
, "Server: end\n");
#endif
#ifdef MRP
rp_Release
();
#else
osc_fpga_exit
();
#endif
return 0;
}
int daq_clear
() {
#ifdef DEBUG
fprintf (stderr
, "Server: clear\n");
#endif
return 0;
}
int16_t chdata
[16*1024];
float * chfdata
= (float *) chdata
;
int daq_run
(const char *par
, char ** data
, int *maxlen
)
{
int *data_buf
;
int neve
;
unsigned short *sbuff
= (unsigned short *) (par
);
unsigned short maxeve
= sbuff
[0];
unsigned short nsamples
= sbuff
[1];
unsigned short tout
= sbuff
[2];
unsigned char trigger
= par
[6];
unsigned char chmask
= par
[7];
clock_t t
,t0
;
neve
= 0;
t0
=clock();
int eventsize
= 0;
if (chmask
& 0x1) eventsize
+= (nsamples
+2);
if (chmask
& 0x2) eventsize
+= (nsamples
+2);
eventsize
+=4;
int required_size
= eventsize
* maxeve
+3;
#ifdef DEBUG
time_t mtime
;
time(&mtime
);
fprintf (stderr
, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s", maxeve
,nsamples
,tout
,trigger
,chmask
, ctime(&mtime
)); //
#endif
if (required_size
> *maxlen
) {
free (*data
);
*data
= (char *) malloc(required_size
*sizeof(int));
fprintf(stderr
, "New Buffer with size %d allocated. Old size %d\n", required_size
, *maxlen
);
*maxlen
= required_size
;
}
int *ibuf
= (int *) (*data
);
data_buf
= ibuf
+ 3;
const int sleeptime
= 135*nsamples
/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/
for (int ieve
=0; ieve
< maxeve
; ieve
++)
{
#ifdef MRP
rp_AcqStart
();
usleep
(sleeptime
);
rp_AcqSetTriggerSrc
(trigger
);
timer_out
= FALSE
;
tmlnk
(tout
);
rp_acq_trig_src_t source
;
do {
rp_AcqGetTriggerSrc
(&source
);
//printf("TRG %d src %d\n", trigger, source);
if (timer_out
|| ctrl_c
) break;
} while (source
== trigger
);
tmulk
();
usleep
(sleeptime
);
#else
osc_fpga_arm_trigger
();
usleep
(sleeptime
);
osc_fpga_set_trigger
(trigger
);
while (g_osc_fpga_reg_mem
->trig_source
!= 0){
if (timer_out
|| ctrl_c
) break;
}
// with this loop the program waits until the acquistion is completed before continue.
int trig_ptr
= g_osc_fpga_reg_mem
->wr_ptr_trigger
; // get pointer to mem. adress where trigger was met
int * ch_signal
[2];
osc_fpga_get_sig_ptr
(&ch_signal
[0], &ch_signal
[1]);
#endif
*(data_buf
++) = 0x2;
*(data_buf
++) = chmask
;
for (int id
= 0;id
<2;id
++){
if ( !(chmask
& (1 << id
)) ) continue;
*(data_buf
++) = id
;
*(data_buf
++) = nsamples
;
#ifdef MRP
const int c
[2] = {RP_CH_1
, RP_CH_2
};
unsigned int isamples
= nsamples
;
rp_AcqGetLatestDataV
(c
[id
], &isamples
, (float *) data_buf
);
data_buf
+=nsamples
;
#else
const int BUF
= 16*1024;
const int offset
= 0;
if (trig_ptr
> (BUF
-nsamples
)) // Enter logic to transition from end to beginning of cha_signal buffer.
{
for (int i
=trig_ptr
;i
<BUF
;i
++) *(data_buf
++) = ch_signal
[id
][i
]-offset
;
for (int i
=0;i
<nsamples
-(BUF
-trig_ptr
);i
++) *(data_buf
++) = ch_signal
[id
][i
]-offset
;
}
else // Enter simple logic to send sampleSize from trigger point
{
for (int i
=0;i
<nsamples
;i
++) *(data_buf
++) = ch_signal
[id
][trig_ptr
+ i
]-offset
;
}
#endif
}
*(data_buf
++) = 0x3;
*(data_buf
++) = neve
;
neve
++;
if (ieve
+1 % 500 == 0) fprintf(stderr
, "Event %d\n", ieve
);
if (timer_out
) break;
}
int *len
= ibuf
;
int *nev
= ibuf
+ 1;
float *dt
= (float *)(ibuf
+ 2);
*len
= (data_buf
-len
)*sizeof(int);
*nev
= neve
;
t
= clock();
*dt
= t
-t0
;
*dt
/= CLOCKS_PER_SEC
;
return *len
;
}
#define MAXLEN 0XFFFF
struct RUNHDR
{
unsigned short neve
;
unsigned short nsamples
;
unsigned short tout
;
unsigned char trigger
;
unsigned char mask
;
int nloops
;
int data
[MAXLEN
];
} ;
struct INIHDR
{
int delay
;
int decimation
;
int threshold
;
};
int daq_help
(char *fname
, struct INIHDR
* i
, struct RUNHDR
*r
, int verbosity
){
printf("-o filename ... output filename %s\n", fname
);
printf("-v verbose ... verbosity %d\n", verbosity
);
printf("-b decimation ... decimation %d\n", i
->decimation
);
printf("-i timeout ... interrupt timeout %d\n", r
->tout
);
printf("-s nsamples ... number of samples %d\n", r
->nsamples
);
printf("-d delay ... delay %d\n", i
->delay
);
printf("-t trigger ... trigger type %d\n", r
->trigger
);
printf("-l level ... trigger level %f\n", i
->threshold
*0.001);
printf("-m mask ... channel mask %d\n", r
->mask
);
printf("-n neve ... number of events per call %d\n", r
->neve
);
printf("-r nloops ... number of calls %d\n", r
->nloops
);
return 0;
}
int daq_main
( int argc
, char ** argv
) {
// intercept routine
if (signal
(SIGINT
, SigInt
) == SIG_ERR
) {
perror ("sigignore");
}
char filename
[0xFF]="";
struct INIHDR inihdr
= {
.
decimation = 1,
.
threshold = 100,
.
delay = 1024
};
struct RUNHDR runhdr
;
runhdr.
neve =10000;
runhdr.
nsamples = 1024;
runhdr.
tout = 1000;
runhdr.
trigger = 1;
runhdr.
mask = 0x1;
runhdr.
nloops = 1;
int verbose
= 0;
int argdata
= 0;
if (argc
<2) {
daq_help
(filename
, &inihdr
, &runhdr
, verbose
);
exit(-1);
}
opterr
= 0;
int c
;
while ((c
= getopt
(argc
, argv
, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1)
switch (c
) {
case 'o':
sprintf(filename
,"%s", optarg
);
break; // output
case 'v':
verbose
= strtoul (optarg
,NULL
,0);
break; // verbosity
case 'b':
inihdr.
decimation = strtoul (optarg
,NULL
,0);
break;
case 'i':
runhdr.
tout = strtoul (optarg
,NULL
,0);
break;
case 's':
runhdr.
nsamples = strtoul (optarg
,NULL
,0);
break;
case 'd':
inihdr.
delay = strtoul (optarg
,NULL
,0);
break;
case 't':
runhdr.
trigger = strtoul (optarg
,NULL
,0);
break;
case 'm':
runhdr.
mask = strtoul (optarg
,NULL
,0);
break;
case 'n':
runhdr.
neve = atoi (optarg
);
break;
case 'r':
runhdr.
nloops = atoi (optarg
);
break;
case 'l':
inihdr.
threshold = (int) (1000*atof (optarg
));
break;
case 'h':
daq_help
(filename
, &inihdr
, &runhdr
, verbose
);
break;
case '?':
if (optopt
== 'c')
fprintf (stderr
, "Option -%c requires an argument.\n", optopt
);
else if (isprint (optopt
))
fprintf (stderr
, "Unknown option `-%c'.\n", optopt
);
else
fprintf (stderr
,
"Unknown option character `\\x%x'.\n",
optopt
);
return 1;
default:
abort ();
}
for (int i
=optind
; i
<argc
; i
++) argdata
= strtoul (argv
[i
],NULL
,0);
if (verbose
) daq_help
(filename
, &inihdr
, &runhdr
, verbose
);
printf("argdata %d nloops %d\n",argdata
,runhdr.
nloops);
daq_init
((char *)&inihdr
);
FILE
*fp
=NULL
;
if (strlen(filename
)>0) fp
= fopen(filename
, "wb");
int maxlen
= MAXLEN
;
char *data
= (char *) malloc(maxlen
* sizeof(int));
time_t t
,tstart
;
time(&tstart
);
for (int i
=0;i
< runhdr.
nloops;i
++){
int nb
=daq_run
((const char*) &runhdr
, &data
, &maxlen
);
if (ctrl_c
) break;
time(&t
);
fprintf(stderr
, "Loop %d dt=%d s\n", i
, (int)(t
-tstart
));
if (fp
) {
fprintf(stderr
, "Writing %d to %s", nb
, filename
);
fwrite(data
, 1, nb
, fp
);
}
}
time(&t
);
fprintf(stderr
, "Total events %d in %d s\n", runhdr.
nloops*runhdr.
neve, (int)(t
-tstart
));
if (fp
) fclose(fp
);
if (data
!=NULL
) free(data
);
return 0;
}