static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { GSList *l; gboolean digital_added; struct sr_channel *ch; struct dev_context *devc; struct sr_scpi_dev_inst *scpi; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; scpi = sdi->conn; devc = sdi->priv; digital_added = FALSE; g_slist_free(devc->enabled_channels); devc->enabled_channels = NULL; 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) { devc->enabled_channels = g_slist_append( devc->enabled_channels, ch); if (ch->type == SR_CHANNEL_LOGIC) digital_added = TRUE; } } if (!devc->enabled_channels) return SR_ERR; if (hmo_check_channels(devc->enabled_channels) != SR_OK) { sr_err("Invalid channel configuration specified!"); return SR_ERR_NA; } if (hmo_setup_channels(sdi) != SR_OK) { sr_err("Failed to setup channel configuration!"); return SR_ERR; } sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50, hmo_receive_data, (void *)sdi); /* Send header packet to the session bus. */ std_session_send_df_header(cb_data, LOG_PREFIX); devc->current_channel = devc->enabled_channels; return hmo_request_data(sdi); }
SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data) { struct sr_channel *ch; struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_datafeed_packet packet; GArray *data; struct sr_datafeed_analog analog; struct sr_datafeed_logic logic; (void)fd; data = NULL; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; if (revents != G_IO_IN) return TRUE; ch = devc->current_channel->data; switch (ch->type) { case SR_CHANNEL_ANALOG: if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) { if (data) g_array_free(data, TRUE); return TRUE; } packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); analog.channels = g_slist_append(NULL, ch); analog.num_samples = data->len; analog.data = (float *) data->data; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = 0; packet.type = SR_DF_ANALOG; packet.payload = &analog; sr_session_send(cb_data, &packet); g_slist_free(analog.channels); g_array_free(data, TRUE); data = NULL; break; case SR_CHANNEL_LOGIC: if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) { g_free(data); return TRUE; } packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); logic.length = data->len; logic.unitsize = 1; logic.data = data->data; packet.type = SR_DF_LOGIC; packet.payload = &logic; sr_session_send(cb_data, &packet); g_array_free(data, TRUE); data = NULL; break; default: sr_err("Invalid channel type."); break; } packet.type = SR_DF_FRAME_END; sr_session_send(sdi, &packet); if (devc->current_channel->next) { devc->current_channel = devc->current_channel->next; hmo_request_data(sdi); } else if (++devc->num_frames == devc->frame_limit) { sdi->driver->dev_acquisition_stop(sdi, cb_data); } else { devc->current_channel = devc->enabled_channels; hmo_request_data(sdi); } return TRUE; }
static int dev_acquisition_start(const struct sr_dev_inst *sdi) { GSList *l; 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; scpi = sdi->conn; devc = sdi->priv; /* 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 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[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!"); 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!"); 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); 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; }
SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data) { struct sr_channel *ch; struct sr_dev_inst *sdi; struct dev_context *devc; struct scope_state *state; struct sr_datafeed_packet packet; GByteArray *data; struct sr_datafeed_analog analog; struct sr_analog_encoding encoding; struct sr_analog_meaning meaning; struct sr_analog_spec spec; struct sr_datafeed_logic logic; (void)fd; (void)revents; data = NULL; if (!(sdi = cb_data)) return TRUE; if (!(devc = sdi->priv)) return TRUE; /* Although this is correct in general, the USBTMC libusb implementation * currently does not generate an event prior to the first read. Often * it is ok to start reading just after the 50ms timeout. See bug #785. if (revents != G_IO_IN) return TRUE; */ ch = devc->current_channel->data; state = devc->model_state; switch (ch->type) { case SR_CHANNEL_ANALOG: if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) { if (data) g_byte_array_free(data, TRUE); return TRUE; } packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); packet.type = SR_DF_ANALOG; analog.data = data->data; analog.num_samples = data->len / sizeof(float); analog.encoding = &encoding; analog.meaning = &meaning; analog.spec = &spec; encoding.unitsize = sizeof(float); encoding.is_signed = TRUE; encoding.is_float = TRUE; encoding.is_bigendian = FALSE; encoding.digits = 0; encoding.is_digits_decimal = FALSE; encoding.scale.p = 1; encoding.scale.q = 1; encoding.offset.p = 0; encoding.offset.q = 1; if (state->analog_channels[ch->index].probe_unit == 'V') { meaning.mq = SR_MQ_VOLTAGE; meaning.unit = SR_UNIT_VOLT; } else { meaning.mq = SR_MQ_CURRENT; meaning.unit = SR_UNIT_AMPERE; } meaning.mqflags = 0; meaning.channels = g_slist_append(NULL, ch); spec.spec_digits = 0; packet.payload = &analog; sr_session_send(sdi, &packet); g_slist_free(meaning.channels); g_byte_array_free(data, TRUE); data = NULL; break; case SR_CHANNEL_LOGIC: if (sr_scpi_get_block(sdi->conn, NULL, &data) != SR_OK) { g_free(data); return TRUE; } packet.type = SR_DF_FRAME_BEGIN; sr_session_send(sdi, &packet); logic.length = data->len; logic.unitsize = 1; logic.data = data->data; packet.type = SR_DF_LOGIC; packet.payload = &logic; sr_session_send(sdi, &packet); g_byte_array_free(data, TRUE); data = NULL; break; default: sr_err("Invalid channel type."); break; } packet.type = SR_DF_FRAME_END; sr_session_send(sdi, &packet); if (devc->current_channel->next) { devc->current_channel = devc->current_channel->next; hmo_request_data(sdi); } else if (++devc->num_frames == devc->frame_limit) { sdi->driver->dev_acquisition_stop(sdi); } else { devc->current_channel = devc->enabled_channels; hmo_request_data(sdi); } return TRUE; }