From 572e07b43d80b9b2aa9e243e449264ad9d081089 Mon Sep 17 00:00:00 2001 From: Roman S Samarev Date: Tue, 6 Jan 2026 15:11:03 +0300 Subject: [PATCH] siglent: added support of SDS800x series --- src/hardware/siglent-sds/api.c | 17 +++++- src/hardware/siglent-sds/protocol.c | 85 +++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/src/hardware/siglent-sds/api.c b/src/hardware/siglent-sds/api.c index 76955e6da..347179539 100644 --- a/src/hardware/siglent-sds/api.c +++ b/src/hardware/siglent-sds/api.c @@ -171,6 +171,8 @@ enum series { SDS1000XP, SDS1000XE, SDS2000X, + SDS800X_HD, + SDS800X_HD_200M, }; /* short name, full name */ @@ -196,6 +198,10 @@ static const struct siglent_sds_series supported_series[] = { { 50, 1 }, { 500, 100000 }, 14, 8, 14000363}, [SDS2000X] = {VENDOR(SIGLENT), "SDS2000X", SPO_MODEL, { 50, 1 }, { 500, 100000 }, 14, 8, 14000363}, + [SDS800X_HD] = {VENDOR(SIGLENT), "SDS800X HD", SPO_MODEL, + { 50, 1 }, { 500, 100000 }, 14, 8, 50000363}, + [SDS800X_HD_200M] = {VENDOR(SIGLENT), "SDS800X HD 200M", SPO_MODEL, + { 50, 1 }, { 500, 100000 }, 14, 8, 100000363}, }; #define SERIES(x) &supported_series[x] @@ -227,6 +233,15 @@ static const struct siglent_sds_model supported_models[] = { { SERIES(SDS2000X), "SDS2204X", { 2, 1000000000 }, 4, FALSE, 0 }, { SERIES(SDS2000X), "SDS2302X", { 2, 1000000000 }, 2, FALSE, 0 }, { SERIES(SDS2000X), "SDS2304X", { 2, 1000000000 }, 4, FALSE, 0 }, + /* SDS800x HD series - Official models from Siglent datasheet */ + /* 70 MHz and 100 MHz models - 50 Mpts max memory (1ch), 25 Mpts (2ch), 10 Mpts (4ch) */ + { SERIES(SDS800X_HD), "SDS802X HD", { 5, 1000000000 }, 2, FALSE, 0 }, + { SERIES(SDS800X_HD), "SDS804X HD", { 5, 1000000000 }, 4, TRUE, 16 }, + { SERIES(SDS800X_HD), "SDS812X HD", { 5, 1000000000 }, 2, FALSE, 0 }, + { SERIES(SDS800X_HD), "SDS814X HD", { 5, 1000000000 }, 4, TRUE, 16 }, + /* 200 MHz models - 100 Mpts max memory (1ch), 50 Mpts (2ch), 25 Mpts (4ch) */ + { SERIES(SDS800X_HD_200M), "SDS822X HD", { 2, 1000000000 }, 2, FALSE, 0 }, + { SERIES(SDS800X_HD_200M), "SDS824X HD", { 2, 1000000000 }, 4, TRUE, 16 }, }; static struct sr_dev_driver siglent_sds_driver_info; @@ -916,7 +931,7 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) static struct sr_dev_driver siglent_sds_driver_info = { .name = "siglent-sds", - .longname = "Siglent SDS1000/SDS2000", + .longname = "Siglent SDS1000/SDS2000/SDS800xHD", .api_version = 1, .init = std_init, .cleanup = std_cleanup, diff --git a/src/hardware/siglent-sds/protocol.c b/src/hardware/siglent-sds/protocol.c index d59e52cbc..d467ee403 100644 --- a/src/hardware/siglent-sds/protocol.c +++ b/src/hardware/siglent-sds/protocol.c @@ -167,19 +167,35 @@ SR_PRIV int siglent_sds_capture_start(const struct sr_dev_inst *sdi) devc->num_frames + 1, devc->limit_frames); if (siglent_sds_config_set(sdi, "ARM") != SR_OK) return SR_ERR; - if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK) - return SR_ERR; - sr_atoi(buf, &out); - g_free(buf); + /* Poll INR a few times to give the scope time to arm. */ + for (int attempt = 0; attempt < 5; attempt++) { + g_usleep(200000); + 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) { + siglent_sds_set_wait_event(devc, WAIT_TRIGGER); + break; + } else if (out == DEVICE_STATE_DATA_TRIG_RDY) { + sr_spew("Device triggered."); + siglent_sds_set_wait_event(devc, WAIT_BLOCK); + return SR_OK; + } + } + /* Check if device entered ARM mode. */ if (out == DEVICE_STATE_TRIG_RDY) { + /* Device is armed and ready, normal case. */ siglent_sds_set_wait_event(devc, WAIT_TRIGGER); - } else if (out == DEVICE_STATE_DATA_TRIG_RDY) { - sr_spew("Device triggered."); - siglent_sds_set_wait_event(devc, WAIT_BLOCK); - return SR_OK; - } else { - sr_spew("Device did not enter ARM mode."); - return SR_ERR; + } else if (out != DEVICE_STATE_DATA_TRIG_RDY) { + /* Device did not enter ARM mode. SDS800X HD series is known to have this issue. */ + if (g_str_has_prefix(devc->model->series->name, "SDS800X HD")) { + sr_dbg("SDS800X HD: Device did not enter ARM mode (INR=%d); continuing anyway.", out); + siglent_sds_set_wait_event(devc, WAIT_TRIGGER); + } else { + sr_spew("Device did not enter ARM mode."); + return SR_ERR; + } } } else { /* TODO: Implement history retrieval. */ unsigned int framecount; @@ -217,17 +233,28 @@ SR_PRIV int siglent_sds_capture_start(const struct sr_dev_inst *sdi) devc->num_frames + 1, devc->limit_frames); if (siglent_sds_config_set(sdi, "ARM") != SR_OK) return SR_ERR; - if (sr_scpi_get_string(sdi->conn, ":INR?", &buf) != SR_OK) - return SR_ERR; - sr_atoi(buf, &out); - g_free(buf); + /* Poll INR a few times to give the scope time to arm. */ + for (int attempt = 0; attempt < 5; attempt++) { + g_usleep(200000); + 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) { + siglent_sds_set_wait_event(devc, WAIT_TRIGGER); + break; + } else if (out == DEVICE_STATE_DATA_TRIG_RDY) { + sr_spew("Device triggered."); + siglent_sds_set_wait_event(devc, WAIT_BLOCK); + return SR_OK; + } + } + /* Check if device entered ARM mode. */ if (out == DEVICE_STATE_TRIG_RDY) { + /* Device is armed and ready, normal case. */ siglent_sds_set_wait_event(devc, WAIT_TRIGGER); - } else if (out == DEVICE_STATE_DATA_TRIG_RDY) { - sr_spew("Device triggered."); - siglent_sds_set_wait_event(devc, WAIT_BLOCK); - return SR_OK; - } else { + } else if (out != DEVICE_STATE_DATA_TRIG_RDY) { + /* Device did not enter ARM mode. */ sr_spew("Device did not enter ARM mode."); return SR_ERR; } @@ -519,9 +546,14 @@ SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data) switch (devc->model->series->protocol) { case NON_SPO_MODEL: case SPO_MODEL: - /* 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 %.f0 ms for device to prepare the output buffers", wait / 1000); + /* SDS800X HD series has faster data transfer, needs less wait time. */ + if (g_str_has_prefix(devc->model->series->name, "SDS800X HD")) { + wait = (devc->memory_depth_analog * 0.5); + } else { + /* 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 %.0f ms for device to prepare the output buffers", wait / 1000); g_usleep(wait); if (sr_scpi_read_begin(scpi) != SR_OK) return TRUE; @@ -531,7 +563,7 @@ SR_PRIV int siglent_sds_receive(int fd, int revents, void *cb_data) if (sr_scpi_read_begin(scpi) != SR_OK) return TRUE; wait = ((devc->timebase * devc->model->series->num_horizontal_divs) * 100000); - sr_dbg("Waiting %.f0 ms for device to prepare the output buffers", wait / 1000); + sr_dbg("Waiting %.0f ms for device to prepare the output buffers", wait / 1000); g_usleep(wait); break; } @@ -915,6 +947,11 @@ SR_PRIV int siglent_sds_get_dev_cfg_horizontal(const struct sr_dev_inst *sdi) } samplerate_scope = fvalue * 10000; } else { + if (sr_atof_ascii(sample_points_string, &fvalue) != SR_OK) { + sr_dbg("Invalid float converted from scope response."); + g_free(sample_points_string); + return SR_ERR; + } samplerate_scope = fvalue; } g_free(sample_points_string);