Rev 231 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
228 | 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 "redpitaya/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; { |
||
231 | f9daq | 32 | fprintf(stderr, "Timeout\n"); |
228 | f9daq | 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 |
||
231 | f9daq | 84 | int daq_init (char * buff) { |
228 | f9daq | 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 | rp_AcqSetDecimation(decimation); |
||
112 | const int c[2] = {RP_CH_1, RP_CH_2}; |
||
113 | rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI |
||
114 | rp_AcqSetTriggerLevel(c[1],threshold_voltage); |
||
115 | rp_AcqSetTriggerDelay(delay); |
||
116 | return 0; |
||
117 | #else |
||
118 | // initialization |
||
119 | int start = osc_fpga_init(); |
||
120 | if(start) |
||
121 | { |
||
122 | printf("osc_fpga_init didn't work, retval = %d",start); |
||
123 | return -1; |
||
124 | } |
||
125 | |||
126 | // set acquisition parameters |
||
127 | osc_fpga_set_trigger_delay(delay); |
||
128 | g_osc_fpga_reg_mem->data_dec = decimation; |
||
129 | osc_fpga_reset(); |
||
130 | g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage |
||
131 | #endif |
||
132 | fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); |
||
133 | return 0; |
||
134 | } |
||
135 | |||
136 | int daq_end () { |
||
137 | #ifdef DEBUG |
||
138 | fprintf (stderr, "Server: end\n"); |
||
139 | #endif |
||
140 | #ifdef MRP |
||
141 | rp_Release(); |
||
142 | #else |
||
143 | osc_fpga_exit(); |
||
144 | #endif |
||
145 | return 0; |
||
146 | } |
||
147 | |||
148 | int daq_clear () { |
||
149 | #ifdef DEBUG |
||
150 | fprintf (stderr, "Server: clear\n"); |
||
151 | #endif |
||
152 | return 0; |
||
153 | } |
||
154 | |||
231 | f9daq | 155 | |
156 | int16_t chdata[16*1024]; |
||
232 | f9daq | 157 | float * chfdata = (float *) chdata; |
228 | f9daq | 158 | int daq_run (const char *par, char ** data, int *maxlen) |
159 | |||
160 | { |
||
161 | |||
162 | int *data_buf; |
||
163 | int neve; |
||
164 | |||
231 | f9daq | 165 | unsigned short *sbuff = (unsigned short *) (par); |
228 | f9daq | 166 | unsigned short maxeve = sbuff[0]; |
167 | unsigned short nsamples = sbuff[1]; |
||
168 | unsigned short tout = sbuff[2]; |
||
231 | f9daq | 169 | unsigned char trigger = par[6]; |
170 | unsigned char chmask = par[7]; |
||
232 | f9daq | 171 | clock_t t,t0; |
172 | neve = 0; |
||
228 | f9daq | 173 | |
232 | f9daq | 174 | t0=clock(); |
228 | f9daq | 175 | int eventsize = 0; |
176 | if (chmask & 0x1) eventsize += (nsamples+2); |
||
177 | if (chmask & 0x2) eventsize += (nsamples+2); |
||
178 | eventsize+=4; |
||
179 | int required_size = eventsize * maxeve+3; |
||
180 | |||
181 | #ifdef DEBUG |
||
232 | f9daq | 182 | time_t mtime; |
183 | time(&mtime); |
||
184 | fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s", maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); // |
||
228 | f9daq | 185 | #endif |
186 | |||
187 | |||
188 | if (required_size > *maxlen ) { |
||
189 | free (*data); |
||
190 | *data = (char *) malloc(required_size *sizeof(int)); |
||
191 | fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen); |
||
192 | *maxlen = required_size; |
||
193 | } |
||
194 | |||
195 | int *ibuf = (int *) (*data); |
||
196 | |||
197 | |||
198 | data_buf = ibuf + 3; |
||
199 | const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/ |
||
200 | |||
201 | for (int ieve=0; ieve < maxeve; ieve++) |
||
202 | { |
||
203 | |||
204 | #ifdef MRP |
||
205 | |||
206 | rp_AcqStart(); |
||
207 | usleep(sleeptime); |
||
208 | rp_AcqSetTriggerSrc(trigger); |
||
231 | f9daq | 209 | timer_out = FALSE; |
210 | tmlnk (tout); |
||
211 | rp_acq_trig_src_t source; |
||
212 | do { |
||
213 | rp_AcqGetTriggerSrc(&source); |
||
214 | //printf("TRG %d src %d\n", trigger, source); |
||
215 | if (timer_out || ctrl_c) break; |
||
216 | } while (source == trigger); |
||
217 | |||
218 | tmulk (); |
||
219 | usleep(sleeptime); |
||
220 | |||
228 | f9daq | 221 | |
222 | #else |
||
223 | |||
224 | osc_fpga_arm_trigger(); |
||
225 | usleep(sleeptime); |
||
226 | osc_fpga_set_trigger(trigger); |
||
227 | |||
231 | f9daq | 228 | while (g_osc_fpga_reg_mem->trig_source != 0){ |
229 | if (timer_out || ctrl_c) break; |
||
230 | } |
||
228 | f9daq | 231 | // with this loop the program waits until the acquistion is completed before continue. |
232 | int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met |
||
233 | int * ch_signal[2]; |
||
234 | osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]); |
||
235 | #endif |
||
236 | *(data_buf++) = 0x2; |
||
237 | *(data_buf++) = chmask; |
||
238 | |||
239 | for (int id = 0;id<2;id++){ |
||
240 | if ( !(chmask & (1 << id)) ) continue; |
||
241 | |||
242 | *(data_buf++) = id; |
||
243 | *(data_buf++) = nsamples; |
||
244 | #ifdef MRP |
||
245 | const int c[2] = {RP_CH_1, RP_CH_2}; |
||
246 | unsigned int isamples = nsamples; |
||
232 | f9daq | 247 | rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf ); |
248 | data_buf+=nsamples; |
||
228 | f9daq | 249 | #else |
250 | |||
251 | const int BUF = 16*1024; |
||
252 | const int offset = 0; |
||
253 | if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer. |
||
254 | { |
||
255 | for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset; |
||
256 | for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset; |
||
257 | } |
||
258 | else // Enter simple logic to send sampleSize from trigger point |
||
259 | { |
||
260 | for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset; |
||
261 | } |
||
262 | #endif |
||
263 | } |
||
264 | *(data_buf++) = 0x3; |
||
265 | *(data_buf++) = neve; |
||
266 | neve++; |
||
231 | f9daq | 267 | if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve); |
228 | f9daq | 268 | if (timer_out) break; |
269 | |||
270 | } |
||
271 | |||
231 | f9daq | 272 | |
228 | f9daq | 273 | |
274 | int *len = ibuf; |
||
275 | int *nev = ibuf + 1; |
||
232 | f9daq | 276 | float *dt = (float *)(ibuf + 2); |
228 | f9daq | 277 | |
278 | *len = (data_buf-len)*sizeof(int); |
||
279 | *nev = neve; |
||
232 | f9daq | 280 | t = clock(); |
281 | *dt = t-t0; |
||
282 | *dt /= CLOCKS_PER_SEC; |
||
228 | f9daq | 283 | |
284 | return *len; |
||
285 | } |
||
286 | |||
287 | #define MAXLEN 0XFFFF |
||
288 | struct RUNHDR { |
||
289 | unsigned short neve; |
||
290 | unsigned short nsamples; |
||
291 | unsigned short tout; |
||
292 | unsigned char trigger; |
||
293 | unsigned char mask; |
||
294 | int nloops ; |
||
295 | int data [MAXLEN]; |
||
296 | } ; |
||
297 | |||
298 | |||
299 | struct INIHDR { |
||
300 | int delay ; |
||
301 | int decimation; |
||
302 | int threshold; |
||
303 | }; |
||
304 | |||
305 | |||
306 | int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){ |
||
307 | |||
308 | printf("-o filename ... output filename %s\n", fname); |
||
309 | printf("-v verbose ... verbosity %d\n", verbosity); |
||
310 | printf("-b decimation ... decimation %d\n", i->decimation); |
||
311 | printf("-i timeout ... interrupt timeout %d\n", r->tout); |
||
312 | printf("-s nsamples ... number of samples %d\n", r->nsamples); |
||
313 | printf("-d delay ... delay %d\n", i->delay); |
||
314 | printf("-t trigger ... trigger type %d\n", r->trigger); |
||
315 | printf("-l level ... trigger level %f\n", i->threshold*0.001); |
||
316 | printf("-m mask ... channel mask %d\n", r->mask ); |
||
317 | printf("-n neve ... number of events per call %d\n", r->neve); |
||
318 | printf("-r nloops ... number of calls %d\n", r->nloops); |
||
319 | return 0; |
||
320 | } |
||
321 | |||
322 | |||
323 | |||
324 | int daq_main( int argc , char ** argv) { |
||
325 | // intercept routine |
||
326 | if (signal (SIGINT, SigInt) == SIG_ERR) { |
||
327 | perror ("sigignore"); |
||
328 | } |
||
329 | |||
330 | |||
331 | char filename[0xFF]=""; |
||
332 | |||
333 | |||
334 | struct INIHDR inihdr = { |
||
335 | .decimation = 1, |
||
336 | .threshold = 100, |
||
337 | .delay = 1024 |
||
338 | }; |
||
339 | |||
340 | |||
341 | |||
342 | struct RUNHDR runhdr; |
||
343 | |||
344 | |||
345 | runhdr.neve =10000; |
||
346 | runhdr.nsamples = 1024; |
||
347 | runhdr.tout = 1000; |
||
348 | runhdr.trigger = 1; |
||
349 | runhdr.mask = 0x1; |
||
350 | runhdr.nloops = 1; |
||
351 | |||
352 | int verbose = 0; |
||
353 | int argdata = 0; |
||
354 | |||
355 | if (argc <2) { |
||
356 | daq_help(filename, &inihdr, &runhdr, verbose); |
||
357 | exit(-1); |
||
358 | } |
||
359 | |||
360 | opterr = 0; |
||
361 | int c; |
||
362 | while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1) |
||
363 | switch (c) { |
||
364 | case 'o': |
||
365 | sprintf(filename,"%s", optarg ); |
||
366 | break; // output |
||
367 | case 'v': |
||
368 | verbose = strtoul (optarg,NULL,0); |
||
369 | break; // verbosity |
||
370 | case 'b': |
||
371 | inihdr.decimation = strtoul (optarg,NULL,0); |
||
372 | break; |
||
373 | case 'i': |
||
374 | runhdr.tout = strtoul (optarg,NULL,0); |
||
375 | break; |
||
376 | case 's': |
||
377 | runhdr.nsamples = strtoul (optarg,NULL,0); |
||
378 | break; |
||
379 | case 'd': |
||
380 | inihdr.delay = strtoul (optarg,NULL,0); |
||
381 | break; |
||
382 | case 't': |
||
383 | runhdr.trigger = strtoul (optarg,NULL,0); |
||
384 | break; |
||
385 | case 'm': |
||
386 | runhdr.mask = strtoul (optarg,NULL,0); |
||
387 | break; |
||
388 | case 'n': |
||
389 | runhdr.neve = atoi (optarg); |
||
390 | break; |
||
391 | case 'r': |
||
392 | runhdr.nloops = atoi (optarg); |
||
393 | break; |
||
394 | case 'l': |
||
395 | inihdr.threshold = (int) (1000*atof (optarg)); |
||
396 | break; |
||
397 | case 'h': |
||
398 | daq_help(filename, &inihdr, &runhdr, verbose); |
||
399 | break; |
||
400 | case '?': |
||
401 | if (optopt == 'c') |
||
402 | fprintf (stderr, "Option -%c requires an argument.\n", optopt); |
||
403 | else if (isprint (optopt)) |
||
404 | fprintf (stderr, "Unknown option `-%c'.\n", optopt); |
||
405 | else |
||
406 | fprintf (stderr, |
||
407 | "Unknown option character `\\x%x'.\n", |
||
408 | optopt); |
||
409 | return 1; |
||
410 | default: |
||
411 | abort (); |
||
412 | } |
||
413 | for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0); |
||
414 | if (verbose) daq_help(filename, &inihdr, &runhdr, verbose); |
||
415 | |||
416 | printf("argdata %d nloops %d\n",argdata,runhdr.nloops); |
||
417 | |||
231 | f9daq | 418 | daq_init((char *)&inihdr); |
228 | f9daq | 419 | FILE *fp=NULL; |
420 | if (strlen(filename)>0) fp = fopen(filename, "wb"); |
||
421 | |||
422 | |||
423 | int maxlen = MAXLEN; |
||
424 | char *data = (char *) malloc(maxlen * sizeof(int)); |
||
425 | time_t t,tstart; |
||
426 | time(&tstart); |
||
427 | |||
428 | for (int i=0;i< runhdr.nloops;i++){ |
||
429 | int nb =daq_run((const char*) &runhdr, &data, &maxlen); |
||
430 | if (ctrl_c) break; |
||
431 | time(&t); |
||
432 | fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart)); |
||
433 | |||
434 | if (fp) { |
||
435 | fprintf(stderr, "Writing %d to %s", nb, filename); |
||
436 | fwrite(data, 1, nb, fp); |
||
437 | } |
||
438 | |||
439 | } |
||
440 | time(&t); |
||
441 | fprintf(stderr, "Total events %d in %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart)); |
||
442 | if (fp) fclose(fp); |
||
443 | if (data!=NULL) free(data); |
||
444 | return 0; |
||
445 | } |