X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/rigol/blobdiff_plain/bd29c60e53e501684134598436c05bb25915cb1c..1574729632acebdcdf8caa025dcb67c6ac3804fc:/scope.c?ds=sidebyside diff --git a/scope.c b/scope.c index c316ee5..9b75ba4 100644 --- a/scope.c +++ b/scope.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "scope.h" #include "usbtmc.h" @@ -58,3 +60,213 @@ char *scope_idn(struct scope *sc) { return sc->idn; } + +#define COPY_SCOPE_STRING(sc, cmd, dst) { \ + char *buf; \ + buf = scope_get_string(sc, cmd, sizeof(dst)); \ + if (buf) { \ + strcpy(dst, buf); \ + free(buf); \ + }\ + } + +char *scope_get_string(struct scope *sc, char *cmd, int maxlen) +{ + unsigned char *buf; + int res; + + buf = malloc(maxlen+1); + if (buf == NULL) { + perror("malloc(scope_get_strings)"); + exit(EXIT_FAILURE); + } + + res = sendscpi(sc, cmd, buf, maxlen); + if (res < 0) { + fprintf(stderr, "Command %s failed with %d\n", cmd, res); + free(buf); + return NULL; + } + + buf[res] = 0; + + return (char*)buf; +} + +int scope_get_truth_value(struct scope *sc, char *cmd) +{ + char buf[128]; + int res; + + bzero(buf, sizeof(buf)); + res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1); + if (res < 0) { + fprintf(stderr, "Command %s failed with %d\n", cmd, res); + return 0; + } + + printf("%s %s\n", cmd, buf); + + if (strcasecmp(buf, "on") == 0) { + return 1; + } else if (strcasecmp(buf, "enable") == 0) { + return 1; + } + + return 0; +} + +int scope_get_int(struct scope *sc, char *cmd) +{ + char buf[128]; + int res; + + bzero(buf, sizeof(buf)); + res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1); + if (res < 0) { + fprintf(stderr, "Command %s failed with %d\n", cmd, res); + return 0; + } + + return atoi(buf); +} + +double scope_get_double(struct scope *sc, char*cmd) +{ + char buf[128]; + int res; + double ret; + + bzero(buf, sizeof(buf)); + res = sendscpi(sc, cmd, (unsigned char*)buf, sizeof(buf)-1); + if (res < 0) { + fprintf(stderr, "Command %s failed with %d\n", cmd, res); + return 0.0; + } + + ret = strtod(buf, NULL); + + return ret; +} + +void update_scope_measurements(struct scope *sc) +{ + sc->status.measure.ch1.vpp = scope_get_double(sc, ":MEAS:VPP? CHAN1"); + sc->status.measure.ch1.vmax = scope_get_double(sc, ":MEAS:VMAX? CHAN1"); + sc->status.measure.ch1.vmin = scope_get_double(sc, ":MEAS:VMIN? CHAN1"); + sc->status.measure.ch1.vamplitude = scope_get_double(sc, ":MEAS:VAMP? CHAN1"); + sc->status.measure.ch1.vtop = scope_get_double(sc, ":MEAS:VTOP? CHAN1"); + sc->status.measure.ch1.vbase = scope_get_double(sc, ":MEAS:VBAS? CHAN1"); + sc->status.measure.ch1.vaverage = scope_get_double(sc, ":MEAS:VAV? CHAN1"); + sc->status.measure.ch1.vrms = scope_get_double(sc, ":MEAS:VRMS? CHAN1"); + sc->status.measure.ch1.overshoot = scope_get_double(sc, ":MEAS:OVER? CHAN1"); + sc->status.measure.ch1.preshoot = scope_get_double(sc, ":MEAS:PRES? CHAN1"); + sc->status.measure.ch1.frequency = scope_get_double(sc, ":MEAS:FREQ? CHAN1"); + sc->status.measure.ch1.risetime = scope_get_double(sc, ":MEAS:RIS? CHAN1"); + sc->status.measure.ch1.falltime = scope_get_double(sc, ":MEAS:FALL? CHAN1"); + sc->status.measure.ch1.period = scope_get_double(sc, ":MEAS:PER? CHAN1"); + sc->status.measure.ch1.pwidth = scope_get_double(sc, ":MEAS:PWID? CHAN1"); + sc->status.measure.ch1.nwidth = scope_get_double(sc, ":MEAS:NWID? CHAN1"); + sc->status.measure.ch1.pdutycycle = scope_get_double(sc, ":MEAS:PDUT? CHAN1"); + sc->status.measure.ch1.ndutycycle = scope_get_double(sc, ":MEAS:NDUT? CHAN1"); + sc->status.measure.ch1.pdelay = scope_get_double(sc, ":MEAS:PDEL? CHAN1"); + sc->status.measure.ch1.ndelay = scope_get_double(sc, ":MEAS:NDEL? CHAN1"); + + sc->status.measure.ch2.vpp = scope_get_double(sc, ":MEAS:VPP? CHAN2"); + sc->status.measure.ch2.vmax = scope_get_double(sc, ":MEAS:VMAX? CHAN2"); + sc->status.measure.ch2.vmin = scope_get_double(sc, ":MEAS:VMIN? CHAN2"); + sc->status.measure.ch2.vamplitude = scope_get_double(sc, ":MEAS:VAMP? CHAN2"); + sc->status.measure.ch2.vtop = scope_get_double(sc, ":MEAS:VTOP? CHAN2"); + sc->status.measure.ch2.vbase = scope_get_double(sc, ":MEAS:VBAS? CHAN2"); + sc->status.measure.ch2.vaverage = scope_get_double(sc, ":MEAS:VAV? CHAN2"); + sc->status.measure.ch2.vrms = scope_get_double(sc, ":MEAS:VRMS? CHAN2"); + sc->status.measure.ch2.overshoot = scope_get_double(sc, ":MEAS:OVER? CHAN2"); + sc->status.measure.ch2.preshoot = scope_get_double(sc, ":MEAS:PRES? CHAN2"); + sc->status.measure.ch2.frequency = scope_get_double(sc, ":MEAS:FREQ? CHAN2"); + sc->status.measure.ch2.risetime = scope_get_double(sc, ":MEAS:RIS? CHAN2"); + sc->status.measure.ch2.falltime = scope_get_double(sc, ":MEAS:FALL? CHAN2"); + sc->status.measure.ch2.period = scope_get_double(sc, ":MEAS:PER? CHAN2"); + sc->status.measure.ch2.pwidth = scope_get_double(sc, ":MEAS:PWID? CHAN2"); + sc->status.measure.ch2.nwidth = scope_get_double(sc, ":MEAS:NWID? CHAN2"); + sc->status.measure.ch2.pdutycycle = scope_get_double(sc, ":MEAS:PDUT? CHAN2"); + sc->status.measure.ch2.ndutycycle = scope_get_double(sc, ":MEAS:NDUT? CHAN2"); + sc->status.measure.ch2.pdelay = scope_get_double(sc, ":MEAS:PDEL? CHAN2"); + sc->status.measure.ch2.ndelay = scope_get_double(sc, ":MEAS:NDEL? CHAN2"); + + sc->status.measure.total = scope_get_truth_value(sc, ":MEAS:TOT?"); + COPY_SCOPE_STRING(sc, ":MEAS:SOUR?", sc->status.measure.source); + +} + +void update_scope_channel(struct scope *sc, int channel) +{ + struct channel_s *ch; + char cmd[128]; + int offs; + + if (channel == 1) { + ch = &(sc->status.channel.ch1); + strcpy(cmd, ":CHAN1:"); + } else if (channel == 2) { + ch = &(sc->status.channel.ch2); + strcpy(cmd, ":CHAN2:"); + } else { + fprintf(stderr, "Unknown channel %d!\n", channel); + return; + } + + offs=strlen(cmd); + + strcpy(cmd + offs, "BWL?"); ch->bwlimit_enabled = scope_get_truth_value(sc, cmd); + strcpy(cmd + offs, "COUP?"); COPY_SCOPE_STRING(sc, cmd, ch->coupling); + strcpy(cmd + offs, "DISP?"); ch->displayed = scope_get_truth_value(sc, cmd); + strcpy(cmd + offs, "INV?"); ch->inverted = scope_get_truth_value(sc, cmd); + strcpy(cmd + offs, "OFFS?"); ch->offset = scope_get_double(sc, cmd); + strcpy(cmd + offs, "PROB?"); ch->probe = scope_get_double(sc, cmd); + strcpy(cmd + offs, "SCAL?"); ch->scale = scope_get_double(sc, cmd); + strcpy(cmd + offs, "FILT?"); ch->filter_enabled = scope_get_truth_value(sc, cmd); + strcpy(cmd + offs, "MEMD?"); ch->memory_depth = scope_get_int(sc, cmd); + strcpy(cmd + offs, "VERN?"); COPY_SCOPE_STRING(sc, cmd, ch->vernier); +} + +int update_scope_status(struct scope *sc) +{ + bzero(&(sc->status), sizeof(sc->status)); + + COPY_SCOPE_STRING(sc, ":INFO:LANG?", sc->status.system.lang); + + sc->status.system.counter_enabled = scope_get_truth_value(sc, ":COUN:ENAB?"); + sc->status.system.beep_enabled = scope_get_truth_value(sc, ":BEEP:ENAB?"); + + sc->status.keyboard.key_lock = scope_get_truth_value(sc, ":KEY:LOCK?"); + + update_scope_measurements(sc); + + COPY_SCOPE_STRING(sc, ":DISP:TYPE?", sc->status.display.type); + COPY_SCOPE_STRING(sc, ":DISP:GRID?", sc->status.display.grid); + sc->status.display.persist = scope_get_truth_value(sc, ":DISP:PERS?"); + COPY_SCOPE_STRING(sc, ":DISP:MNUD?", sc->status.display.mnudisplay); + sc->status.display.mnustatus = scope_get_truth_value(sc, ":DISP:MNUS?"); + COPY_SCOPE_STRING(sc, ":DISP:SCR?", sc->status.display.screen); + sc->status.display.brightness = scope_get_int(sc, ":DISP:BRIG?"); + sc->status.display.intensity = scope_get_int(sc, ":DISP:INT?"); + + update_scope_channel(sc, 1); + update_scope_channel(sc, 2); + + COPY_SCOPE_STRING(sc, ":ACQ:TYPE?", sc->status.acquire.type); + COPY_SCOPE_STRING(sc, ":ACQ:MODE?", sc->status.acquire.mode); + + sc->status.acquire.averages = scope_get_int(sc, ":ACQ:AVER?"); + sc->status.acquire.srate_ch1 = scope_get_double(sc, ":ACQ:SAMP? CHAN1"); + sc->status.acquire.srate_ch2 = scope_get_double(sc, ":ACQ:SAMP? CHAN2"); + sc->status.acquire.srate_digital = scope_get_double(sc, ":ACQ:SAMP? DIGITAL"); + + COPY_SCOPE_STRING(sc, ":TIM:MODE?", sc->status.timebase.mode); + sc->status.timebase.offset = scope_get_double(sc, ":TIM:OFFS?"); + sc->status.timebase.delayed_offset = scope_get_double(sc, ":TIM:DEL:OFFS?"); + sc->status.timebase.scale = scope_get_double(sc, ":TIM:SCAL?"); + COPY_SCOPE_STRING(sc, ":TIM:FORM?", sc->status.timebase.format); + + return 0; +}