]> sigrok.org Git - libsigrok.git/commitdiff
gwinstek-gpd: Retry device identification on failure
authorRichard Allen <redacted>
Sat, 16 Jan 2021 19:31:31 +0000 (13:31 -0600)
committerSoeren Apel <redacted>
Sun, 21 Feb 2021 20:41:18 +0000 (21:41 +0100)
Try the identification command up to three times
if the device responds with 'Invalid Character.',
which can happen if the device has buffered part
of a command but not executed it.

src/hardware/gwinstek-gpd/api.c

index 5bf0ce52622e346e9c740fe60b178423165b0d16..6e745ee48c41cd1fb4fa36a6d10ef54c2769e8f8 100644 (file)
@@ -21,6 +21,8 @@
 #include <string.h>
 #include "protocol.h"
 
+#define IDN_RETRIES 3 /* at least 2 */
+
 static const uint32_t scanopts[] = {
        SR_CONF_CONN,
        SR_CONF_SERIALCOMM,
@@ -117,12 +119,32 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
        if (serial_open(serial, SERIAL_RDWR) != SR_OK)
                return NULL;
 
-       gpd_send_cmd(serial, "*IDN?\n");
-       if (gpd_receive_reply(serial, reply, sizeof(reply)) != SR_OK) {
-               sr_err("Device did not reply.");
+       /*
+        * Problem: we need to clear the GPD receive buffer before we
+        * can expect it to process commands correctly.
+        *
+        * Do not just send a newline, since that may cause it to
+        * execute a currently buffered command.
+        *
+        * Solution: Send identification request a few times.
+        * The first should corrupt any previous buffered command if present
+        * and respond with "Invalid Character." or respond directly with
+        * an identification string starting with "GW INSTEK"
+        */
+       for (i = 0; i<IDN_RETRIES; ++i) {
+               /* Request the GPD to identify itself */
+               gpd_send_cmd(serial, "*IDN?\n");
+               if (gpd_receive_reply(serial, reply, sizeof(reply)) == SR_OK) {
+                       if (0 == strncmp(reply, "GW INSTEK", 9 )) {
+                               break;
+                       }
+               }
+       }
+       if (i == IDN_RETRIES) {
+               sr_err("Device did not reply to identification request.");
+               serial_flush(serial);
                goto error;
        }
-       serial_flush(serial);
 
        /*
         * Returned identification string is for example: