+SR_PRIV const char *rigol_dg_waveform_to_string(enum waveform_type type)
+{
+ switch (type) {
+ case WF_DC:
+ return "DC";
+ case WF_SINE:
+ return "Sine";
+ case WF_SQUARE:
+ return "Square";
+ case WF_RAMP:
+ return "Ramp";
+ case WF_PULSE:
+ return "Pulse";
+ case WF_NOISE:
+ return "Noise";
+ case WF_ARB:
+ return "Arb";
+ }
+
+ return "Unknown";
+}
+
+SR_PRIV const struct waveform_spec *rigol_dg_get_waveform_spec(
+ const struct channel_spec *ch, enum waveform_type wf)
+{
+ const struct waveform_spec *spec;
+ unsigned int i;
+
+ spec = NULL;
+ for (i = 0; i < ch->num_waveforms; i++) {
+ if (ch->waveforms[i].waveform == wf) {
+ spec = &ch->waveforms[i];
+ break;
+ }
+ }
+
+ return spec;
+}
+
+SR_PRIV int rigol_dg_get_channel_state(const struct sr_dev_inst *sdi,
+ const struct sr_channel_group *cg)
+{
+ struct dev_context *devc;
+ struct sr_scpi_dev_inst *scpi;
+ struct sr_channel *ch;
+ struct channel_status *ch_status;
+ const char *command;
+ GVariant *data;
+ gchar *response, **params;
+ const gchar *s;
+ enum waveform_type wf;
+ double freq, ampl, offset, phase;
+ int ret;
+
+ devc = sdi->priv;
+ scpi = sdi->conn;
+ data = NULL;
+ params = NULL;
+ response = NULL;
+ ret = SR_ERR_NA;
+
+ if (!sdi || !cg)
+ return SR_ERR_BUG;
+
+ ch = cg->channels->data;
+ ch_status = &devc->ch_status[ch->index];
+
+ command = sr_scpi_cmd_get(devc->cmdset, PSG_CMD_GET_SOURCE);
+ if (command && *command) {
+ sr_scpi_get_opc(scpi);
+ ret = sr_scpi_cmd_resp(sdi, devc->cmdset,
+ PSG_CMD_SELECT_CHANNEL, cg->name, &data,
+ G_VARIANT_TYPE_STRING, PSG_CMD_GET_SOURCE, cg->name);
+ if (ret != SR_OK)
+ goto done;
+ response = g_variant_dup_string(data, NULL);
+ g_strstrip(response);
+ s = sr_scpi_unquote_string(response);
+ sr_spew("Channel state: '%s'", s);
+ params = g_strsplit(s, ",", 0);
+ if (!params[0])
+ goto done;
+
+ /* First parameter is the waveform type */
+ if (!(s = params[0]))
+ goto done;
+ if (g_ascii_strncasecmp(s, "SIN", strlen("SIN")) == 0)
+ wf = WF_SINE;
+ else if (g_ascii_strncasecmp(s, "SQU", strlen("SQU")) == 0)
+ wf = WF_SQUARE;
+ else if (g_ascii_strncasecmp(s, "RAMP", strlen("RAMP")) == 0)
+ wf = WF_RAMP;
+ else if (g_ascii_strncasecmp(s, "PULSE", strlen("PULSE")) == 0)
+ wf = WF_PULSE;
+ else if (g_ascii_strncasecmp(s, "NOISE", strlen("NOISE")) == 0)
+ wf = WF_NOISE;
+ else if (g_ascii_strncasecmp(s, "USER", strlen("USER")) == 0)
+ wf = WF_ARB;
+ else if (g_ascii_strncasecmp(s, "DC", strlen("DC")) == 0)
+ wf = WF_DC;
+ else
+ goto done;
+ ch_status->wf = wf;
+ ch_status->wf_spec = rigol_dg_get_waveform_spec(
+ &devc->device->channels[ch->index], wf);
+
+ /* Second parameter if the frequency (or "DEF" if not applicable) */
+ if (!(s = params[1]))
+ goto done;
+ freq = g_ascii_strtod(s, NULL);
+ ch_status->freq = freq;
+
+ /* Third parameter if the amplitude (or "DEF" if not applicable) */
+ if (!(s = params[2]))
+ goto done;
+ ampl = g_ascii_strtod(s, NULL);
+ ch_status->ampl = ampl;
+
+ /* Fourth parameter if the offset (or "DEF" if not applicable) */
+ if (!(s = params[3]))
+ goto done;
+ offset = g_ascii_strtod(s, NULL);
+ ch_status->offset = offset;
+
+ /* Fifth parameter if the phase (or "DEF" if not applicable) */
+ if (!(s = params[4]))
+ goto done;
+ phase = g_ascii_strtod(s, NULL);
+ ch_status->phase = phase;
+
+ ret = SR_OK;
+ }
+
+done:
+ g_variant_unref(data);
+ g_free(response);
+ g_strfreev(params);
+ return ret;
+}
+
+static void rigol_dg_send_channel_value(const struct sr_dev_inst *sdi,
+ struct sr_channel *ch, double value, enum sr_mq mq,
+ enum sr_unit unit, int digits)
+{
+ struct sr_datafeed_packet packet;
+ struct sr_datafeed_analog analog;
+ struct sr_analog_encoding encoding;
+ struct sr_analog_meaning meaning;
+ struct sr_analog_spec spec;
+ double val;
+
+ val = value;
+ sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
+ analog.meaning->channels = g_slist_append(NULL, ch);
+ analog.num_samples = 1;
+ analog.data = &val;
+ analog.encoding->unitsize = sizeof(val);
+ analog.encoding->is_float = TRUE;
+ analog.encoding->digits = digits;
+ analog.meaning->mq = mq;
+ analog.meaning->unit = unit;
+
+ packet.type = SR_DF_ANALOG;
+ packet.payload = &analog;
+ sr_session_send(sdi, &packet);
+ g_slist_free(analog.meaning->channels);
+}
+