X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fhameg-hmo%2Fapi.c;h=f8fc644cbb2c99b4667451a9998a87a1b85c3059;hb=841aadc95b918fd883d36c6c8555f8cb0e3cd049;hp=4ed9527e5a154a071d023a79505a859a0c572a91;hpb=dd5c48a6d567a3cac62c4b0058588273bbeea171;p=libsigrok.git diff --git a/src/hardware/hameg-hmo/api.c b/src/hardware/hameg-hmo/api.c index 4ed9527e..f8fc644c 100644 --- a/src/hardware/hameg-hmo/api.c +++ b/src/hardware/hameg-hmo/api.c @@ -568,6 +568,11 @@ SR_PRIV int hmo_request_data(const struct sr_dev_inst *sdi) case SR_CHANNEL_ANALOG: g_snprintf(command, sizeof(command), (*model->scpi_dialect)[SCPI_CMD_GET_ANALOG_DATA], +#ifdef WORDS_BIGENDIAN + "MSBF", +#else + "LSBF", +#endif ch->index + 1); break; case SR_CHANNEL_LOGIC: @@ -587,34 +592,50 @@ static int hmo_check_channels(GSList *channels) { GSList *l; struct sr_channel *ch; - gboolean enabled_pod1, enabled_pod2, enabled_chan3, enabled_chan4; - - enabled_pod1 = enabled_pod2 = enabled_chan3 = enabled_chan4 = FALSE; - + gboolean enabled_chan[MAX_ANALOG_CHANNEL_COUNT]; + gboolean enabled_pod[MAX_DIGITAL_GROUP_COUNT]; + size_t idx; + + /* Preset "not enabled" for all channels / pods. */ + for (idx = 0; idx < ARRAY_SIZE(enabled_chan); idx++) + enabled_chan[idx] = FALSE; + for (idx = 0; idx < ARRAY_SIZE(enabled_pod); idx++) + enabled_pod[idx] = FALSE; + + /* + * Determine which channels / pods are required for the caller's + * specified configuration. + */ for (l = channels; l; l = l->next) { ch = l->data; switch (ch->type) { case SR_CHANNEL_ANALOG: - if (ch->index == 2) - enabled_chan3 = TRUE; - else if (ch->index == 3) - enabled_chan4 = TRUE; + idx = ch->index; + if (idx < ARRAY_SIZE(enabled_chan)) + enabled_chan[idx] = TRUE; break; case SR_CHANNEL_LOGIC: - if (ch->index < 8) - enabled_pod1 = TRUE; - else - enabled_pod2 = TRUE; + idx = ch->index / 8; + if (idx < ARRAY_SIZE(enabled_pod)) + enabled_pod[idx] = TRUE; break; default: return SR_ERR; } } - if ((enabled_pod1 && enabled_chan3) || - (enabled_pod2 && enabled_chan4)) + /* + * Check for resource conflicts. Some channels can be either + * analog or digital, but never both at the same time. + * + * Note that the constraints might depend on the specific model. + * These tests might need some adjustment when support for more + * models gets added to the driver. + */ + if (enabled_pod[0] && enabled_chan[2]) + return SR_ERR; + if (enabled_pod[1] && enabled_chan[3]) return SR_ERR; - return SR_OK; } @@ -701,55 +722,88 @@ static int hmo_setup_channels(const struct sr_dev_inst *sdi) static int dev_acquisition_start(const struct sr_dev_inst *sdi) { GSList *l; - gboolean digital_added; + gboolean digital_added[MAX_DIGITAL_GROUP_COUNT]; + size_t group, pod_count; struct sr_channel *ch; struct dev_context *devc; struct sr_scpi_dev_inst *scpi; + int ret; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; scpi = sdi->conn; devc = sdi->priv; - digital_added = FALSE; + /* Preset empty results. */ + for (group = 0; group < ARRAY_SIZE(digital_added); group++) + digital_added[group] = FALSE; g_slist_free(devc->enabled_channels); devc->enabled_channels = NULL; + /* + * Contruct the list of enabled channels. Determine the highest + * number of digital pods involved in the acquisition. + */ + pod_count = 0; for (l = sdi->channels; l; l = l->next) { ch = l->data; if (!ch->enabled) continue; - /* Only add a single digital channel. */ - if (ch->type != SR_CHANNEL_LOGIC || !digital_added) { + /* Only add a single digital channel per group (pod). */ + group = ch->index / 8; + if (ch->type != SR_CHANNEL_LOGIC || !digital_added[group]) { devc->enabled_channels = g_slist_append( devc->enabled_channels, ch); - if (ch->type == SR_CHANNEL_LOGIC) - digital_added = TRUE; + if (ch->type == SR_CHANNEL_LOGIC) { + digital_added[group] = TRUE; + if (pod_count < group + 1) + pod_count = group + 1; + } } } - if (!devc->enabled_channels) return SR_ERR; + devc->pod_count = pod_count; + devc->logic_data = NULL; + /* + * Check constraints. Some channels can be either analog or + * digital, but not both at the same time. + */ if (hmo_check_channels(devc->enabled_channels) != SR_OK) { sr_err("Invalid channel configuration specified!"); - return SR_ERR_NA; + ret = SR_ERR_NA; + goto free_enabled; } + /* + * Configure the analog and digital channels and the + * corresponding digital pods. + */ if (hmo_setup_channels(sdi) != SR_OK) { sr_err("Failed to setup channel configuration!"); - return SR_ERR; + ret = SR_ERR; + goto free_enabled; } + /* + * Start acquisition on the first enabled channel. The + * receive routine will continue driving the acquisition. + */ sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50, hmo_receive_data, (void *)sdi); - std_session_send_df_header(sdi, LOG_PREFIX); + std_session_send_df_header(sdi); devc->current_channel = devc->enabled_channels; return hmo_request_data(sdi); + +free_enabled: + g_slist_free(devc->enabled_channels); + devc->enabled_channels = NULL; + return ret; } static int dev_acquisition_stop(struct sr_dev_inst *sdi) @@ -757,7 +811,7 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) struct dev_context *devc; struct sr_scpi_dev_inst *scpi; - std_session_send_df_end(sdi, LOG_PREFIX); + std_session_send_df_end(sdi); if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED;