Always interleave analog data with all enabled probes.

The new "probes" field in sr_datafeed_analog contains a copy
of all enabled struct sr_probe.
This commit is contained in:
Bert Vermeulen 2013-01-23 03:40:44 +01:00
parent b1a051544d
commit 69e19dd769
17 changed files with 85 additions and 41 deletions

View File

@ -263,6 +263,7 @@ static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match)
analog.mq = devc->cur_mq;
analog.unit = devc->cur_unit;
analog.mqflags = devc->cur_mqflags;
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &fvalue;
packet.type = SR_DF_ANALOG;

View File

@ -396,6 +396,7 @@ SR_PRIV int alsa_receive_data(int fd, int revents, void *cb_data)
}
/* Send a sample packet with the analog values. */
analog.probes = sdi->probes;
analog.num_samples = count;
analog.mq = SR_MQ_VOLTAGE; /* FIXME */
analog.unit = SR_UNIT_VOLT; /* FIXME */

View File

@ -75,6 +75,7 @@ static void process_packet(const struct sr_dev_inst *sdi)
memset(&analog, 0, sizeof(struct sr_datafeed_analog));
analog.mq = SR_MQ_SOUND_PRESSURE_LEVEL;
analog.unit = SR_UNIT_DECIBEL_SPL;
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &fvalue;

View File

@ -55,11 +55,12 @@ static struct sr_datafeed_analog *handle_qm_18x(const struct sr_dev_inst *sdi,
while(*e && *e == ' ')
e++;
/* TODO: Check malloc return value. */
analog = g_try_malloc0(sizeof(struct sr_datafeed_analog));
if (!(analog = g_try_malloc0(sizeof(struct sr_datafeed_analog))))
return NULL;
if (!(analog->data = g_try_malloc(sizeof(float))))
return NULL;
analog->probes = sdi->probes;
analog->num_samples = 1;
/* TODO: Check malloc return value. */
analog->data = g_try_malloc(sizeof(float));
if (is_oor)
*analog->data = NAN;
else
@ -169,11 +170,12 @@ static struct sr_datafeed_analog *handle_qm_28x(const struct sr_dev_inst *sdi,
return NULL;
}
/* TODO: Check malloc return value. */
analog = g_try_malloc0(sizeof(struct sr_datafeed_analog));
if (!(analog = g_try_malloc0(sizeof(struct sr_datafeed_analog))))
return NULL;
if (!(analog->data = g_try_malloc(sizeof(float))))
return NULL;
analog->probes = sdi->probes;
analog->num_samples = 1;
/* TODO: Check malloc return value. */
analog->data = g_try_malloc(sizeof(float));
*analog->data = fvalue;
analog->mq = -1;
@ -396,6 +398,7 @@ static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens)
fvalue = 1.0;
}
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &fvalue;
analog.mq = devc->mq;

View File

