Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

siglent-sds: original driver fixes, USBTMC support #114

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/hardware/siglent-sds/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static const uint64_t averages[] = {

/* Do not change the order of entries. */
static const char *data_sources[] = {
"Display",
"Screen",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config_get for DATA_SOURCE returns "Screen" to the cli/pulseview, and since the enum is also DATA_SOURCE_SCREEN I decided to change these two occurrences of "Display" into "Screen".

"History",
};

Expand Down Expand Up @@ -294,6 +294,12 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
sdi->serial_num = g_strdup(hw_info->serial_number);
devc = g_malloc0(sizeof(struct dev_context));
devc->limit_frames = 1;

// Set some pointers to null so they can be safely g_free'd later
for (i = 0; i < MAX_ANALOG_CHANNELS; i++) {
devc->coupling[i] = NULL;
}
devc->trigger_slope = NULL;
devc->model = model;

sr_scpi_hw_info_free(hw_info);
Expand Down Expand Up @@ -677,7 +683,7 @@ static int config_set(uint32_t key, GVariant *data,
return ret;
case SR_CONF_DATA_SOURCE:
tmp_str = g_variant_get_string(data, NULL);
if (!strcmp(tmp_str, "Display"))
if (!strcmp(tmp_str, "Screen"))
devc->data_source = DATA_SOURCE_SCREEN;
else if (devc->model->series->protocol >= SPO_MODEL
&& !strcmp(tmp_str, "History"))
Expand Down
74 changes: 56 additions & 18 deletions src/hardware/siglent-sds/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@
#include "scpi.h"
#include "protocol.h"

/* Siglent USBTMC notes
*
* USBTMC packet size is 64 bytes. In other words, a read will never return more
* than 64 bytes. In addition, Siglent has an internal USBTMC buffer,
* show_send_buffer_size, which is set to 61440 bytes (source: some uboot logs from eevblog).
* This means that every 61440 bytes the read will fail (returns -1) while the buffer is being
* refilled.
*/

/* Set the next event to wait for in siglent_sds_receive(). */
static void siglent_sds_set_wait_event(struct dev_context *devc, enum wait_events event)
{
Expand Down Expand Up @@ -314,18 +323,37 @@ static int siglent_sds_read_header(struct sr_dev_inst *sdi)
struct sr_scpi_dev_inst *scpi = sdi->conn;
struct dev_context *devc = sdi->priv;
char *buf = (char *)devc->buffer;
int ret, desc_length;
int desc_length;
int block_offset = 15; /* Offset for descriptor block. */
long data_length = 0;
int header_bytes_read_total = 0;
int header_bytes_read;

/* Read header from device.
* USBTMC packet is limited to 64 bytes (52 bytes per packet), so we read it with a loop
*/
do {
sr_dbg("Reading header..");
header_bytes_read = sr_scpi_read_data(
scpi,
buf + header_bytes_read_total,
SIGLENT_HEADER_SIZE - header_bytes_read_total
);
if (header_bytes_read == -1) {
sr_err("Read error");
return SR_ERR;
} else if (header_bytes_read == 0) {
sr_err("No data");
return SR_ERR;
}
sr_dbg("Got %d bytes", header_bytes_read);
header_bytes_read_total += header_bytes_read;

/* Read header from device. */
ret = sr_scpi_read_data(scpi, buf, SIGLENT_HEADER_SIZE);
if (ret < SIGLENT_HEADER_SIZE) {
sr_err("Read error while reading data header.");
return SR_ERR;
}
sr_dbg("Device returned %i bytes.", ret);
devc->num_header_bytes += ret;
} while (header_bytes_read_total < SIGLENT_HEADER_SIZE);

sr_dbg("Device returned %i bytes.", header_bytes_read_total);

devc->num_header_bytes += (unsigned long) header_bytes_read_total;
buf += block_offset; /* Skip to start descriptor block. */

/* Parse WaveDescriptor header. */
Expand All @@ -335,9 +363,9 @@ static int siglent_sds_read_header(struct sr_dev_inst *sdi)
devc->block_header_size = desc_length + 15;
devc->num_samples = data_length;

sr_dbg("Received data block header: '%s' -> block length %d.", buf, ret);
sr_dbg("Received data block header: '%s' -> block length %d.", buf, header_bytes_read_total);

return ret;
return header_bytes_read_total;
}

static int siglent_sds_get_digital(const struct sr_dev_inst *sdi, struct sr_channel *ch)
Expand Down Expand Up @@ -470,6 +498,7 @@ SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data)
struct sr_datafeed_logic logic;
struct sr_channel *ch;
int len, i;
int retry_count;
float wait;
gboolean read_complete = FALSE;

Expand Down Expand Up @@ -566,13 +595,22 @@ SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data)
len = devc->num_samples;
} else {
sr_dbg("Requesting: %" PRIu64 " bytes.", devc->num_samples - devc->num_block_bytes);
len = sr_scpi_read_data(scpi, (char *)devc->buffer, devc->num_samples-devc->num_block_bytes);
if (len == -1) {
sr_err("Read error, aborting capture.");
std_session_send_df_frame_end(sdi);
sdi->driver->dev_acquisition_stop(sdi);
return TRUE;
}
/* Retry because USBTMC will return -1 every 61440 bytes while it fills the send buffer */
retry_count = 0;
do {
len = sr_scpi_read_data(scpi, (char *)devc->buffer, devc->num_samples-devc->num_block_bytes);
if (len == -1) {
if (retry_count > 5) {
sr_err("Read error, aborting capture.");
std_session_send_df_frame_end(sdi);
sdi->driver->dev_acquisition_stop(sdi);
return TRUE;
}
retry_count++;
g_usleep(200000);

}
} while (len == -1);
devc->num_block_read++;
devc->num_block_bytes += len;
}
Expand Down