Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
360 | f9daq | 1 | #include <stdlib.h> |
2 | #include <stdio.h> |
||
3 | #include <signal.h> |
||
4 | #include <time.h> |
||
5 | #include <string.h> |
||
6 | #include <sys/types.h> |
||
7 | #include <sys/time.h> |
||
8 | #include <ctype.h> |
||
9 | #include <unistd.h> |
||
10 | |||
11 | #ifdef MRP |
||
12 | #include <rp.h> |
||
13 | #else |
||
14 | #include "calib.h" |
||
15 | #endif |
||
16 | |||
17 | #include "fpga_osc.h" |
||
18 | |||
19 | #define TRUE -1 |
||
20 | #define FALSE 0 |
||
21 | |||
22 | int timer_out; struct sigaction oact; |
||
23 | |||
24 | int ctrl_c=0; |
||
25 | |||
26 | void SigInt (int sig) { |
||
27 | ctrl_c = 1; |
||
28 | } |
||
29 | |||
30 | |||
31 | void timerast (signumber, code, context) int signumber, code; struct sigcontext context; { |
||
32 | fprintf(stderr, "Timeout\n"); |
||
33 | timer_out = TRUE; |
||
34 | } |
||
35 | |||
36 | void tmlnk (tout) int tout; { |
||
37 | struct sigaction act; |
||
38 | struct itimerval tdelay; |
||
39 | |||
40 | act.sa_handler = timerast; |
||
41 | sigemptyset (&act.sa_mask); |
||
42 | act.sa_flags = 0; |
||
43 | |||
44 | tdelay.it_value.tv_sec = tout / 100; |
||
45 | tdelay.it_value.tv_usec = 10000 * (tout % 100); |
||
46 | tdelay.it_interval.tv_sec = 0; |
||
47 | tdelay.it_interval.tv_usec = 0; |
||
48 | |||
49 | if (sigaction (SIGALRM, &act, &oact) < 0) |
||
50 | { |
||
51 | perror ("sigaction(tmlnk)"); |
||
52 | exit (EXIT_FAILURE); |
||
53 | } |
||
54 | if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) |
||
55 | { |
||
56 | perror ("setitimer(tmlnk)"); |
||
57 | exit (EXIT_FAILURE); |
||
58 | } |
||
59 | } |
||
60 | |||
61 | void tmulk () { |
||
62 | struct itimerval tdelay; |
||
63 | |||
64 | tdelay.it_value.tv_sec = 0; |
||
65 | tdelay.it_value.tv_usec = 0; |
||
66 | tdelay.it_interval.tv_sec = 0; |
||
67 | tdelay.it_interval.tv_usec = 0; |
||
68 | |||
69 | if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) |
||
70 | { |
||
71 | perror ("setitimer(tmulk)"); |
||
72 | exit (EXIT_FAILURE); |
||
73 | } |
||
74 | if (sigaction (SIGALRM, &oact, NULL) < 0) |
||
75 | { |
||
76 | perror ("sigaction(tmulk)"); |
||
77 | exit (EXIT_FAILURE); |
||
78 | } |
||
79 | } |
||
80 | |||
81 | #ifndef MRP |
||
82 | rp_calib_params_t rp_calib_params; /** Pointer to externally defined calibration parameters. */ rp_calib_params_t *gen_calib_params = NULL; |
||
83 | #endif |
||
84 | int daq_init (char * buff) { |
||
85 | #ifdef DEBUG |
||
86 | fprintf (stderr, "Server: init\n"); |
||
87 | #endif |
||
88 | int * hdr = (int *) buff; |
||
89 | int delay = hdr[0]; |
||
90 | int decimation = hdr[1]; |
||
91 | float threshold_voltage = hdr[2]/1000.; |
||
92 | fprintf(stderr, "delay = %d\tdecimation = %d\tthreshold = %f\n", delay, decimation, threshold_voltage); |
||
93 | |||
94 | /* |
||
95 | |||
96 | rp_default_calib_params(&rp_calib_params); |
||
97 | gen_calib_params = &rp_calib_params; |
||
98 | if(rp_read_calib_params(gen_calib_params) < 0) { |
||
99 | fprintf(stderr, "rp_read_calib_params() failed, using default" |
||
100 | " parameters\n"); |
||
101 | } |
||
102 | |||
103 | */ |
||
104 | |||
105 | // use this to acquire calibrated offset: int offset = gen_calib_params->fe_ch1_dc_offs; |
||
106 | #ifdef MRP |
||
107 | if(rp_Init() != RP_OK){ |
||
108 | fprintf(stderr, "Rp api init failed!\n"); |
||
109 | } |
||
110 | rp_AcqReset(); |
||
111 | const int rpdecimation[6]={RP_DEC_1 ,RP_DEC_8 ,RP_DEC_64, |
||
112 | RP_DEC_1024 ,RP_DEC_8192 ,RP_DEC_65536 }; |
||
113 | rp_AcqSetDecimation(rpdecimation[decimation%6]); |
||
114 | const int c[2] = {RP_CH_1, RP_CH_2}; |
||
115 | rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI |
||
116 | rp_AcqSetTriggerLevel(c[1],threshold_voltage); |
||
117 | rp_AcqSetTriggerDelay(delay); |
||
118 | return 0; |
||
119 | #else |
||
120 | // initialization |
||
121 | int start = osc_fpga_init(); |
||
122 | if(start) |
||
123 | { |
||
124 | printf("osc_fpga_init didn't work, retval = %d",start); |
||
125 | return -1; |
||
126 | } |
||
127 | |||
128 | // set acquisition parameters |
||
129 | osc_fpga_set_trigger_delay(delay); |
||
130 | g_osc_fpga_reg_mem->data_dec = decimation; |
||
131 | osc_fpga_reset(); |
||
132 | g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage |
||
133 | #endif |
||
134 | fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); |
||
135 | return 0; |
||
136 | } |
||
137 | |||
138 | int daq_end () { |
||
139 | #ifdef DEBUG |
||
140 | fprintf (stderr, "Server: end\n"); |
||
141 | #endif |
||
142 | #ifdef MRP |
||
143 | rp_Release(); |
||
144 | #else |
||
145 | osc_fpga_exit(); |
||
146 | #endif |
||
147 | return 0; |
||
148 | } |
||
149 | |||
150 | int daq_clear () { |
||
151 | #ifdef DEBUG |
||
152 | fprintf (stderr, "Server: clear\n"); |
||
153 | #endif |
||
154 | return 0; |
||
155 | } |
||
156 | |||
157 | |||
158 | int16_t chdata[16*1024]; |
||
159 | float * chfdata = (float *) chdata; |
||
160 | int daq_run (const char *par, char ** data, int *maxlen) |
||
161 | |||
162 | { |
||
163 | |||
164 | int *data_buf; |
||
165 | int neve; |
||
166 | |||
167 | unsigned short *sbuff = (unsigned short *) (par); |
||
168 | unsigned short maxeve = sbuff[0]; |
||
169 | unsigned short nsamples = sbuff[1]; |
||
170 | unsigned short tout = sbuff[2]; |
||
171 | unsigned char trigger = par[6]; |
||
172 | unsigned char chmask = par[7]; |
||
173 | clock_t t,t0; |
||
174 | neve = 0; |
||
175 | |||
176 | t0=clock(); |
||
177 | int eventsize = 0; |
||
178 | if (chmask & 0x1) eventsize += (nsamples+2); |
||
179 | if (chmask & 0x2) eventsize += (nsamples+2); |
||
180 | eventsize+=4; |
||
181 | int required_size = eventsize * maxeve+3; |
||
182 | |||
183 | #ifdef DEBUG |
||
184 | time_t mtime; |
||
185 | time(&mtime); |
||
186 | fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s", maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); // |
||
187 | #endif |
||
188 | |||
189 | |||
190 | if (required_size > *maxlen ) { |
||
191 | free (*data); |
||
192 | *data = (char *) malloc(required_size *sizeof(int)); |
||
193 | fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen); |
||
194 | *maxlen = required_size; |
||
195 | } |
||
196 | |||
197 | int *ibuf = (int *) (*data); |
||
198 | |||
199 | |||
200 | data_buf = ibuf + 3; |
||
201 | const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/ |
||
202 | |||
203 | for (int ieve=0; ieve < maxeve; ieve++) |
||
204 | { |
||
205 | |||
206 | #ifdef MRP |
||
207 | |||
208 | rp_AcqStart(); |
||
209 | usleep(sleeptime); |
||
210 | rp_AcqSetTriggerSrc(trigger); |
||
211 | timer_out = FALSE; |
||
212 | tmlnk (tout); |
||
213 | rp_acq_trig_src_t source; |
||
214 | do { |
||
215 | rp_AcqGetTriggerSrc(&source); |
||
216 | //printf("TRG %d src %d\n", trigger, source); |
||
217 | if (timer_out || ctrl_c) break; |
||
218 | } while (source == trigger); |
||
219 | |||
220 | tmulk (); |
||
221 | usleep(sleeptime); |
||
222 | |||
223 | |||
224 | #else |
||
225 | |||
226 | osc_fpga_arm_trigger(); |
||
227 | usleep(sleeptime); |
||
228 | osc_fpga_set_trigger(trigger); |
||
229 | |||
230 | while (g_osc_fpga_reg_mem->trig_source != 0){ |
||
231 | if (timer_out || ctrl_c) break; |
||
232 | } |
||
233 | // with this loop the program waits until the acquistion is completed before continue. |
||
234 | int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met |
||
235 | int * ch_signal[2]; |
||
236 | osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]); |
||
237 | #endif |
||
238 | *(data_buf++) = 0x2; |
||
239 | *(data_buf++) = chmask; |
||
240 | |||
241 | for (int id = 0;id<2;id++){ |
||
242 | if ( !(chmask & (1 << id)) ) continue; |
||
243 | |||
244 | *(data_buf++) = id; |
||
245 | *(data_buf++) = nsamples; |
||
246 | #ifdef MRP |
||
247 | const int c[2] = {RP_CH_1, RP_CH_2}; |
||
248 | unsigned int isamples = nsamples; |
||
249 | rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf ); |
||
250 | data_buf+=nsamples; |
||
251 | #else |
||
252 | |||
253 | const int BUF = 16*1024; |
||
254 | const int offset = 0; |
||
255 | if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer. |
||
256 | { |
||
257 | for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset; |
||
258 | for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset; |
||
259 | } |
||
260 | else // Enter simple logic to send sampleSize from trigger point |
||
261 | { |
||
262 | for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset; |
||
263 | } |
||
264 | #endif |
||
265 | } |
||
266 | *(data_buf++) = 0x3; |
||
267 | *(data_buf++) = neve; |
||
268 | neve++; |
||
269 | if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve); |
||
270 | if (timer_out) break; |
||
271 | |||
272 | } |
||
273 | |||
274 | |||
275 | |||
276 | int *len = ibuf; |
||
277 | int *nev = ibuf + 1; |
||
278 | float *dt = (float *)(ibuf + 2); |
||
279 | |||
280 | *len = (data_buf-len)*sizeof(int); |
||
281 | *nev = neve; |
||
282 | t = clock(); |
||
283 | *dt = t-t0; |
||
284 | *dt /= CLOCKS_PER_SEC; |
||
285 | |||
286 | return *len; |
||
287 | } |
||
288 | |||
289 | #define MAXLEN 0XFFFF |
||
290 | struct RUNHDR { |
||
291 | unsigned short neve; |
||
292 | unsigned short nsamples; |
||
293 | unsigned short tout; |
||
294 | unsigned char trigger; |
||
295 | unsigned char mask; |
||
296 | int nloops ; |
||
297 | int data [MAXLEN]; |
||
298 | } ; |
||
299 | |||
300 | |||
301 | struct INIHDR { |
||
302 | int delay ; |
||
303 | int decimation; |
||
304 | int threshold; |
||
305 | }; |
||
306 | |||
307 | |||
308 | int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){ |
||
309 | |||
310 | printf("-o filename ... output filename %s\n", fname); |
||
311 | printf("-v verbose ... verbosity %d\n", verbosity); |
||
312 | printf("-b decimation ... decimation %d\n", i->decimation); |
||
313 | printf("-i timeout ... interrupt timeout %d\n", r->tout); |
||
314 | printf("-s nsamples ... number of samples %d\n", r->nsamples); |
||
315 | printf("-d delay ... delay %d\n", i->delay); |
||
316 | printf("-t trigger ... trigger type %d\n", r->trigger); |
||
317 | printf("-l level ... trigger level %f\n", i->threshold*0.001); |
||
318 | printf("-m mask ... channel mask %d\n", r->mask ); |
||
319 | printf("-n neve ... number of events per call %d\n", r->neve); |
||
320 | printf("-r nloops ... number of calls %d\n", r->nloops); |
||
321 | return 0; |
||
322 | } |
||
323 | |||
324 | |||
325 | |||
326 | int daq_main( int argc , char ** argv) { |
||
327 | // intercept routine |
||
328 | if (signal (SIGINT, SigInt) == SIG_ERR) { |
||
329 | perror ("sigignore"); |
||
330 | } |
||
331 | |||
332 | |||
333 | char filename[0xFF]=""; |
||
334 | |||
335 | |||
336 | struct INIHDR inihdr = { |
||
337 | .decimation = 1, |
||
338 | .threshold = 100, |
||
339 | .delay = 1024 |
||
340 | }; |
||
341 | |||
342 | |||
343 | |||
344 | struct RUNHDR runhdr; |
||
345 | |||
346 | |||
347 | runhdr.neve =10000; |
||
348 | runhdr.nsamples = 1024; |
||
349 | runhdr.tout = 1000; |
||
350 | runhdr.trigger = 1; |
||
351 | runhdr.mask = 0x1; |
||
352 | runhdr.nloops = 1; |
||
353 | |||
354 | int verbose = 0; |
||
355 | int argdata = 0; |
||
356 | |||
357 | if (argc <2) { |
||
358 | daq_help(filename, &inihdr, &runhdr, verbose); |
||
359 | exit(-1); |
||
360 | } |
||
361 | |||
362 | opterr = 0; |
||
363 | int c; |
||
364 | while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1) |
||
365 | switch (c) { |
||
366 | case 'o': |
||
367 | sprintf(filename,"%s", optarg ); |
||
368 | break; // output |
||
369 | case 'v': |
||
370 | verbose = strtoul (optarg,NULL,0); |
||
371 | break; // verbosity |
||
372 | case 'b': |
||
373 | inihdr.decimation = strtoul (optarg,NULL,0); |
||
374 | break; |
||
375 | case 'i': |
||
376 | runhdr.tout = strtoul (optarg,NULL,0); |
||
377 | break; |
||
378 | case 's': |
||
379 | runhdr.nsamples = strtoul (optarg,NULL,0); |
||
380 | break; |
||
381 | case 'd': |
||
382 | inihdr.delay = strtoul (optarg,NULL,0); |
||
383 | break; |
||
384 | case 't': |
||
385 | runhdr.trigger = strtoul (optarg,NULL,0); |
||
386 | break; |
||
387 | case 'm': |
||
388 | runhdr.mask = strtoul (optarg,NULL,0); |
||
389 | break; |
||
390 | case 'n': |
||
391 | runhdr.neve = atoi (optarg); |
||
392 | break; |
||
393 | case 'r': |
||
394 | runhdr.nloops = atoi (optarg); |
||
395 | break; |
||
396 | case 'l': |
||
397 | inihdr.threshold = (int) (1000*atof (optarg)); |
||
398 | break; |
||
399 | case 'h': |
||
400 | daq_help(filename, &inihdr, &runhdr, verbose); |
||
401 | break; |
||
402 | case '?': |
||
403 | if (optopt == 'c') |
||
404 | fprintf (stderr, "Option -%c requires an argument.\n", optopt); |
||
405 | else if (isprint (optopt)) |
||
406 | fprintf (stderr, "Unknown option `-%c'.\n", optopt); |
||
407 | else |
||
408 | fprintf (stderr, |
||
409 | "Unknown option character `\\x%x'.\n", |
||
410 | optopt); |
||
411 | return 1; |
||
412 | default: |
||
413 | abort (); |
||
414 | } |
||
415 | for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0); |
||
416 | if (verbose) daq_help(filename, &inihdr, &runhdr, verbose); |
||
417 | |||
418 | printf("argdata %d nloops %d\n",argdata,runhdr.nloops); |
||
419 | |||
420 | daq_init((char *)&inihdr); |
||
421 | FILE *fp=NULL; |
||
422 | if (strlen(filename)>0) fp = fopen(filename, "wb"); |
||
423 | |||
424 | |||
425 | int maxlen = MAXLEN; |
||
426 | char *data = (char *) malloc(maxlen * sizeof(int)); |
||
427 | time_t t,tstart; |
||
428 | time(&tstart); |
||
429 | |||
430 | for (int i=0;i< runhdr.nloops;i++){ |
||
431 | int nb =daq_run((const char*) &runhdr, &data, &maxlen); |
||
432 | if (ctrl_c) break; |
||
433 | time(&t); |
||
434 | fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart)); |
||
435 | |||
436 | if (fp) { |
||
437 | fprintf(stderr, "Writing %d to %s", nb, filename); |
||
438 | fwrite(data, 1, nb, fp); |
||
439 | } |
||
440 | |||
441 | } |
||
442 | time(&t); |
||
443 | fprintf(stderr, "Total events %d in %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart)); |
||
444 | if (fp) fclose(fp); |
||
445 | if (data!=NULL) free(data); |
||
446 | return 0; |
||
447 | } |