-
Notifications
You must be signed in to change notification settings - Fork 358
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
Add support for Siglent's SDS2000X Plus series #176
base: master
Are you sure you want to change the base?
Conversation
@@ -322,6 +322,7 @@ static int siglent_sds_read_header(struct sr_dev_inst *sdi) | |||
ret = sr_scpi_read_data(scpi, buf, SIGLENT_HEADER_SIZE); | |||
if (ret < SIGLENT_HEADER_SIZE) { | |||
sr_err("Read error while reading data header."); | |||
sr_dbg("Device returned %i bytes.", ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line was added when I was trying to debug why capturing a waveform wasn't working over USB. Doing this showed that it was only getting 52 bytes when done over USB. This line should hopefully help with future debugging.
Here's what printing this header shows: ALL,#9000000446WAVEDESC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI see these findings on using USB on SDS1104X-E: https://github.com/sigrokproject/libsigrok/pull/114/files#diff-b2e40d0d92f027de6ccfdb0e8581aca4192f2408ec3eb900fcc1a6520d054fd3R39
The USB packet size is 64 bytes with a 12 byte packet header so you get 52 bytes of data per packet. Additionally at least the SDS1104X-E has an internal buffer of 61440 bytes (variable named show_send_buffer_size can be seen on uboot log) which gets refilled only when it has been completely read. And while it's refilling the read will fail.
Pinging @marchelh since he implemented the existing Siglent device driver. |
This was tested against tag |
@marchelh while I'm at this, I was wondering how you got 363 for SIGLENT_HEADER_SIZE. After some experimentation, I found that if I do 361 for this number then my first few points are not garbage and are actually part of the waveform. At 363 it seems like I might be missing 2 valid sample points, at numbers less than 361 it seems I'm getting some sort of preamble data in the beginning.
I'm not sure if this is happening for all SIglents or if it only applies to SDS2000X Plus. Edit: I fixed this and other issues in 54730ea by removing |
647e32d
to
62444c6
Compare
Edit: This has been fixed. |
46ece52
to
66d2b87
Compare
f6e2248
to
ffbd467
Compare
4c7d423
to
54730ea
Compare
I just added support for the digital (logic analyzer) channels as well. Edit: there seems to be a bug where the SCPI command "WAVeform:STARt <value>" is not obeyed for the digital channels. So I added a workaround where just the first block of the waveform is displayed for large timebases. Currently, this results in half of the screen being displayed at a timebase of 2ms/div, a fifth of the screen displayed at a timebase of 5ms/div, and a tenth of the screen being displayed at timebases >= 10ms. You will capture the entire screen for timebases of 1ms/div or less. |
455d96d
to
fafe491
Compare
@uwehermann If you get a chance, could you please take a look at this merge request. I believe it's ready to be merged. |
@gsigh Could you help get this merged? |
My last push just added some fixes to work with the latest firmware (V1.5.2R1). |
b5f1b52
to
16c651d
Compare
25a46dc
to
a056b30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments.
- I have issues with some of the changes that would seem to impact the other devices ? If that is the case, they belong in a separate commit with a good explanation and testing that confirms no breakage
- lots of strcmp with the model name; in some areas it looks like there is so much difference that it would make sense to split code into separate functions.
- I didn't even look at code that looked like for{if{do{if{if{for{if{if... that is way too many indents and almost unreviewable
- you replaced some hardcoded constants with something that ends up in the device struct - that is great, but could/should have been a separate commit for those cases that could be applied independantly of adding SDS2000 per se. Small changesets are much prefered.
/* SDS2000X+: The channels need to be enabled/disabled prior to | ||
* obtaining the sample rate when the data source is set to display. | ||
* If a channel is turned on/off on the oscilloscope then use Sigrok's settings instead. */ | ||
if (!strcmp(devc->model->series->name, "SDS2000X+") && devc->data_source == DATA_SOURCE_SCREEN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer avoiding to test things like model name strings for feature support... adding a bool flag (or bit-masked enums, I would look at other more mature drivers to see if there is a more common pattern) would be preferable esp. if future models also need this
if (!strcmp(channel_state, "OFF") && ch->enabled) | ||
if (siglent_sds_config_set(sdi, "C%d:TRA %s", ch->index + 1, | ||
ch->enabled ? "ON" : "OFF") != SR_OK) | ||
return SR_ERR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is getting into some pretty deep indent levels, maybe time to split some functionality into a separate func ?
char *channel_state; | ||
char *cmd = g_strdup_printf("C%d:TRA?", ch->index + 1); | ||
sr_scpi_get_string(sdi->conn, cmd, &channel_state); | ||
if (!strcmp(channel_state, "ON") && !ch->enabled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not checking if sr_scpi_get_string() failed before strcmp (i didnt check if it sets channel_state to null or to an empty string if it fails)
switch (devc->model->series->protocol) { | ||
case SPO_MODEL: | ||
if (siglent_sds_config_set(sdi, "WFSU SP,0,TYPE,1") != SR_OK) | ||
if (siglent_sds_config_set(sdi, "WFSU SP,0,NP,0,FP,0") != SR_OK) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are changing this for all models , is this intended ?
if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK) | ||
return SR_ERR; | ||
sr_atoi(buf, &out); | ||
g_free(buf); | ||
if (out == DEVICE_STATE_TRIG_RDY) { | ||
if (out == DEVICE_STATE_TRIG_RDY || out == DEVICE_STATE_STOPPED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another change that impacts other devices, would like to hear rationale, testing on other models to confirm no breakage, and separate commit unless it's directly related to sds2000 support
s = (ch->type == SR_CHANNEL_LOGIC) ? "D%d:WF?" : "C%d:WF? ALL"; | ||
if (sr_scpi_send(sdi->conn, s, ch->index + 1) != SR_OK) | ||
return SR_ERR; | ||
if (!strcmp(devc->model->series->name, "SDS2000X+")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another strcmp with model name
@@ -315,13 +336,25 @@ static int siglent_sds_read_header(struct sr_dev_inst *sdi) | |||
struct dev_context *devc = sdi->priv; | |||
char *buf = (char *)devc->buffer; | |||
int ret, desc_length; | |||
int block_offset = 15; /* Offset for descriptor block. */ | |||
int block_offset; /* Offset for descriptor block. */ | |||
if (!strcmp(devc->model->series->name, "SDS2000X+")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe would make sense to have this value (and header_size just below) in the device descriptor struct. Less code.
} else { | ||
/* Get previous stored sample from low channel buffer. */ | ||
tmp_value = g_array_index(data_low_channels, uint8_t, samples_index); | ||
if (ch->type == SR_CHANNEL_LOGIC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this section is complex and hard to review (I am skipping over it at this time)
Also if there's that many different sub-cases with "if model is SDS2000", it starts making sense to have a separate function entirely.
/* The older models need more time to prepare the the output buffers due to CPU speed. */ | ||
wait = (devc->memory_depth_analog * 2.5); | ||
sr_dbg("Waiting %.f ms for device to prepare the output buffers", wait / 1000); | ||
g_usleep(wait); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always dislike sleep/wait calls. Is there no way to tweak SCPI read timeouts ?
@@ -609,16 +727,18 @@ SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data) | |||
g_array_free(data, TRUE); | |||
} | |||
len = 0; | |||
if (devc->num_samples == (devc->num_block_bytes - SIGLENT_HEADER_SIZE)) { | |||
if (devc->num_samples == devc->num_block_bytes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changing common code for non-obvious reason
…c Kuzmenko) in this PR : github.com/sigrokproject/pull/176/ Created a new protocol version "E11" matching the latest Siglent SDS Scope programming guide. Reduced the read-wait time from 7sec to 50ms for better performance (achived by looping on read sample logic to consume the data has it arrives). Tested with SDS2504X HD model connected via Ethernet cable.
Add support for both analog and digital (logic analyzer) channels. Don't set num_block_bytes before any waveform data is read. Add a pause after sending a command to enter ARM mode. This is necessary to prevent crashes when the timebase is large. Move the start point after every full block is read. Don't wait for the instrument to prepare its output buffers if it's a SDS2000X Plus. Fix multi-channel support and ensure that the correct sample rate is obtained when the timebase is changed or when channels are enabled/disabled in "display" mode. If a channel is turned on/off on the oscilloscope then use sigrok's settings instead.
Don't set num_block_bytes before any waveform data is read.
Add support for both analog and digital (logic analyzer) channels.
Make SIGLENT_HEADER_SIZE 361 based on experimentation.
Add a pause after sending a command to enter ARM mode. This is necessary to prevent crashes when the timebase is large.
Move the start point after every full block is read.
Don't wait for the instrument to prepare its output buffers if it's a SDS2000X Plus.
Fix multi-channel support and ensure that the correct sample rate is obtained when the timebase is changed or when channels are enabled/disabled in "display" mode.
If a channel is turned on/off on the oscilloscope then use sigrok's settings instead.