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)
|
static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
|
||||||
{
|
{
|
||||||
struct sr_dev_inst *sdi;
|
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);
|
sr_scpi_hw_info_free(hw_info);
|
||||||
|
|
||||||
|
/* Check for device/firmware specific issues. */
|
||||||
|
check_device_quirks(sdi);
|
||||||
|
|
||||||
return sdi;
|
return sdi;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -729,6 +753,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
struct sr_scpi_dev_inst *scpi;
|
struct sr_scpi_dev_inst *scpi;
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
char *response;
|
char *response;
|
||||||
|
GVariant *data;
|
||||||
|
gboolean need_quirk;
|
||||||
|
gboolean ch_active;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!sdi)
|
if (!sdi)
|
||||||
|
@ -737,6 +764,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
scpi = sdi->conn;
|
scpi = sdi->conn;
|
||||||
response = NULL;
|
response = NULL;
|
||||||
|
data = NULL;
|
||||||
ret = SR_OK;
|
ret = SR_OK;
|
||||||
|
|
||||||
if (!scpi)
|
if (!scpi)
|
||||||
|
@ -754,13 +782,45 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
|
||||||
devc->counter_enabled = FALSE;
|
devc->counter_enabled = FALSE;
|
||||||
|
|
||||||
if (!devc->counter_enabled) {
|
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,
|
cmd = sr_scpi_cmd_get(devc->cmdset,
|
||||||
PSG_CMD_COUNTER_SET_ENABLE);
|
PSG_CMD_COUNTER_SET_ENABLE);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return SR_ERR_BUG;
|
return SR_ERR_BUG;
|
||||||
sr_scpi_get_opc(scpi);
|
sr_scpi_get_opc(scpi);
|
||||||
ret = sr_scpi_send(scpi, cmd);
|
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 (cmd && *cmd && !devc->counter_enabled) {
|
||||||
/*
|
/*
|
||||||
* If counter was not running when acquisiton started,
|
* 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);
|
sr_scpi_get_opc(scpi);
|
||||||
ret = sr_scpi_send(scpi, cmd);
|
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);
|
sr_scpi_source_remove(sdi->session, scpi);
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
|
|
||||||
#define LOG_PREFIX "rigol-dg"
|
#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 {
|
enum psg_commands {
|
||||||
PSG_CMD_SETUP_REMOTE,
|
PSG_CMD_SETUP_REMOTE,
|
||||||
PSG_CMD_SETUP_LOCAL,
|
PSG_CMD_SETUP_LOCAL,
|
||||||
|
@ -115,6 +121,7 @@ struct dev_context {
|
||||||
struct channel_status *ch_status;
|
struct channel_status *ch_status;
|
||||||
struct sr_sw_limits limits;
|
struct sr_sw_limits limits;
|
||||||
gboolean counter_enabled;
|
gboolean counter_enabled;
|
||||||
|
uint32_t quirks;
|
||||||
};
|
};
|
||||||
|
|
||||||
SR_PRIV const char *rigol_dg_waveform_to_string(enum waveform_type type);
|
SR_PRIV const char *rigol_dg_waveform_to_string(enum waveform_type type);
|
||||||
|
|
Loading…
Reference in New Issue