]> sigrok.org Git - libsigrok.git/commitdiff
yokogawa-dlm: Introduce config_channel_set()
authorSoeren Apel <redacted>
Sun, 7 Jun 2015 09:50:29 +0000 (11:50 +0200)
committerUwe Hermann <redacted>
Mon, 22 Jun 2015 22:15:56 +0000 (00:15 +0200)
src/hardware/yokogawa-dlm/api.c
src/hardware/yokogawa-dlm/protocol.c
src/hardware/yokogawa-dlm/protocol.h

index 0ccf5834e157638aac443d69708a5230a8fceb46..9a1c6a001c345e64837af4abd109ce2f05e9a109 100644 (file)
@@ -491,6 +491,16 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
        return ret;
 }
 
+static int config_channel_set(const struct sr_dev_inst *sdi,
+                       struct sr_channel *ch, unsigned int changes)
+{
+       /* Curretly we only handle SR_CHANNEL_SET_ENABLED. */
+       if (changes != SR_CHANNEL_SET_ENABLED)
+               return SR_ERR_NA;
+
+       return dlm_channel_state_set(sdi, ch->index, ch->enabled);
+}
+
 static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
                const struct sr_channel_group *cg)
 {
@@ -778,6 +788,7 @@ SR_PRIV struct sr_dev_driver yokogawa_dlm_driver_info = {
        .dev_clear = dev_clear,
        .config_get = config_get,
        .config_set = config_set,
+       .config_channel_set = config_channel_set,
        .config_list = config_list,
        .dev_open = dev_open,
        .dev_close = dev_close,
index a60bc0d3208d3f103400e50ba335fe33d54fa6b3..e833389c815ef0e2e1aaf8d689f76f18a067b963 100644 (file)
@@ -410,25 +410,38 @@ static int array_float_get(gchar *value, const uint64_t array[][2],
  * Obtains information about all analog channels from the oscilloscope.
  * The internal state information is updated accordingly.
  *
- * @param scpi An open SCPI connection.
+ * @param sdi The device instance.
  * @param config The device's device configuration.
  * @param state The device's state information.
  *
  * @return SR_ERR on error, SR_OK otherwise.
  */
-static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
+static int analog_channel_state_get(const struct sr_dev_inst *sdi,
                const struct scope_config *config,
                struct scope_state *state)
 {
+       struct sr_scpi_dev_inst *scpi;
        int i, j;
+       GSList *l;
+       struct sr_channel *ch;
        gchar *response;
 
+       scpi = sdi->conn;
+
        for (i = 0; i < config->analog_channels; ++i) {
 
                if (dlm_analog_chan_state_get(scpi, i + 1,
                                &state->analog_states[i].state) != SR_OK)
                        return SR_ERR;
 
+               for (l = sdi->channels; l; l = l->next) {
+                       ch = l->data;
+                       if (ch->index == i) {
+                               ch->enabled = state->analog_states[i].state;
+                               break;
+                       }
+               }
+
                if (dlm_analog_chan_vdiv_get(scpi, i + 1, &response) != SR_OK)
                        return SR_ERR;
 
@@ -473,17 +486,22 @@ static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
  * Obtains information about all digital channels from the oscilloscope.
  * The internal state information is updated accordingly.
  *
- * @param scpi An open SCPI connection.
+ * @param sdi The device instance.
  * @param config The device's device configuration.
  * @param state The device's state information.
  *
  * @return SR_ERR on error, SR_OK otherwise.
  */
-static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
+static int digital_channel_state_get(const struct sr_dev_inst *sdi,
                const struct scope_config *config,
                struct scope_state *state)
 {
-       unsigned int i;
+       struct sr_scpi_dev_inst *scpi;
+       int i;
+       GSList *l;
+       struct sr_channel *ch;
+
+       scpi = sdi->conn;
 
        if (!config->digital_channels)
                {
@@ -497,6 +515,14 @@ static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
                                &state->digital_states[i]) != SR_OK) {
                        return SR_ERR;
                }
+
+               for (l = sdi->channels; l; l = l->next) {
+                       ch = l->data;
+                       if (ch->index == i + DLM_DIG_CHAN_INDEX_OFFS) {
+                               ch->enabled = state->digital_states[i];
+                               break;
+                       }
+               }
        }
 
        if (!config->pods)
@@ -514,6 +540,93 @@ static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
        return SR_OK;
 }
 
+/**
+ *
+ */
+SR_PRIV int dlm_channel_state_set(const struct sr_dev_inst *sdi,
+               const int ch_index, gboolean ch_state)
+{
+       GSList *l;
+       struct sr_channel *ch;
+       struct dev_context *devc = NULL;
+       struct scope_state *state;
+       const struct scope_config *model = NULL;
+       struct sr_scpi_dev_inst *scpi;
+       gboolean chan_found;
+       gboolean *pod_enabled;
+       int i, result;
+
+       result = SR_OK;
+
+       scpi = sdi->conn;
+       devc = sdi->priv;
+       state = devc->model_state;
+       model = devc->model_config;
+       chan_found = FALSE;
+
+       pod_enabled = g_malloc0(sizeof(gboolean) * model->pods);
+
+       for (l = sdi->channels; l; l = l->next) {
+               ch = l->data;
+
+               switch (ch->type) {
+               case SR_CHANNEL_ANALOG:
+                       if (ch->index == ch_index) {
+                               if (dlm_analog_chan_state_set(scpi, ch->index + 1, ch_state) != SR_OK) {
+                                       result = SR_ERR;
+                                       break;
+                               }
+
+                               ch->enabled = ch_state;
+                               state->analog_states[ch->index].state = ch_state;
+                               chan_found = TRUE;
+                               break;
+                       }
+                       break;
+               case SR_CHANNEL_LOGIC:
+                       i = ch->index - DLM_DIG_CHAN_INDEX_OFFS;
+
+                       if (ch->index == ch_index) {
+                               if (dlm_digital_chan_state_set(scpi, i + 1, ch_state) != SR_OK) {
+                                       result = SR_ERR;
+                                       break;
+                               }
+
+                       ch->enabled = ch_state;
+                       state->digital_states[i] = ch_state;
+                       chan_found = TRUE;
+
+                       /* The corresponding pod has to be enabled also. */
+                       pod_enabled[i / 8] |= ch->enabled;
+                       } else
+                               /* Also check all other channels. Maybe we can disable a pod. */
+                               pod_enabled[i / 8] |= ch->enabled;
+                       break;
+               default:
+                       result = SR_ERR_NA;
+               }
+       }
+
+       for (i = 0; i < model->pods; ++i) {
+               if (state->pod_states[i] == pod_enabled[i])
+                       continue;
+
+               if (dlm_digital_pod_state_set(scpi, i + 1, pod_enabled[i]) != SR_OK) {
+                       result = SR_ERR;
+                       break;
+               }
+
+               state->pod_states[i] = pod_enabled[i];
+       }
+
+       g_free(pod_enabled);
+
+       if ((result == SR_OK) && !chan_found)
+               result = SR_ERR_BUG;
+
+       return result;
+}
+
 /**
  * Obtains information about the sample rate from the oscilloscope.
  * The internal state information is updated accordingly.
@@ -564,10 +677,10 @@ SR_PRIV int dlm_scope_state_query(struct sr_dev_inst *sdi)
        config = devc->model_config;
        state = devc->model_state;
 
-       if (analog_channel_state_get(sdi->conn, config, state) != SR_OK)
+       if (analog_channel_state_get(sdi, config, state) != SR_OK)
                return SR_ERR;
 
-       if (digital_channel_state_get(sdi->conn, config, state) != SR_OK)
+       if (digital_channel_state_get(sdi, config, state) != SR_OK)
                return SR_ERR;
 
        if (dlm_timebase_get(sdi->conn, &response) != SR_OK)
index 3ae9243329b6862867c09ed899f1c450a819693d..c5e7d5609daabe2fb301f0fe439d2eebbbfbc2ff 100644 (file)
@@ -113,6 +113,8 @@ struct dev_context {
        gboolean data_pending;
 };
 
+SR_PRIV int dlm_channel_state_set(const struct sr_dev_inst *sdi,
+               const int ch_index, gboolean state);
 SR_PRIV int dlm_data_request(const struct sr_dev_inst *sdi);
 SR_PRIV int dlm_model_get(char *model_id, char **model_name, int *model_index);
 SR_PRIV int dlm_device_init(struct sr_dev_inst *sdi, int model_index);