@ -202,18 +202,22 @@ static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof
static int configure_probes(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
const struct sr_probe *probe;
struct sr_probe *probe;
const GSList *l;
int p;
devc = sdi->priv;
g_slist_free(devc->enabled_probes);
devc->ch1_enabled = devc->ch2_enabled = FALSE;
for (l = sdi->probes; l; l = l->next) {
probe = (struct sr_probe *)l->data;
if (probe->index == 0)
for (l = sdi->probes, p = 0; l; l = l->next, p++) {
probe = l->data;
if (p == 0)
devc->ch1_enabled = probe->enabled;
else if (probe->index == 1)
else
devc->ch2_enabled = probe->enabled;
if (probe->enabled)
devc->enabled_probes = g_slist_append(devc->enabled_probes, probe);
}
return SR_OK;
@ -242,6 +246,7 @@ static int clear_instances(void)
dso_close(sdi);
sr_usb_dev_inst_free(devc->usb);
g_free(devc->triggersource);
g_slist_free(devc->enabled_probes);
sr_dev_inst_free(sdi);
}
@ -577,18 +582,21 @@ static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
return ret;
}
static void send_chunk(struct dev_context *devc, unsigned char *buf,
static void send_chunk(struct sr_dev_inst *sdi, unsigned char *buf,
int num_samples)
{
struct sr_datafeed_packet packet;
struct sr_datafeed_analog analog;
struct dev_context *devc;
float ch1, ch2, range;
int num_probes, data_offset, i;
devc = sdi->priv;
num_probes = (devc->ch1_enabled && devc->ch2_enabled) ? 2 : 1;
packet.type = SR_DF_ANALOG;
packet.payload = &analog;
/* TODO: support for 5xxx series 9-bit samples */
analog.probes = devc->enabled_probes;
analog.num_samples = num_samples;
analog.mq = SR_MQ_VOLTAGE;
analog.unit = SR_UNIT_VOLT;
@ -635,10 +643,12 @@ static void send_chunk(struct dev_context *devc, unsigned char *buf,
static void receive_transfer(struct libusb_transfer *transfer)
{
struct sr_datafeed_packet packet;
struct sr_dev_inst *sdi;
struct dev_context *devc;
int num_samples, pre;
devc = transfer->user_data;
sdi = transfer->user_data;
devc = sdi->priv;
sr_dbg("receive_transfer(): status %d received %d bytes.",
transfer->status, transfer->actual_length);
@ -685,12 +695,12 @@ static void receive_transfer(struct libusb_transfer *transfer)
/* Avoid the corner case where the chunk ended at
* exactly the trigger point. */
if (num_samples > pre)
send_chunk(devc, transfer->buffer + pre * 2,
send_chunk(sdi, transfer->buffer + pre * 2,
num_samples - pre);
}
} else {
/* Already past the trigger point, just send it all out. */
send_chunk(devc, transfer->buffer,
send_chunk(sdi, transfer->buffer,
num_samples);
}
@ -706,7 +716,7 @@ static void receive_transfer(struct libusb_transfer *transfer)
* pre-trigger samples out now, in one big chunk. */
sr_dbg("End of frame, sending %d pre-trigger buffered samples.",
devc->samp_buffered);
send_chunk(devc, devc->framebuf, devc->samp_buffered);
send_chunk(sdi, devc->framebuf, devc->samp_buffered);
/* Mark the end of this frame. */
packet.type = SR_DF_FRAME_END;
@ -808,7 +818,7 @@ static int handle_event(int fd, int revents, void *cb_data)
devc->samp_buffered = devc->samp_received = 0;
/* Tell the scope to send us the first frame. */
if (dso_get_channeldata(devc, receive_transfer) != SR_OK)
if (dso_get_channeldata(sdi, receive_transfer) != SR_OK)
break;
/*

View File

@ -707,13 +707,16 @@ SR_PRIV int dso_capture_start(struct dev_context *devc)
return SR_OK;
}
SR_PRIV int dso_get_channeldata(struct dev_context *devc, libusb_transfer_cb_fn cb)
SR_PRIV int dso_get_channeldata(const struct sr_dev_inst *sdi,
libusb_transfer_cb_fn cb)
{
struct dev_context *devc;
struct libusb_transfer *transfer;
int num_transfers, ret, i;
uint8_t cmdstring[2];
unsigned char *buf;
devc = sdi->priv;
sr_dbg("Sending CMD_GET_CHANNELDATA.");
cmdstring[0] = CMD_GET_CHANNELDATA;
@ -737,7 +740,7 @@ SR_PRIV int dso_get_channeldata(struct dev_context *devc, libusb_transfer_cb_fn
transfer = libusb_alloc_transfer(0);
libusb_fill_bulk_transfer(transfer, devc->usb->devhdl,
DSO_EP_IN | LIBUSB_ENDPOINT_IN, buf,
devc->epin_maxpacketsize, cb, devc, 40);
devc->epin_maxpacketsize, cb, (void *)sdi, 40);
if ((ret = libusb_submit_transfer(transfer)) != 0) {
sr_err("Failed to submit transfer: %s.",
libusb_error_name(ret));

View File

@ -163,6 +163,7 @@ struct dev_context {
void *cb_data;
uint64_t limit_frames;
uint64_t num_frames;
GSList *enabled_probes;
/* We can't keep track of an FX2-based device after upgrading
* the firmware (it re-enumerates into a different device address
* after the upgrade) this is like a global lock. No device will open
@ -210,7 +211,7 @@ SR_PRIV int dso_init(struct dev_context *devc);
SR_PRIV int dso_get_capturestate(struct dev_context *devc,
uint8_t *capturestate, uint32_t *trigger_offset);
SR_PRIV int dso_capture_start(struct dev_context *devc);
SR_PRIV int dso_get_channeldata(struct dev_context *devc,
SR_PRIV int dso_get_channeldata(const struct sr_dev_inst *sdi,
libusb_transfer_cb_fn cb);
#endif

View File

@ -387,6 +387,8 @@ static void lascar_el_usb_dispatch(struct sr_dev_inst *sdi, unsigned char *buf,
int samples, samples_left, i, j;
devc = sdi->priv;
analog.probes = sdi->probes;
samples = buflen / devc->sample_size;
samples_left = devc->logged_samples - devc->rcvd_samples;
if (samples_left < samples)

View File

@ -138,6 +138,7 @@ static int clear_instances(void)
continue;
g_free(devc->device);
g_slist_free(devc->enabled_probes);
close(devc->fd);
sr_dev_inst_free(sdi);
@ -464,6 +465,8 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
gettimeofday(&header.starttime, NULL);
sr_session_send(cb_data, &packet);
/* Hardcoded to CH1 only. */
devc->enabled_probes = g_slist_append(NULL, sdi->probes->data);
rigol_ds1xx2_send_data(devc->fd, ":CHAN1:SCAL?\n");
len = read(devc->fd, buf, sizeof(buf));
buf[len] = 0;

View File

@ -49,6 +49,7 @@ SR_PRIV int rigol_ds1xx2_receive_data(int fd, int revents, void *cb_data)
return TRUE;
for (i = 0; i < len; i++)
data[i] = devc->scale / 25.6 * (128 - buf[i]) - devc->offset;
analog.probes = devc->enabled_probes;
analog.num_samples = len;
analog.data = data;
analog.mq = SR_MQ_VOLTAGE;

View File

@ -66,6 +66,8 @@ struct dev_context {
/** USBTMC character device file descriptor. */
int fd;
GSList *enabled_probes;
};
SR_PRIV int rigol_ds1xx2_receive_data(int fd, int revents, void *cb_data);

View File

@ -85,20 +85,23 @@ SR_PRIV void dmm_details_pce_dm32(struct sr_datafeed_analog *analog, void *info)
}
}
static void handle_packet(const uint8_t *buf, struct dev_context *devc,
static void handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi,
int dmm, void *info)
{
float floatval;
struct sr_datafeed_packet packet;
struct sr_datafeed_analog *analog;
struct dev_context *devc;
log_dmm_packet(buf);
devc = sdi->priv;
if (!(analog = g_try_malloc0(sizeof(struct sr_datafeed_analog)))) {
sr_err("Analog packet malloc failed.");
return;
}
analog->probes = sdi->probes;
analog->num_samples = 1;
analog->mq = -1;
@ -120,10 +123,13 @@ static void handle_packet(const uint8_t *buf, struct dev_context *devc,
g_free(analog);
}
static void handle_new_data(struct dev_context *devc, int dmm, void *info)
static void handle_new_data(struct sr_dev_inst *sdi, int dmm, void *info)
{
struct dev_context *devc;
int len, i, offset = 0;
devc = sdi->priv;
/* Try to get as much data as the buffer can hold. */
len = DMM_BUFSIZE - devc->buflen;
len = serial_read(devc->serial, devc->buf + devc->buflen, len);
@ -136,7 +142,7 @@ static void handle_new_data(struct dev_context *devc, int dmm, void *info)
/* Now look for packets in that data. */
while ((devc->buflen - offset) >= dmms[dmm].packet_size) {
if (dmms[dmm].packet_valid(devc->buf + offset)) {
handle_packet(devc->buf + offset, devc, dmm, info);
handle_packet(devc->buf + offset, sdi, dmm, info);
offset += dmms[dmm].packet_size;
} else {
offset++;
@ -166,7 +172,7 @@ static int receive_data(int fd, int revents, int dmm, void *info, void *cb_data)
if (revents == G_IO_IN) {
/* Serial data arrived. */
handle_new_data(devc, dmm, info);
handle_new_data(sdi, dmm, info);
} else {
/* Timeout, send another packet request (if DMM needs it). */
if (dmms[dmm].packet_request) {

View File

@ -85,17 +85,20 @@ static void parse_packet(const uint8_t *buf, float *floatval,
(void)level;
}
static void decode_packet(struct dev_context *devc)
static void decode_packet(struct sr_dev_inst *sdi)
{
struct sr_datafeed_packet packet;
struct sr_datafeed_analog analog;
struct dev_context *devc;
float floatval;
devc = sdi->priv;
memset(&analog, 0, sizeof(struct sr_datafeed_analog));
parse_packet(devc->buf, &floatval, &analog);
/* Send a sample packet with one analog value. */
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &floatval;
packet.type = SR_DF_ANALOG;
@ -185,7 +188,7 @@ int tondaj_sl_814_receive_data(int fd, int revents, void *cb_data)
return TRUE;
}
decode_packet(devc);
decode_packet(sdi);
devc->state = SEND_PACKET_REQUEST;
} else {

View File

@ -66,14 +66,16 @@
* - ...
*/
static void decode_packet(struct dev_context *devc, int dmm, const uint8_t *buf)
static void decode_packet(struct sr_dev_inst *sdi, int dmm, const uint8_t *buf)
{
struct sr_datafeed_packet packet;
struct sr_datafeed_analog analog;
struct dev_context *devc;
struct fs9721_info info;
float floatval;
int ret;
devc = sdi->priv;
memset(&analog, 0, sizeof(struct sr_datafeed_analog));
/* Parse the protocol packet. */
@ -88,6 +90,7 @@ static void decode_packet(struct dev_context *devc, int dmm, const uint8_t *buf)
}
/* Send a sample packet with one analog value. */
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &floatval;
packet.type = SR_DF_ANALOG;
@ -261,7 +264,7 @@ static int uni_t_dmm_receive_data(int fd, int revents, int dmm, void *cb_data)
return TRUE;
}
}
decode_packet(devc, dmm, pbuf);
decode_packet(sdi, dmm, pbuf);
memset(pbuf, 0x00, NUM_DATA_BYTES);
}
}

View File

@ -40,16 +40,19 @@ static uint8_t decode_digit(uint8_t in)
return out;
}
static void decode_buf(struct dev_context *devc, unsigned char *data)
static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data)
{
struct sr_datafeed_packet packet;
struct sr_datafeed_analog analog;
struct dev_context *devc;
long factor, ivalue;
uint8_t digits[4];
gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto;
gboolean is_hold, is_max, is_min, is_relative, minus;
float fvalue;
devc = sdi->priv;
digits[0] = decode_digit(data[12]);
digits[1] = decode_digit(data[11]);
digits[2] = decode_digit(data[10]);
@ -249,6 +252,7 @@ static void decode_buf(struct dev_context *devc, unsigned char *data)
if (is_relative)
analog.mqflags |= SR_MQFLAG_RELATIVE;
analog.probes = sdi->probes;
analog.num_samples = 1;
analog.data = &fvalue;
packet.type = SR_DF_ANALOG;
@ -260,7 +264,6 @@ static void decode_buf(struct dev_context *devc, unsigned char *data)
SR_PRIV int victor_dmm_receive_data(struct sr_dev_inst *sdi, unsigned char *buf)
{
struct dev_context *devc;
GString *dbg;
int i;
unsigned char data[DMM_DATA_SIZE];
@ -269,8 +272,6 @@ SR_PRIV int victor_dmm_receive_data(struct sr_dev_inst *sdi, unsigned char *buf)
6, 13, 5, 11, 2, 7, 9, 8, 3, 10, 12, 0, 4, 1
};
devc = sdi->priv;
for (i = 0; i < DMM_DATA_SIZE && buf[i] == 0; i++);
if (i == DMM_DATA_SIZE) {
/* This DMM outputs all zeroes from time to time, just ignore it. */
@ -291,7 +292,7 @@ SR_PRIV int victor_dmm_receive_data(struct sr_dev_inst *sdi, unsigned char *buf)
g_string_free(dbg, TRUE);
}
decode_buf(devc, data);
decode_buf(sdi, data);
return SR_OK;
}

View File

@ -286,6 +286,7 @@ struct sr_datafeed_logic {
};
struct sr_datafeed_analog {
GSList *probes;
int num_samples;
/** Measured quantity (voltage, current, temperature, and so on). */
int mq;

View File

@ -191,10 +191,12 @@ static void fancyprint(int unit, int mqflags, float value, GString *out)
static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet)
{
const struct sr_datafeed_analog *analog;
struct context *ctx;
const struct sr_datafeed_analog *analog;
struct sr_probe *probe;
GSList *l;
const float *fdata;
int i, j;
int i, p;
(void)sdi;
@ -216,11 +218,11 @@ static GString *receive(struct sr_output *o, const struct sr_dev_inst *sdi,
analog = packet->payload;
fdata = (const float *)analog->data;
for (i = 0; i < analog->num_samples; i++) {
for (j = 0; j < ctx->num_enabled_probes; j++) {
g_string_append_printf(ctx->out, "%s: ",
(char *)g_ptr_array_index(ctx->probelist, j));
for (l = analog->probes, p = 0; l; l = l->next, p++) {
probe = l->data;
g_string_append_printf(ctx->out, "%s: ", probe->name);
fancyprint(analog->unit, analog->mqflags,
fdata[i + j], ctx->out);
fdata[i + p], ctx->out);
}
}
break;