]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/fluke-dmm/protocol.c
fluke-dmm: reduce indentation in 18x/190/28x dispatch logic
[libsigrok.git] / src / hardware / fluke-dmm / protocol.c
index 77200c3ed163be8e9f4f00358963190e4bdb9a3d..20487f087da177fd339c0302510d769578f121ae 100644 (file)
 #include "libsigrok-internal.h"
 #include "protocol.h"
 
+static int count_digits(const char *str) {
+       int digits;
+
+       while (*str && *str != ' ' && *str != ',' && *str != '.')
+               str++;
+
+       digits = 0;
+       if (*str == '.') {
+               str++;
+               while (*str && *str != ' ' && *str != ',') {
+                       str++;
+                       digits++;
+               }
+       }
+
+       return digits;
+}
+
 static void handle_qm_18x(const struct sr_dev_inst *sdi, char **tokens)
 {
        struct dev_context *devc;
@@ -37,6 +55,7 @@ static void handle_qm_18x(const struct sr_dev_inst *sdi, char **tokens)
        float fvalue;
        char *e, *u;
        gboolean is_oor;
+       int digits;
 
        devc = sdi->priv;
 
@@ -46,6 +65,7 @@ static void handle_qm_18x(const struct sr_dev_inst *sdi, char **tokens)
        if ((e = strstr(tokens[1], "Out of range"))) {
                is_oor = TRUE;
                fvalue = -1;
+               digits = 0;
                while (*e && *e != '.')
                        e++;
        } else {
@@ -58,15 +78,15 @@ static void handle_qm_18x(const struct sr_dev_inst *sdi, char **tokens)
                *e++ = '\0';
                if (sr_atof_ascii(tokens[1], &fvalue) != SR_OK) {
                        /* Happens all the time, when switching modes. */
-                       sr_dbg("Invalid float.");
+                       sr_dbg("Invalid float: '%s'", tokens[1]);
                        return;
                }
+               digits = count_digits(tokens[1]);
        }
        while (*e && *e == ' ')
                e++;
 
-       /* TODO: Use proper 'digits' value for this device (and its modes). */
-       sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
+       sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
        analog.data = &fvalue;
        analog.meaning->channels = sdi->channels;
        analog.num_samples = 1;
@@ -167,6 +187,7 @@ static void handle_qm_28x(const struct sr_dev_inst *sdi, char **tokens)
        struct sr_analog_meaning meaning;
        struct sr_analog_spec spec;
        float fvalue;
+       int digits;
 
        devc = sdi->priv;
 
@@ -177,9 +198,9 @@ static void handle_qm_28x(const struct sr_dev_inst *sdi, char **tokens)
                sr_err("Invalid float '%s'.", tokens[0]);
                return;
        }
+       digits = count_digits(tokens[0]);
 
-       /* TODO: Use proper 'digits' value for this device (and its modes). */
-       sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
+       sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
        analog.data = &fvalue;
        analog.meaning->channels = sdi->channels;
        analog.num_samples = 1;
@@ -378,7 +399,9 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens)
        struct sr_analog_meaning meaning;
        struct sr_analog_spec spec;
        float fvalue;
+       int digits;
 
+       digits = 2;
        if (!strcmp(tokens[0], "9.9E+37")) {
                /* An invalid measurement shows up on the display as "OL", but
                 * comes through like this. Since comparing 38-digit floats
@@ -389,6 +412,7 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens)
                        sr_err("Invalid float '%s'.", tokens[0]);
                        return;
                }
+               digits = count_digits(tokens[0]);
        }
 
        devc = sdi->priv;
@@ -405,8 +429,7 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens)
                        fvalue = 1.0;
        }
 
-       /* TODO: Use proper 'digits' value for this device (and its modes). */
-       sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
+       sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
        analog.meaning->channels = sdi->channels;
        analog.num_samples = 1;
        analog.data = &fvalue;
@@ -426,6 +449,7 @@ static void handle_line(const struct sr_dev_inst *sdi)
        struct sr_serial_dev_inst *serial;
        int num_tokens, n, i;
        char cmd[16], **tokens;
+       int ret;
 
        devc = sdi->priv;
        serial = sdi->conn;
@@ -443,34 +467,48 @@ static void handle_line(const struct sr_dev_inst *sdi)
 
        tokens = g_strsplit(devc->buf, ",", 0);
        if (tokens[0]) {
-               if (devc->profile->model == FLUKE_187 || devc->profile->model == FLUKE_189) {
+               switch (devc->profile->model) {
+               case FLUKE_87:
+               case FLUKE_89:
+               case FLUKE_187:
+               case FLUKE_189:
                        devc->expect_response = FALSE;
                        handle_qm_18x(sdi, tokens);
-               } else if (devc->profile->model == FLUKE_287 || devc->profile->model == FLUKE_289) {
+                       break;
+               case FLUKE_287:
+               case FLUKE_289:
                        devc->expect_response = FALSE;
                        handle_qm_28x(sdi, tokens);
-               } else if (devc->profile->model == FLUKE_190) {
+                       break;
+               case FLUKE_190:
                        devc->expect_response = FALSE;
-                       for (num_tokens = 0; tokens[num_tokens]; num_tokens++);
-                       if (num_tokens >= 7) {
-                               /* Response to QM: this is a comma-separated list of
-                                * fields with metadata about the measurement. This
-                                * format can return multiple sets of metadata,
-                                * split into sets of 7 tokens each. */
-                               devc->meas_type = 0;
-                               for (i = 0; i < num_tokens; i += 7)
-                                       handle_qm_19x_meta(sdi, tokens + i);
-                               if (devc->meas_type) {
-                                       /* Slip the request in now, before the main
-                                        * timer loop asks for metadata again. */
-                                       n = sprintf(cmd, "QM %d\r", devc->meas_type);
-                                       if (serial_write_blocking(serial, cmd, n, SERIAL_WRITE_TIMEOUT_MS) < 0)
-                                               sr_err("Unable to send QM (measurement).");
-                               }
-                       } else {
+                       num_tokens = g_strv_length(tokens);
+                       if (num_tokens < 7) {
                                /* Response to QM <n> measurement request. */
                                handle_qm_19x_data(sdi, tokens);
+                               break;
+                       }
+                       /*
+                        * Response to QM: This is a comma-separated list of
+                        * fields with metadata about the measurement. This
+                        * format can return multiple sets of metadata,
+                        * split into sets of 7 tokens each.
+                        */
+                       devc->meas_type = 0;
+                       for (i = 0; i < num_tokens; i += 7)
+                               handle_qm_19x_meta(sdi, tokens + i);
+                       if (devc->meas_type) {
+                               /*
+                                * Slip the request in now, before the main
+                                * timer loop asks for metadata again.
+                                */
+                               n = sprintf(cmd, "QM %d\r", devc->meas_type);
+                               ret = serial_write_blocking(serial,
+                                       cmd, n, SERIAL_WRITE_TIMEOUT_MS);
+                               if (ret < 0)
+                                       sr_err("Cannot send QM (measurement).");
                        }
+                       break;
                }
        }
        g_strfreev(tokens);