#include "usbscope.h"
#include <string.h>
#include <math.h>
#define MAXDEV 4
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
struct devinfo {
int addr;
int fd;
float ran;
int ran_code;
int ran_prec;
float raw_offset;
float dac_scale;
int trig_offset;
char fnread[PATH_MAX];
char fnwrite[PATH_MAX];
};
int detect_init(struct devinfo *di, int devs, int master) {
int i, ret;
for(i = 0; i < devs; i++) {
usbtm_set_trig_master(di[i].fd, 0);
usbtm_set_detect_line(di[i].fd, 0, 1);
}
usbtm_set_detect_line(di[master].fd, 0, 1);
usbtm_get_detect_line(di[master].fd, &ret);
if(!ret) {
fprintf(stderr, "Nektere z propojenych zarizeni neni pripojeno na USB!\n");
return 0;
}
usbtm_set_detect_line(di[master].fd, 1, 0);
for(i = 0; i < devs; i++) {
if(i == master) continue;
usbtm_set_detect_line(di[i].fd, 0, 1);
usbtm_get_detect_line(di[i].fd, &ret);
if(ret) {
fprintf(stderr, "Nektere uvedene zarizeni neni propojeno s ostatnimi!\n");
return 0;
}
}
for(i = 0; i < devs; i++)
if(!scope50_init_scope(di[i].fd, i==master,
&di[i].raw_offset, &di[i].dac_scale, &di[i].trig_offset)) return 0;
scope50_set_trig_master(di[master].fd, 1);
return 1;
}
int parse_coupling(char *str) {
int ret = -1;
if(!strcasecmp(str, "ac")) ret = SCOPE50_COUPLING_AC;
if(!strcasecmp(str, "dc")) ret = SCOPE50_COUPLING_DC;
return ret;
}
int parse_edge(char *str) {
int ret = -1;
if(*str == 'l') ret = SCOPE50_TRIG_TYPE_LESS;
if(*str == 'g') ret = SCOPE50_TRIG_TYPE_GREATER;
if(*str == 'u') ret = SCOPE50_TRIG_TYPE_EDGE_UP;
if(*str == 'd') ret = SCOPE50_TRIG_TYPE_EDGE_DOWN;
return ret;
}
int main(int argc, char *argv[]) {
int opt, devs = 0, help = 0;
struct devinfo di[MAXDEV];
int len = 3072, freq = 1E7, pretrig = 0, real,
coup = SCOPE50_COUPLING_DC, ttype = SCOPE50_TRIG_TYPE_EDGE_UP;
int i, j, res;
float thresh = 0, ran, rc, rp, defran = 3.0;
int defranc = SCOPE50_RANGE_30V, defranp = 2;
unsigned char data[4][3072];
int master = 0;
FILE *fcalib;
while((opt = getopt(argc, argv, "d:mf:l:r:t:p:e:C:S:L:h?")) != -1)
switch(opt) {
case 'd':
if(devs == MAXDEV) {
help = 1;
break;
}
di[devs].addr = atoi(optarg);
di[devs].ran = defran;
di[devs].ran_code = defranc;
di[devs].ran_prec = defranp;
di[devs].raw_offset = 0;
di[devs].dac_scale = 0;
di[devs].trig_offset = 0;
di[devs].fnread[0] = 0;
di[devs].fnwrite[0] = 0;
devs++;
break;
case 'm':
if(!devs) help = 1;
else master = devs-1;
break;
case 'f':
freq = (int)(atof(optarg));
break;
case 'l':
len = atoi(optarg);
break;
case 't':
thresh = atof(optarg);
break;
case 'p':
pretrig = atoi(optarg);
break;
case 'e':
ttype = parse_edge(optarg);
break;
case 'C':
coup = parse_coupling(optarg);
break;
case 'r':
ran = atof(optarg);
if(ran > 0 && ran < 0.4) ran = 0.3, rc = SCOPE50_RANGE_3V, rp = 3;
else if(ran > 0.4 && ran < 4) ran = 3, rc = SCOPE50_RANGE_30V, rp = 2;
else if(ran > 4 && ran <= 300) ran = 30, rc = SCOPE50_RANGE_300V, rp = 1;
else help = 1;
if(!devs) defran = ran, defranc = rc, defranp = rp;
else di[devs-1].ran = ran, di[devs-1].ran_code = rc, di[devs-1].ran_prec = rp;
break;
case 'S':
if(!devs) {
help = 1;
break;
}
strcpy(di[devs-1].fnwrite, optarg);
break;
case 'L':
if(!devs) {
help = 1;
break;
}
strcpy(di[devs-1].fnread, optarg);
break;
default:
help = 1;
break;
}
if(help || optind != argc || devs < 1 || len < 1 || len > 3072 ||
fabs(thresh) > 0.9*di[0].ran || pretrig > len || ttype < 0 || coup < 0) {
printf("Pouziti: %s [-f freq] [-p pretrig] [-t thresh] [-e edge]\n"
" [-l len] [-C coup] [-d dev] [-r ran] [-m] [-S|-L conf] [-d...\n"
" freq je pocet vzorku za vterinu: 25 - 5E7 (vychozi: 1E7).\n"
" pretrig je pocet vzorku v pameti pred spustenim triggeru.\n"
" thresh je prahove napeti triggeru ve voltech.\n"
" edge je zpusob detekce hrany: less/l, greater/g, up/u, down/d.\n"
" len je delka zaznamu: 1 - 3072 (vychozi: maximum).\n"
" dev je cislo zarizeni %sn, na ktere se pripojit.\n"
" ran je vertikalni rozsah kanalu: 0.3, 3 nebo 30 V (vych. 3).\n"
" Jestlize je uvedeno pred prvnim -d, urcuje vychozi hodnotu.\n"
" -m urcuje predchozi -d jako Trigger Master.\n"
" Volby -S/-L umoznuji ulozit / nacist kalibracni data pro\n"
" rychlejsi spusteni. Uvedte zvlast pro kazdy kanal.\n",
argv[0], DEVNAME);
return 0;
}
for(i = 0; i < devs; i++)
if(!opendev(di[i].addr, &di[i].fd)) {
fprintf(stderr, deverror(di[i].addr));
return 1;
}
for(i = 0; i < devs; i++) {
if(*di[i].fnread) {
fcalib = fopen(di[i].fnread, "r");
if(!fcalib) {
fprintf(stderr,
"Nepodarilo se otevrit soubor %s pro cteni kalibracnich dat.\n", di[i].fnread);
} else {
if(fscanf(fcalib, "%f %f %i", &di[i].raw_offset, &di[i].dac_scale, &di[i].trig_offset) < 3) {
fprintf(stderr, "Neplatna kalibracni data.");
di[i].raw_offset = di[i].dac_scale = di[i].trig_offset = 0;
}
fclose(fcalib);
}
}
}
if(!detect_init(di, devs, master)) {
for(i = 0; i < devs; i++)
closedev(di[i].addr, di[i].fd);
return 1;
}
for(i = 0; i < devs; i++) {
if(*di[i].fnwrite) {
fcalib = fopen(di[i].fnwrite, "w");
if(!fcalib) {
fprintf(stderr,
"Nepodarilo se otevrit soubor %s pro ulozeni kalibracnich dat.\n", di[i].fnwrite);
} else {
fprintf(fcalib, "%f %f %i", di[i].raw_offset, di[i].dac_scale, di[i].trig_offset);
fclose(fcalib);
}
}
}
for(i = 0; i < devs; i++) {
scope50_setup_front_end(di[i].fd, di[i].ran_code, coup, 0);
scope50_set_sample_frequency(di[i].fd, freq, &real);
if(real != freq) fprintf(stderr, "Skutecna vzorkovaci frekvence: %i\n", real);
scope50_set_offset(di[i].fd, 0, NULL);
scope50_set_norm_trig(di[i].fd, 1);
}
scope50_set_trig_thresh(di[master].fd, thresh*100.0/di[master].ran);
scope50_set_trig_type(di[master].fd, ttype);
scope50_set_pretrig_depth(pretrig);
scope50_set_trig_master(di[master].fd, 1);
for(i = 0; i < devs; i++)
if(i != master)
scope50_acquisition_start(di[i].fd);
scope50_acquisition_start(di[master].fd);
do {
if(!scope50_get_acquisition_state(di[master].fd, &res)) return 1;
if(res) usleep(100);
} while(res);
for(i = 0; i < devs; i++)
scope50_get_buffer_blocks_raw(di[i].fd, data[i], 6);
for(j = 0; j < len; j++) {
for(i = 0; i < devs; i++) {
if(i) printf("\t");
printf("%.*f", di[i].ran_prec, (data[i][j]/255.0 - 0.5)*2*di[i].ran);
}
printf("\n");
}
fflush(stdout);
for(i = 0; i < devs; i++)
closedev(di[i].addr, di[i].fd);
return 0;
}