X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Frigol-dg%2Fapi.c;h=a173243264576e2a0ff6e8859d03e240f464f080;hb=64414853067e727f99c7d41851ac635d4342f17b;hp=43121aed57c02cf79685065075fb50fe5674ae9d;hpb=d999f2b61e96882aed01fd58cbf45e773b855009;p=libsigrok.git diff --git a/src/hardware/rigol-dg/api.c b/src/hardware/rigol-dg/api.c index 43121aed..a1732432 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; @@ -359,12 +380,9 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi) for (i = 0; i < device->num_channels; i++) { ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE, device->channels[i].name); - cg = g_malloc0(sizeof(*cg)); snprintf(tmp, sizeof(tmp), "%u", i + 1); - cg->name = g_strdup(tmp); + cg = sr_channel_group_new(sdi, tmp, NULL); cg->channels = g_slist_append(cg->channels, ch); - - sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } /* Create channels for the frequency counter output. */ @@ -382,6 +400,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 +750,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 +761,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) @@ -752,15 +777,48 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) devc->counter_enabled = TRUE; else devc->counter_enabled = FALSE; + g_free(response); 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); } } @@ -774,8 +832,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) } } - g_free(response); - return ret; } @@ -797,10 +853,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);