X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Fsiglent-sds%2Fapi.c;h=846399b678c4a8a3af56864e99ffbf27173b9d87;hp=f77dcc16bce9d640aaedbb528527e379384b68ed;hb=2f464b6c85281396ce06fd03167aa47b35d0c40a;hpb=e4fb1a821dc879b15be9feea28cd439d103db971 diff --git a/src/hardware/siglent-sds/api.c b/src/hardware/siglent-sds/api.c index f77dcc16..846399b6 100644 --- a/src/hardware/siglent-sds/api.c +++ b/src/hardware/siglent-sds/api.c @@ -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; } @@ -525,13 +535,13 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *devc; - uint64_t p, q; + uint64_t p; double t_dbl; - unsigned int i; + int i; int ret, idx; const char *tmp_str; char buffer[16]; - char *cmd; + char *cmd = ""; char cmd4[4]; devc = sdi->priv; @@ -588,12 +598,13 @@ 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); - return siglent_sds_config_set(sdi, "TDIV %s", cmd); + ret = siglent_sds_config_set(sdi, "TDIV %s", cmd); + g_free(cmd); + return ret; case SR_CONF_TRIGGER_SOURCE: if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources))) < 0) return SR_ERR_ARG; @@ -636,7 +647,9 @@ static int config_set(uint32_t key, GVariant *data, cmd = g_strdup_printf("%" PRIu64 "UV", p); break; } - return siglent_sds_config_set(sdi, "C%d:VDIV %s", i + 1, cmd); + ret = siglent_sds_config_set(sdi, "C%d:VDIV %s", i + 1, cmd); + g_free(cmd); + return ret; case SR_CONF_COUPLING: if (!cg) return SR_ERR_CHANNEL_GROUP; @@ -678,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; } @@ -755,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; } @@ -762,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; @@ -777,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; @@ -816,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; } } @@ -846,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. */ @@ -864,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); @@ -875,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; } @@ -898,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, @@ -916,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);