X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=hardware%2Frigol-ds1xx2%2Fapi.c;h=53c4fb313ae2fc36b78542080224e0576e38c7bf;hb=886bd5e05686617c928be2d600ce91ed298a2331;hp=cdbdaad66ee9a01e48be11fb8404185f66705b7a;hpb=169dbe8577c2f7570f61799a064f95b39b3b6fe3;p=libsigrok.git diff --git a/hardware/rigol-ds1xx2/api.c b/hardware/rigol-ds1xx2/api.c index cdbdaad6..53c4fb31 100644 --- a/hardware/rigol-ds1xx2/api.c +++ b/hardware/rigol-ds1xx2/api.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "libsigrok.h" #include "libsigrok-internal.h" @@ -33,7 +32,6 @@ static const int32_t hwcaps[] = { SR_CONF_OSCILLOSCOPE, - SR_CONF_LIMIT_SAMPLES, SR_CONF_TIMEBASE, SR_CONF_TRIGGER_SOURCE, SR_CONF_TRIGGER_SLOPE, @@ -104,6 +102,22 @@ static const char *trigger_sources[] = { "CH2", "EXT", "AC Line", + "D0", + "D1", + "D2", + "D3", + "D4", + "D5", + "D6", + "D7", + "D8", + "D9", + "D10", + "D11", + "D12", + "D13", + "D14", + "D15", }; static const char *coupling[] = { @@ -158,7 +172,6 @@ static int clear_instances(void) static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...) { struct dev_context *devc; - struct timespec delay; va_list args; char buf[256]; @@ -172,10 +185,8 @@ static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...) /* When setting a bunch of parameters in a row, the DS1052E scrambles * some of them unless there is at least 100ms delay in between. */ - delay.tv_sec = 0; - delay.tv_nsec = 100000000L; - sr_spew("delay %dms", delay.tv_nsec / 1000000); - nanosleep(&delay, NULL); + sr_spew("delay %dms", 100); + g_usleep(100000); return SR_OK; } @@ -204,7 +215,9 @@ static GSList *hw_scan(GSList *options) gchar **tokens; const char *manufacturer, *model, *version; gboolean matched = FALSE; + gboolean has_digital = FALSE; char buf[256]; + gchar *channel_name; (void)options; @@ -230,7 +243,7 @@ static GSList *hw_scan(GSList *options) close(fd); if (len == 0) { g_free(device); - return NULL; + continue; } buf[len] = 0; @@ -243,7 +256,7 @@ static GSList *hw_scan(GSList *options) if (num_tokens < 4) { g_strfreev(tokens); g_free(device); - return NULL; + continue; } manufacturer = tokens[0]; @@ -253,12 +266,13 @@ static GSList *hw_scan(GSList *options) if (strcmp(manufacturer, "Rigol Technologies")) { g_strfreev(tokens); g_free(device); - return NULL; + continue; } for (i = 0; i < ARRAY_SIZE(supported_models); i++) { if (!strcmp(model, supported_models[i])) { matched = 1; + has_digital = g_str_has_suffix(model, "D"); break; } } @@ -267,7 +281,7 @@ static GSList *hw_scan(GSList *options) manufacturer, model, version))) { g_strfreev(tokens); g_free(device); - return NULL; + continue; } g_strfreev(tokens); @@ -275,27 +289,46 @@ static GSList *hw_scan(GSList *options) if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); g_free(device); - return NULL; + goto hw_scan_abort; } + devc->limit_frames = 0; devc->device = device; + devc->has_digital = has_digital; sdi->priv = devc; sdi->driver = di; + drvc->instances = g_slist_append(drvc->instances, sdi); + devices = g_slist_append(devices, sdi); for (i = 0; i < 2; i++) { - if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, - i == 0 ? "CH1" : "CH2"))) - return NULL; + if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, + i == 0 ? "CH1" : "CH2"))) + goto hw_scan_abort; sdi->probes = g_slist_append(sdi->probes, probe); } - drvc->instances = g_slist_append(drvc->instances, sdi); - devices = g_slist_append(devices, sdi); + if (devc->has_digital) { + for (i = 0; i < 16; i++) { + if (!(channel_name = g_strdup_printf("D%d", i))) + goto hw_scan_abort; + probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name); + g_free(channel_name); + if (!probe) + goto hw_scan_abort; + sdi->probes = g_slist_append(sdi->probes, probe); + } + } } g_dir_close(dir); return devices; + +hw_scan_abort: + g_dir_close(dir); + g_slist_free(devices); + clear_instances(); + return NULL; } static GSList *hw_dev_list(void) @@ -352,7 +385,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) *data = g_variant_new_int32(NUM_VDIV); break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; @@ -461,8 +494,7 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) ret = SR_ERR_ARG; break; default: - sr_err("Unknown hardware capability: %d.", id); - ret = SR_ERR_ARG; + ret = SR_ERR_NA; break; } @@ -474,8 +506,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) GVariant *tuple, *rational[2]; GVariantBuilder gvb; unsigned int i; - - (void)sdi; + struct dev_context *devc; switch (key) { case SR_CONF_DEVICE_OPTIONS: @@ -506,11 +537,15 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) *data = g_variant_builder_end(&gvb); break; case SR_CONF_TRIGGER_SOURCE: + if (!sdi || !sdi->priv) + /* Can't know this until we have the exact model. */ + return SR_ERR_ARG; + devc = sdi->priv; *data = g_variant_new_strv(trigger_sources, - ARRAY_SIZE(trigger_sources)); + devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4); break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; @@ -521,7 +556,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) struct dev_context *devc; struct sr_probe *probe; GSList *l; - int probenum; char cmd[256]; (void)cb_data; @@ -530,19 +564,32 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) for (l = sdi->probes; l; l = l->next) { probe = l->data; - probenum = probe->name[2] == '1' ? 0 : 1; - if (probe->enabled) - devc->enabled_probes = g_slist_append(devc->enabled_probes, probe); - - if (probe->enabled != devc->channels[probenum]) { - /* Enabled channel is currently disabled, or vice versa. */ - sprintf(cmd, ":CHAN%d:DISP %s", probenum + 1, - probe->enabled ? "ON" : "OFF"); - if (rigol_ds1xx2_send(devc, cmd) != SR_OK) - return SR_ERR; + sr_dbg("handling probe %s", probe->name); + if (probe->type == SR_PROBE_ANALOG) { + if (probe->enabled) + devc->enabled_analog_probes = g_slist_append( + devc->enabled_analog_probes, probe); + if (probe->enabled != devc->analog_channels[probe->index]) { + /* Enabled channel is currently disabled, or vice versa. */ + sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1, + probe->enabled ? "ON" : "OFF"); + if (rigol_ds1xx2_send(devc, cmd) != SR_OK) + return SR_ERR; + } + } else if (probe->type == SR_PROBE_LOGIC) { + if (probe->enabled) + devc->enabled_digital_probes = g_slist_append( + devc->enabled_digital_probes, probe); + if (probe->enabled != devc->digital_channels[probe->index]) { + /* Enabled channel is currently disabled, or vice versa. */ + sprintf(cmd, ":DIG%d:TURN %s", probe->index, + probe->enabled ? "ON" : "OFF"); + if (rigol_ds1xx2_send(devc, cmd) != SR_OK) + return SR_ERR; + } } } - if (!devc->enabled_probes) + if (!devc->enabled_analog_probes && !devc->enabled_digital_probes) return SR_ERR; sr_source_add(devc->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi); @@ -551,10 +598,18 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN); /* Fetch the first frame. */ - devc->channel_frame = devc->enabled_probes->data; - if (rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%c", - devc->channel_frame->name[2]) != SR_OK) - return SR_ERR; + if (devc->enabled_analog_probes) { + devc->channel_frame = devc->enabled_analog_probes->data; + if (rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%d", + devc->channel_frame->index + 1) != SR_OK) + return SR_ERR; + } else { + devc->channel_frame = devc->enabled_digital_probes->data; + if (rigol_ds1xx2_send(devc, ":WAV:DATA? DIG") != SR_OK) + return SR_ERR; + } + + devc->num_frame_bytes = 0; return SR_OK; } @@ -572,8 +627,10 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) return SR_ERR; } - g_slist_free(devc->enabled_probes); - devc->enabled_probes = NULL; + g_slist_free(devc->enabled_analog_probes); + g_slist_free(devc->enabled_digital_probes); + devc->enabled_analog_probes = NULL; + devc->enabled_digital_probes = NULL; sr_source_remove(devc->fd); return SR_OK;