]> cvs.zerfleddert.de Git - rigol/blobdiff - scope.c
math/fft added to scope status
[rigol] / scope.c
diff --git a/scope.c b/scope.c
index 806ba3475ca2f417479df1272c6180d29a9e285d..ef14e7285acd51b7658975bb754c3e72ab60f2ca 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -1,54 +1,52 @@
-#include <usb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <strings.h>
 
-#include "usbtmc.h"
 #include "scope.h"
+#include "usbtmc.h"
 
 /* Just USB for now... */
 int sendscpi(struct scope* sc, char* cmd, unsigned char *resp, int resplen)
 {
-       return usbtmc_sendscpi(sc->usbdev, cmd, resp, resplen);
+       return usbtmc_sendscpi(sc, cmd, resp, resplen);
 }
 
 void closescope(struct scope* sc)
 {
-       return usbtmc_close(sc->usbdev);
+       return usbtmc_close(sc);
 }
 
 void claimscope(struct scope* sc)
 {
-       return usbtmc_claim(sc->usbdev);
+       return usbtmc_claim(sc);
 }
 
 void releasescope(struct scope* sc)
 {
-       //Disable keylock, so the user doesn't have to press the 'force'-button
+       /* Disable keylock, so the user doesn't have to press the 'force'-button */
        sendscpi(sc, ":KEY:LOCK DISABLE",NULL,0); 
-       return usbtmc_release(sc->usbdev);
+       return usbtmc_release(sc);
+}
+
+void resetscope(struct scope* sc)
+{
+       return usbtmc_reset(sc);
 }
 
 struct scope* initscope(void)
 {
-       struct usb_dev_handle *usbdev;
        struct scope *sc;
 
-       usbdev = usbtmc_initscope();
+       sc = usbtmc_initscope();
 
-       if (!usbdev) {
+       if (!sc) {
                printf("No scope found.\n");
                exit(EXIT_FAILURE);
        }
 
-       sc = calloc(1, sizeof(struct scope));
-       if (sc == NULL) {
-               perror("malloc");
-               exit(EXIT_FAILURE);
-       }
-
-       sc->usbdev = usbdev;
-
        claimscope(sc);
        sendscpi(sc, "*IDN?", (unsigned char*)sc->idn, sizeof(sc->idn)); 
        releasescope(sc);
@@ -62,3 +60,216 @@ 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);
+
+       sc->status.math.displayed = scope_get_truth_value(sc, ":MATH:DISP?");
+       sc->status.fft.displayed = scope_get_truth_value(sc, ":FFT:DISP?");
+
+       return 0;
+}
Impressum, Datenschutz