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.
This commit is contained in:
parent
92cd85149a
commit
b1eb94bbef
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue