#include "usbscope.h" #include #include #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; }