]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/siglent-sds/api.c
siglent-sds: move model dependent request emission to after identification
[libsigrok.git] / src / hardware / siglent-sds / api.c
index ebefa4bca5a4b26f6742bf7630c51cbac0b63021..846399b678c4a8a3af56864e99ffbf27173b9d87 100644 (file)
@@ -50,7 +50,7 @@ static const uint32_t devopts[] = {
        SR_CONF_SAMPLERATE | SR_CONF_GET,
        SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_DATA_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
-       SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+       SR_CONF_AVERAGING | SR_CONF_GET | SR_CONF_SET,
        SR_CONF_AVG_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
 };
 
@@ -149,6 +149,10 @@ static const uint64_t probe_factor[] = {
        1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000,
 };
 
+static const uint64_t averages[] = {
+       4, 16, 32, 64, 128, 256, 512, 1024,
+};
+
 /* Do not change the order of entries. */
 static const char *data_sources[] = {
        "Display",
@@ -188,7 +192,7 @@ static const struct siglent_sds_series supported_series[] = {
                { 50, 1 }, { 500, 100000 }, 14, 8, 14000363},
        [SDS1000XP] = {VENDOR(SIGLENT), "SDS1000X+", SPO_MODEL,
                { 50, 1 }, { 500, 100000 }, 14, 8, 14000363},
-       [SDS1000XE] = {VENDOR(SIGLENT), "SDS1000XE", SPO_MODEL,
+       [SDS1000XE] = {VENDOR(SIGLENT), "SDS1000XE", ESERIES,
                { 50, 1 }, { 500, 100000 }, 14, 8, 14000363},
        [SDS2000X] = {VENDOR(SIGLENT), "SDS2000X", SPO_MODEL,
                { 50, 1 }, { 500, 100000 }, 14, 8, 14000363},
@@ -197,35 +201,35 @@ static const struct siglent_sds_series supported_series[] = {
 #define SERIES(x) &supported_series[x]
 /* series, model, min timebase, analog channels, digital */
 static const struct siglent_sds_model supported_models[] = {
-       { SERIES(SDS1000CML), "SDS1152CML", { 20, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000CML), "SDS1102CML", { 10, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000CML), "SDS1072CML", { 5, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000CNL), "SDS1202CNL", { 20, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000CNL), "SDS1102CNL", { 10, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000CNL), "SDS1072CNL", { 5, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000DL), "SDS1202DL", { 20, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000DL), "SDS1102DL", { 10, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000DL), "SDS1022DL", { 5, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000DL), "SDS1052DL", { 5, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000DL), "SDS1052DL+", { 5, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000X), "SDS1102X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000XP), "SDS1102X+", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000X), "SDS1202X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000XP), "SDS1202X+", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000XE), "SDS1202X-E", { 1, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS1000XE), "SDS1104X-E", { 1, 1000000000 }, 4, true, 16 },
-       { SERIES(SDS1000XE), "SDS1204X-E", { 1, 1000000000 }, 4, true, 16 },
-       { SERIES(SDS2000X), "SDS2072X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS2000X), "SDS2074X", { 2, 1000000000 }, 4, false, 0 },
-       { SERIES(SDS2000X), "SDS2102X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS2000X), "SDS2104X", { 2, 1000000000 }, 4, false, 0 },
-       { SERIES(SDS2000X), "SDS2202X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS2000X), "SDS2204X", { 2, 1000000000 }, 4, false, 0 },
-       { SERIES(SDS2000X), "SDS2302X", { 2, 1000000000 }, 2, false, 0 },
-       { SERIES(SDS2000X), "SDS2304X", { 2, 1000000000 }, 4, false, 0 },
+       { SERIES(SDS1000CML), "SDS1152CML", { 20, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000CML), "SDS1102CML", { 10, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000CML), "SDS1072CML", { 5, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000CNL), "SDS1202CNL", { 20, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000CNL), "SDS1102CNL", { 10, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000CNL), "SDS1072CNL", { 5, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000DL), "SDS1202DL", { 20, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000DL), "SDS1102DL", { 10, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000DL), "SDS1022DL", { 5, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000DL), "SDS1052DL", { 5, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000DL), "SDS1052DL+", { 5, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000X), "SDS1102X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000XP), "SDS1102X+", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000X), "SDS1202X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000XP), "SDS1202X+", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000XE), "SDS1202X-E", { 1, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS1000XE), "SDS1104X-E", { 1, 1000000000 }, 4, TRUE, 16 },
+       { SERIES(SDS1000XE), "SDS1204X-E", { 1, 1000000000 }, 4, TRUE, 16 },
+       { SERIES(SDS2000X), "SDS2072X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2074X", { 2, 1000000000 }, 4, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2102X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2104X", { 2, 1000000000 }, 4, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2202X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2204X", { 2, 1000000000 }, 4, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2302X", { 2, 1000000000 }, 2, FALSE, 0 },
+       { SERIES(SDS2000X), "SDS2304X", { 2, 1000000000 }, 4, FALSE, 0 },
 };
 
-SR_PRIV struct sr_dev_driver siglent_sds_driver_info;
+static struct sr_dev_driver siglent_sds_driver_info;
 
 static void clear_helper(void *priv)
 {
@@ -253,10 +257,6 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
        const struct siglent_sds_model *model;
        gchar *channel_name;
 
-       sr_dbg("Setting Communication Headers to off.");
-       if (sr_scpi_send(scpi, "CHDR OFF") != SR_OK)
-               return NULL;
-
        if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
                sr_info("Couldn't get IDN response, retrying.");
                sr_scpi_close(scpi);
@@ -280,6 +280,10 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
                return NULL;
        }
 
+       sr_dbg("Setting Communication Headers to off.");
+       if (sr_scpi_send(scpi, "CHDR OFF") != SR_OK)
+               return NULL;
+
        sdi = g_malloc0(sizeof(struct sr_dev_inst));
        sdi->vendor = g_strdup(model->series->vendor->name);
        sdi->model = g_strdup(model->name);
@@ -514,6 +518,12 @@ static int config_get(uint32_t key, GVariant **data,
                }
                *data = g_variant_new_uint64(devc->attenuation[analog_channel]);
                break;
+       case SR_CONF_AVERAGING:
+               *data = g_variant_new_boolean(devc->average_enabled);
+               break;
+       case SR_CONF_AVG_SAMPLES:
+               *data = g_variant_new_uint64(devc->average_samples);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -588,11 +598,10 @@ static int config_set(uint32_t key, GVariant *data,
                case 1000000:
                        cmd = g_strdup_printf("%" PRIu64 "US", p);
                        break;
-               case 100000000:
+               case 1000000000:
                        cmd = g_strdup_printf("%" PRIu64 "NS", p);
                        break;
                }
-               sr_dbg("Setting device timebase: TDIV %s.", cmd);
                ret = siglent_sds_config_set(sdi, "TDIV %s", cmd);
                g_free(cmd);
                return ret;
@@ -682,6 +691,14 @@ static int config_set(uint32_t key, GVariant *data,
                siglent_sds_get_dev_cfg_horizontal(sdi);
                data = g_variant_new_uint64(devc->samplerate);
                break;
+       case SR_CONF_AVERAGING:
+               devc->average_enabled = g_variant_get_boolean(data);
+               sr_dbg("%s averaging", devc->average_enabled ? "Enabling" : "Disabling");
+               break;
+       case SR_CONF_AVG_SAMPLES:
+               devc->average_samples = g_variant_get_uint64(data);
+               sr_dbg("Setting averaging rate to %" PRIu64, devc->average_samples);
+               break;  
        default:
                return SR_ERR_NA;
        }
@@ -759,6 +776,7 @@ static int config_list(uint32_t key, GVariant **data,
                        *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
                        break;
                case SPO_MODEL:
+               case ESERIES:
                        *data = g_variant_new_strv(ARRAY_AND_SIZE(data_sources));
                        break;
                }
@@ -766,8 +784,8 @@ static int config_list(uint32_t key, GVariant **data,
        case SR_CONF_NUM_HDIV:
                *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
                break;
-       case SR_CONF_AVERAGING:
-               /* TODO: Implement averaging. */
+       case SR_CONF_AVG_SAMPLES:
+               *data = std_gvar_array_u64(ARRAY_AND_SIZE(averages));
                break;
        default:
                return SR_ERR_NA;
@@ -781,7 +799,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        struct sr_scpi_dev_inst *scpi;
        struct dev_context *devc;
        struct sr_channel *ch;
-       struct sr_datafeed_packet packet;
        gboolean some_digital;
        GSList *l, *d;
 
@@ -820,20 +837,17 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                        if (ch->enabled) {
                                /* Turn on LA module if currently off and digital channels are enabled. */
                                if (!devc->la_enabled) {
-                                       if (siglent_sds_config_set(sdi, "DGST ON") != SR_OK)
+                                       if (siglent_sds_config_set(sdi, "DI:SW?") != SR_OK)
                                                return SR_ERR;
-                                       g_usleep(630000);
                                        devc->la_enabled = TRUE;
                                }
                                devc->enabled_channels = g_slist_append(
                                        devc->enabled_channels, ch);
                        }
                        /* Enabled channel is currently disabled, or vice versa. */
-                       if (siglent_sds_config_set(sdi, "D%d:DGCH %s", ch->index,
+                       if (siglent_sds_config_set(sdi, "D%d:TRA %s", ch->index,
                                ch->enabled ? "ON" : "OFF") != SR_OK)
                                return SR_ERR;
-                       /* Slowing the command sequence down to let the device handle it. */
-                       g_usleep(630000);
                        devc->digital_channels[ch->index] = ch->enabled;
                }
        }
@@ -850,12 +864,18 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        // devc->analog_frame_size = devc->model->series->buffer_samples;
        // devc->digital_frame_size = devc->model->series->buffer_samples;
 
+       siglent_sds_get_dev_cfg_horizontal(sdi);
        switch (devc->model->series->protocol) {
        case SPO_MODEL:
                if (siglent_sds_config_set(sdi, "WFSU SP,0,TYPE,1") != SR_OK)
                        return SR_ERR;
-               if (siglent_sds_config_set(sdi, "ACQW SAMPLING") != SR_OK)
-                       return SR_ERR;
+               if (devc->average_enabled) {
+                       if (siglent_sds_config_set(sdi, "ACQW AVERAGE,%i", devc->average_samples) != SR_OK)
+                               return SR_ERR;
+               } else {
+                       if (siglent_sds_config_set(sdi, "ACQW SAMPLING") != SR_OK)
+                               return SR_ERR;
+               }
                break;
        case NON_SPO_MODEL:
                /* TODO: Implement CML/CNL/DL models. */
@@ -868,7 +888,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                break;
        }
 
-       sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
+       sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 7000,
                siglent_sds_receive, (void *) sdi);
 
        std_session_send_df_header(sdi);
@@ -879,8 +899,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
                return SR_ERR;
 
        /* Start of first frame. */
-       packet.type = SR_DF_FRAME_BEGIN;
-       sr_session_send(sdi, &packet);
+       std_session_send_df_frame_begin(sdi);
 
        return SR_OK;
 }
@@ -902,7 +921,7 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
-SR_PRIV struct sr_dev_driver siglent_sds_driver_info = {
+static struct sr_dev_driver siglent_sds_driver_info = {
        .name = "siglent-sds",
        .longname = "Siglent SDS1000/SDS2000",
        .api_version = 1,
@@ -920,5 +939,4 @@ SR_PRIV struct sr_dev_driver siglent_sds_driver_info = {
        .dev_acquisition_stop = dev_acquisition_stop,
        .context = NULL,
 };
-
 SR_REGISTER_DEV_DRIVER(siglent_sds_driver_info);