]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/rdtech-tc/protocol.c
rdtech-tc: request keyword differs between CDC and BLE transports
[libsigrok.git] / src / hardware / rdtech-tc / protocol.c
index 32ada461dc6f770b331a9fcc1de4677cea67b8e8..9320b84fafa5435578dfed04c3a217440df6cba5 100644 (file)
@@ -33,8 +33,6 @@
 #define WRITE_TO_MS    1
 #define POLL_PERIOD_MS 100
 
-static const char *poll_cmd = "getva";
-
 /*
  * Response data (raw sample data) consists of three adjacent chunks
  * of 64 bytes each. These chunks start with their magic string, and
@@ -55,6 +53,9 @@ static const char *poll_cmd = "getva";
 #define OFF_PAC2 (1 * PAC_LEN)
 #define OFF_PAC3 (2 * PAC_LEN)
 #define TC_POLL_LEN (3 * PAC_LEN)
+#if TC_POLL_LEN > RDTECH_TC_RSPBUFSIZE
+#  error "response length exceeds receive buffer space"
+#endif
 
 #define OFF_MODEL 4
 #define LEN_MODEL 4
@@ -126,16 +127,28 @@ static int process_poll_pkt(struct dev_context *devc, uint8_t *dst)
 
 SR_PRIV int rdtech_tc_probe(struct sr_serial_dev_inst *serial, struct dev_context *devc)
 {
+       static const char *poll_cmd_cdc = "getva";
+       static const char *poll_cmd_ble = "bgetva\r\n";
+
        int len;
        uint8_t poll_pkt[TC_POLL_LEN];
 
+       /* Construct the request text. Which differs across transports. */
+       devc->is_bluetooth = ser_name_is_bt(serial);
+       snprintf(devc->req_text, sizeof(devc->req_text), "%s",
+               devc->is_bluetooth ? poll_cmd_ble : poll_cmd_cdc);
+       sr_dbg("is bluetooth %d -> poll request '%s'.",
+               devc->is_bluetooth, devc->req_text);
+
+       /* Transmit the request. */
        len = serial_write_blocking(serial,
-               poll_cmd, strlen(poll_cmd), WRITE_TO_MS);
+               devc->req_text, strlen(devc->req_text), WRITE_TO_MS);
        if (len < 0) {
                sr_err("Failed to send probe request.");
                return SR_ERR;
        }
 
+       /* Receive a response. */
        len = serial_read_blocking(serial, devc->buf, TC_POLL_LEN, PROBE_TO_MS);
        if (len != TC_POLL_LEN) {
                sr_err("Failed to read probe response.");
@@ -167,7 +180,7 @@ SR_PRIV int rdtech_tc_poll(const struct sr_dev_inst *sdi, gboolean force)
         * Don't send the request while receive data is being accumulated.
         */
        devc = sdi->priv;
-       if (!force && devc->buflen)
+       if (!force && devc->rdlen)
                return SR_OK;
 
        /*
@@ -185,7 +198,7 @@ SR_PRIV int rdtech_tc_poll(const struct sr_dev_inst *sdi, gboolean force)
         */
        serial = sdi->conn;
        len = serial_write_blocking(serial,
-               poll_cmd, strlen(poll_cmd), WRITE_TO_MS);
+               devc->req_text, strlen(devc->req_text), WRITE_TO_MS);
        if (len < 0) {
                sr_err("Unable to send poll request.");
                return SR_ERR;
@@ -205,9 +218,9 @@ static int handle_poll_data(struct sr_dev_inst *sdi)
        float v;
 
        devc = sdi->priv;
-       sr_spew("Received poll packet (len: %zu).", devc->buflen);
-       if (devc->buflen < TC_POLL_LEN) {
-               sr_err("Insufficient poll packet length: %zu", devc->buflen);
+       sr_spew("Received poll packet (len: %zu).", devc->rdlen);
+       if (devc->rdlen < TC_POLL_LEN) {
+               sr_err("Insufficient poll packet length: %zu", devc->rdlen);
                return SR_ERR_DATA;
        }
 
@@ -216,21 +229,24 @@ static int handle_poll_data(struct sr_dev_inst *sdi)
                return SR_ERR_DATA;
        }
 
+       ret = SR_OK;
+       std_session_send_df_frame_begin(sdi);
        for (ch_idx = 0; ch_idx < devc->channel_count; ch_idx++) {
                pch = &devc->channels[ch_idx];
                ret = bv_get_value(&v, &pch->spec, poll_pkt, TC_POLL_LEN);
                if (ret != SR_OK)
-                       return ret;
+                       break;
                ret = feed_queue_analog_submit(devc->feeds[ch_idx], v, 1);
                if (ret != SR_OK)
-                       return ret;
+                       break;
        }
+       std_session_send_df_frame_end(sdi);
 
-       sr_sw_limits_update_samples_read(&devc->limits, 1);
+       sr_sw_limits_update_frames_read(&devc->limits, 1);
        if (sr_sw_limits_check(&devc->limits))
                sr_dev_acquisition_stop(sdi);
 
-       return SR_OK;
+       return ret;
 }
 
 static int recv_poll_data(struct sr_dev_inst *sdi, struct sr_serial_dev_inst *serial)
@@ -242,15 +258,15 @@ static int recv_poll_data(struct sr_dev_inst *sdi, struct sr_serial_dev_inst *se
 
        /* Receive data became available. Drain the transport layer. */
        devc = sdi->priv;
-       while (devc->buflen < TC_POLL_LEN) {
-               space = sizeof(devc->buf) - devc->buflen;
+       while (devc->rdlen < TC_POLL_LEN) {
+               space = sizeof(devc->buf) - devc->rdlen;
                len = serial_read_nonblocking(serial,
-                       &devc->buf[devc->buflen], space);
+                       &devc->buf[devc->rdlen], space);
                if (len < 0)
                        return SR_ERR_IO;
                if (len == 0)
                        return SR_OK;
-               devc->buflen += len;
+               devc->rdlen += len;
        }
 
        /*
@@ -259,13 +275,13 @@ static int recv_poll_data(struct sr_dev_inst *sdi, struct sr_serial_dev_inst *se
         */
 
        /* Process packets when their reception has completed. */
-       while (devc->buflen >= TC_POLL_LEN) {
+       while (devc->rdlen >= TC_POLL_LEN) {
                ret = handle_poll_data(sdi);
                if (ret != SR_OK)
                        return ret;
-               devc->buflen -= TC_POLL_LEN;
-               if (devc->buflen)
-                       memmove(&devc->buf[0], &devc->buf[TC_POLL_LEN], devc->buflen);
+               devc->rdlen -= TC_POLL_LEN;
+               if (devc->rdlen)
+                       memmove(devc->buf, &devc->buf[TC_POLL_LEN], devc->rdlen);
        }
 
        return SR_OK;