From: Timo Kokkonen Date: Mon, 5 Oct 2020 09:04:57 +0000 (-0700) Subject: rigol-dg: Add device/firmware specific quirks support. X-Git-Url: https://sigrok.org/gitweb/?a=commitdiff_plain;h=b1eb94bbef0312005f879b7525b11b8c7049aca1;p=libsigrok.git rigol-dg: Add device/firmware specific quirks support. DG800/DG900 units seems to have issues with counter implementation: - About 1 second delay is needed after enabling or disabling the counter. Otherwise unit stops responding properly (start seeing USB errors). - Second channel and counter cannot be enabled simultaneously. --- diff --git a/src/hardware/rigol-dg/api.c b/src/hardware/rigol-dg/api.c index 43121aed..ea8189b9 100644 --- a/src/hardware/rigol-dg/api.c +++ b/src/hardware/rigol-dg/api.c @@ -302,6 +302,27 @@ static const struct device_spec device_models[] = { }, }; +static void check_device_quirks(struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + gboolean is_8xx, is_9xx; + + devc = sdi->priv; + + /* + * Check for counter issue in DG800/DG900 units... + * + * TODO: Add firmware version check if Rigol fixes this issue + * in future firmware versions. + */ + is_8xx = g_ascii_strncasecmp(sdi->model, "DG8", strlen("DG8")) == 0; + is_9xx = g_ascii_strncasecmp(sdi->model, "DG9", strlen("DG9")) == 0; + if (is_8xx || is_9xx) { + devc->quirks |= RIGOL_DG_COUNTER_BUG; + devc->quirks |= RIGOL_DG_COUNTER_CH2_CONFLICT; + } +} + static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi) { struct sr_dev_inst *sdi; @@ -382,6 +403,9 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi) sr_scpi_hw_info_free(hw_info); + /* Check for device/firmware specific issues. */ + check_device_quirks(sdi); + return sdi; error: @@ -729,6 +753,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) struct sr_scpi_dev_inst *scpi; const char *cmd; char *response; + GVariant *data; + gboolean need_quirk; + gboolean ch_active; int ret; if (!sdi) @@ -737,6 +764,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) devc = sdi->priv; scpi = sdi->conn; response = NULL; + data = NULL; ret = SR_OK; if (!scpi) @@ -754,13 +782,45 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) devc->counter_enabled = FALSE; if (!devc->counter_enabled) { - /* Enable counter if it was not already running. */ + /* + * Enable counter if it was not already running. + * Some devices cannot use channel 2 and the counter + * at the same time. Some cannot respond right after + * enabling the counter and need a delay. + */ + + need_quirk = devc->quirks & RIGOL_DG_COUNTER_CH2_CONFLICT; + need_quirk &= devc->device->num_channels > 1; + if (need_quirk) { + sr_scpi_get_opc(scpi); + ret = sr_scpi_cmd_resp(sdi, devc->cmdset, + PSG_CMD_SELECT_CHANNEL, "2", + &data, G_VARIANT_TYPE_BOOLEAN, + PSG_CMD_GET_ENABLED, "2"); + if (ret != SR_OK) + return SR_ERR_NA; + ch_active = g_variant_get_boolean(data); + g_variant_unref(data); + if (ch_active) { + sr_scpi_get_opc(scpi); + ret = sr_scpi_cmd(sdi, devc->cmdset, + PSG_CMD_SELECT_CHANNEL, "2", + PSG_CMD_SET_DISABLE, "2"); + if (ret != SR_OK) + return SR_ERR_NA; + } + } + cmd = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_COUNTER_SET_ENABLE); if (!cmd) return SR_ERR_BUG; sr_scpi_get_opc(scpi); ret = sr_scpi_send(scpi, cmd); + + need_quirk = devc->quirks & RIGOL_DG_COUNTER_BUG; + if (need_quirk) + g_usleep(RIGOL_DG_COUNTER_BUG_DELAY); } } @@ -797,10 +857,13 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) if (cmd && *cmd && !devc->counter_enabled) { /* * If counter was not running when acquisiton started, - * turn it off now... + * turn it off now. Some devices need a delay after + * disabling the counter. */ sr_scpi_get_opc(scpi); ret = sr_scpi_send(scpi, cmd); + if (devc->quirks & RIGOL_DG_COUNTER_BUG) + g_usleep(RIGOL_DG_COUNTER_BUG_DELAY); } sr_scpi_source_remove(sdi->session, scpi); diff --git a/src/hardware/rigol-dg/protocol.h b/src/hardware/rigol-dg/protocol.h index bff7c208..5d1227d0 100644 --- a/src/hardware/rigol-dg/protocol.h +++ b/src/hardware/rigol-dg/protocol.h @@ -27,6 +27,12 @@ #define LOG_PREFIX "rigol-dg" +/* Device/firmware specific quirks. */ +#define RIGOL_DG_COUNTER_BUG (1UL << 0) +#define RIGOL_DG_COUNTER_CH2_CONFLICT (1UL << 1) + +#define RIGOL_DG_COUNTER_BUG_DELAY (1000 * 1000) + enum psg_commands { PSG_CMD_SETUP_REMOTE, PSG_CMD_SETUP_LOCAL, @@ -115,6 +121,7 @@ struct dev_context { struct channel_status *ch_status; struct sr_sw_limits limits; gboolean counter_enabled; + uint32_t quirks; }; SR_PRIV const char *rigol_dg_waveform_to_string(enum waveform_type type);