]> sigrok.org Git - libsigrok.git/commitdiff
scpi_serial: Reimplement to allow scpi_read_complete() to work correctly.
authorMartin Ling <redacted>
Wed, 22 Jan 2014 07:41:34 +0000 (07:41 +0000)
committerBert Vermeulen <redacted>
Thu, 23 Jan 2014 00:42:34 +0000 (01:42 +0100)
hardware/common/scpi_serial.c

index 9711c010a80fb9f5c92cfe60af7710d5e8760684..cf962af7c4075cf1a87aaafb69ec31c7d88fb347 100644 (file)
 
 #define LOG_PREFIX "scpi_serial"
 
-#define SCPI_READ_RETRIES 100
-#define SCPI_READ_RETRY_TIMEOUT 10000
+#define BUFFER_SIZE 1024
 
 struct scpi_serial {
        struct sr_serial_dev_inst *serial;
-       char last_character;
+       char buffer[BUFFER_SIZE];
+       size_t count;
+       size_t read;
 };
 
 static int scpi_serial_dev_inst_new(void *priv, const char *resource,
@@ -58,6 +59,9 @@ static int scpi_serial_open(void *priv)
        if (serial_flush(serial) != SR_OK)
                return SR_ERR;
 
+       sscpi->count = 0;
+       sscpi->read = 0;
+
        return SR_OK;
 }
 
@@ -107,9 +111,7 @@ static int scpi_serial_send(void *priv, const char *command)
 
 static int scpi_serial_read_begin(void *priv)
 {
-       struct scpi_serial *sscpi = priv;
-
-       sscpi->last_character = '\0';
+       (void) priv;
 
        return SR_OK;
 }
@@ -117,27 +119,56 @@ static int scpi_serial_read_begin(void *priv)
 static int scpi_serial_read_data(void *priv, char *buf, int maxlen)
 {
        struct scpi_serial *sscpi = priv;
-       int ret;
+       int len, ret;
+
+       len = BUFFER_SIZE - sscpi->count;
+
+       /* Try to read new data into the buffer if there is space. */
+       if (len > 0) {
+               ret = serial_read(sscpi->serial, sscpi->buffer + sscpi->read,
+                               BUFFER_SIZE - sscpi->count);
 
-       ret = serial_read(sscpi->serial, buf, maxlen);
+               if (ret < 0)
+                       return ret;
 
-       if (ret < 0)
-               return ret;
+               sscpi->count += ret;
 
-       if (ret > 0) {
-               sscpi->last_character = buf[ret - 1];
-               if (sscpi->last_character == '\n')
-                       ret--;
+               if (ret > 0)
+                       sr_spew("Read %d bytes into buffer.", ret);
        }
 
-       return ret;
+       /* Return as many bytes as possible from buffer, excluding any trailing newline. */
+       if (sscpi->read < sscpi->count) {
+               len = sscpi->count - sscpi->read;
+               if (len > maxlen)
+                       len = maxlen;
+               if (sscpi->buffer[sscpi->read + len - 1] == '\n')
+                       len--;
+               sr_spew("Returning %d bytes from buffer.", len);
+               memcpy(buf, sscpi->buffer + sscpi->read, len);
+               sscpi->read += len;
+               if (sscpi->read == BUFFER_SIZE) {
+                       sr_spew("Resetting buffer.");
+                       sscpi->count = 0;
+                       sscpi->read = 0;
+               }
+               return len;
+       }
+
+       return 0;
 }
 
 static int scpi_serial_read_complete(void *priv)
 {
        struct scpi_serial *sscpi = priv;
 
-       return (sscpi->last_character == '\n');
+       /* If the next character is a newline, discard it and report complete. */
+       if (sscpi->read < sscpi->count && sscpi->buffer[sscpi->read] == '\n') {
+               sscpi->read++;
+               return 1;
+       } else {
+               return 0;
+       }
 }
 
 static int scpi_serial_close(void *priv)