#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; {
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)
{
}
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)
{
}
}
#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
#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;
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;
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 ) {
*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;
*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) {
}
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);
}
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':
break; // output
case 'v':
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
);
fprintf (stderr
, "Unknown option `-%c'.\n", optopt
);
else
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
}
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;
int maxlen = MAXLEN;
char *data
= (char *) malloc(maxlen
* sizeof(int));
time_t t,tstart;
for (int i=0;i< runhdr.nloops;i++){
int nb =daq_run((const char*) &runhdr, &data, &maxlen);
if (ctrl_c) break;
fprintf(stderr
, "Loop %d dt=%d s\n", i
, (int)(t
-tstart
));
if (fp) {
fprintf(stderr
, "Writing %d to %s", nb
, filename
);
}
}
fprintf(stderr
, "Total events %d in %d s\n", runhdr.
nloops*runhdr.
neve, (int)(t
-tstart
));
if (data
!=NULL
) free(data
);
return 0;
}