From f253296c23482af68569db20d54ff6c3e15d4dc5 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 15 Apr 2026 14:51:39 +0200 Subject: [PATCH] default to MHz, removed space between units for consistency with timers, min and max checks for clks --- .../slsDetectorServer_defs.h | 3 + .../src/slsDetectorServer_funcs.c | 7 ++ .../slsDetectorServer_defs.h | 3 + .../Caller/test-Caller-chiptestboard.cpp | 75 ++++++++++++++++--- slsSupportLib/include/sls/ToString.h | 21 +++--- slsSupportLib/src/ToString.cpp | 19 ----- slsSupportLib/tests/test-ToString.cpp | 16 ++-- 7 files changed, 96 insertions(+), 48 deletions(-) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h index 2e95c08a1..49e06b623 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h @@ -57,6 +57,9 @@ #define NS_TO_CLK_CYCLE (1E-9) // ns to MHz #define DEFAULT_TRANSCEIVER_MASK (0x3) +#define MIN_CLK_FREQ (2000000) // 2 MHz +#define MAX_CLK_FREQ (300000000) // 300 MHz + #define MAX_TRANSCEIVER_MASK (0xF) #define MAX_TRANSCEIVER_SAMPLES (0xFFFF) diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 39c776571..127099f6b 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -5866,6 +5866,13 @@ int set_clock_frequency(int file_des) { if (getFrequency(c) == val) { LOG(logINFO, ("Same %s: %d %s\n", modeName, val, "Hz")); + } else if (val < MIN_CLK_FREQ || val > MAX_CLK_FREQ) { + ret = FAIL; + sprintf(mess, + "Cannot set frequency to %d Hz. Frequency outside " + "limits (%f - %f MHz)\n", + val, MIN_CLK_FREQ / 1e6, MAX_CLK_FREQ / 1e6); + LOG(logERROR, (mess)); } else { int ret = setFrequency(c, val); if (ret == FAIL) { diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h index 2e2ee58a0..b5691bbc5 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h @@ -164,3 +164,6 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS }; #define DEFAULT_SYNC_CLK (20000) // 20 MHz #define DEFAULT_DBIT_CLK (100000) // 100 MHz #define NS_TO_CLK_CYCLE (1E-9) // ns to Hz + +#define MIN_CLK_FREQ (10000000) // 10 MHz +#define MAX_CLK_FREQ (300000000) // 300 MHz diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp index 8a649a020..47f03254f 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp @@ -699,8 +699,24 @@ TEST_CASE("adcclk", "[.detectorintegration]") { Caller caller(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD) { + if (det_type == defs::CHIPTESTBOARD || + det_type == defs::XILINX_CHIPTESTBOARD) { auto prev_val = det.getADCClock(); + + REQUIRE_NOTHROW(caller.call("adcclk", {"MHZ"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("adcclk", {"mhz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("adcclk", {"MHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("adcclk", {"kHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("adcclk", {"Hz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("adcclk", {}, -1, GET)); + // min + if (det_type == defs::CHIPTESTBOARD) + REQUIRE_THROWS(caller.call("adcclk", {"1", "MHz"}, -1, PUT)); + else + REQUIRE_THROWS(caller.call("adcclk", {"9", "MHz"}, -1, PUT)); + // max + REQUIRE_THROWS(caller.call("adcclk", {"301", "MHz"}, -1, PUT)); + { std::ostringstream oss; caller.call("adcclk", {"20"}, -1, PUT, oss); @@ -711,10 +727,11 @@ TEST_CASE("adcclk", "[.detectorintegration]") { caller.call("adcclk", {"10"}, -1, PUT, oss); REQUIRE(oss.str() == "adcclk 10\n"); } + { std::ostringstream oss; caller.call("adcclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "adcclk 10000000\n"); + REQUIRE(oss.str() == "adcclk 10MHz\n"); } { std::ostringstream oss; @@ -724,7 +741,7 @@ TEST_CASE("adcclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("adcclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "adcclk 15000000\n"); + REQUIRE(oss.str() == "adcclk 15MHz\n"); } { std::ostringstream oss; @@ -734,7 +751,7 @@ TEST_CASE("adcclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("adcclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "adcclk 5750000\n"); + REQUIRE(oss.str() == "adcclk 5.75MHz\n"); } for (int i = 0; i != det.size(); ++i) { det.setADCClock(prev_val[i], {i}); @@ -750,8 +767,24 @@ TEST_CASE("runclk", "[.detectorintegration]") { Caller caller(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD) { + if (det_type == defs::CHIPTESTBOARD || + det_type == defs::XILINX_CHIPTESTBOARD) { auto prev_val = det.getRUNClock(); + + REQUIRE_NOTHROW(caller.call("runclk", {"MHZ"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("runclk", {"mhz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("runclk", {"MHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("runclk", {"kHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("runclk", {"Hz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("runclk", {}, -1, GET)); + // min + if (det_type == defs::CHIPTESTBOARD) + REQUIRE_THROWS(caller.call("runclk", {"1", "MHz"}, -1, PUT)); + else + REQUIRE_THROWS(caller.call("runclk", {"9", "MHz"}, -1, PUT)); + // max + REQUIRE_THROWS(caller.call("runclk", {"301", "MHz"}, -1, PUT)); + { std::ostringstream oss; caller.call("runclk", {"20"}, -1, PUT, oss); @@ -762,10 +795,11 @@ TEST_CASE("runclk", "[.detectorintegration]") { caller.call("runclk", {"10"}, -1, PUT, oss); REQUIRE(oss.str() == "runclk 10\n"); } + { std::ostringstream oss; caller.call("runclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "runclk 10000000\n"); + REQUIRE(oss.str() == "runclk 10MHz\n"); } { std::ostringstream oss; @@ -775,7 +809,7 @@ TEST_CASE("runclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("runclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "runclk 15000000\n"); + REQUIRE(oss.str() == "runclk 15MHz\n"); } { std::ostringstream oss; @@ -785,7 +819,7 @@ TEST_CASE("runclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("runclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "runclk 5750000\n"); + REQUIRE(oss.str() == "runclk 5.75MHz\n"); } for (int i = 0; i != det.size(); ++i) { det.setRUNClock(prev_val[i], {i}); @@ -1067,8 +1101,24 @@ TEST_CASE("dbitclk", "[.detectorintegration]") { Caller caller(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD) { + if (det_type == defs::CHIPTESTBOARD || + det_type == defs::XILINX_CHIPTESTBOARD) { auto prev_val = det.getDBITClock(); + + REQUIRE_NOTHROW(caller.call("dbitclk", {"MHZ"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("dbitclk", {"mhz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("dbitclk", {"MHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("dbitclk", {"kHz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("dbitclk", {"Hz"}, -1, GET)); + REQUIRE_NOTHROW(caller.call("dbitclk", {}, -1, GET)); + // min + if (det_type == defs::CHIPTESTBOARD) + REQUIRE_THROWS(caller.call("dbitclk", {"1", "MHz"}, -1, PUT)); + else + REQUIRE_THROWS(caller.call("dbitclk", {"9", "MHz"}, -1, PUT)); + // max + REQUIRE_THROWS(caller.call("dbitclk", {"301", "MHz"}, -1, PUT)); + { std::ostringstream oss; caller.call("dbitclk", {"20"}, -1, PUT, oss); @@ -1079,10 +1129,11 @@ TEST_CASE("dbitclk", "[.detectorintegration]") { caller.call("dbitclk", {"10"}, -1, PUT, oss); REQUIRE(oss.str() == "dbitclk 10\n"); } + { std::ostringstream oss; caller.call("dbitclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "dbitclk 10000000\n"); + REQUIRE(oss.str() == "dbitclk 10MHz\n"); } { std::ostringstream oss; @@ -1092,7 +1143,7 @@ TEST_CASE("dbitclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("dbitclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "dbitclk 15000000\n"); + REQUIRE(oss.str() == "dbitclk 15MHz\n"); } { std::ostringstream oss; @@ -1102,7 +1153,7 @@ TEST_CASE("dbitclk", "[.detectorintegration]") { { std::ostringstream oss; caller.call("dbitclk", {}, -1, GET, oss); - REQUIRE(oss.str() == "dbitclk 5750000\n"); + REQUIRE(oss.str() == "dbitclk 5.75MHz\n"); } for (int i = 0; i != det.size(); ++i) { det.setDBITClock(prev_val[i], {i}); diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index 14fda7539..f38fa0019 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -111,13 +111,19 @@ typename std::enable_if::value, std::string>::type ToString(T f, const std::string &unit) { double val = static_cast(f.value); + auto unitLower = [&] { + std::string result = unit; + std::transform(result.begin(), result.end(), result.begin(), + [](unsigned char c) { return std::tolower(c); }); + return result; + }(); std::ostringstream os; - if (unit == "Hz") - os << val << ' ' << unit; - else if (unit == "kHz") - os << val / (static_cast(1e3)) << ' ' << unit; - else if (unit == "MHz") - os << val / (static_cast(1e6)) << ' ' << unit; + if (unitLower == "hz") + os << val << unit; + else if (unitLower == "khz") + os << val / (static_cast(1e3)) << unit; + else if (unitLower == "mhz") + os << val / (static_cast(1e6)) << unit; else throw std::runtime_error("Unknown unit: " + unit); return os.str(); @@ -412,7 +418,4 @@ std::vector StringTo(const std::vector &strings) { return result; } -/** Convert frequency string with unit (MHz, kHz, Hz) to Hz */ -int StringToHz(const std::string &s, const std::string &unit); - } // namespace sls diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 562fe9049..98790f7cd 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -1181,23 +1181,4 @@ template <> int64_t StringTo(const std::string &s) { return std::stol(s, nullptr, base); } -int StringToHz(const std::string &s, const std::string &unit) { - double fval{0}; - try { - fval = std::stod(s); - } catch (const std::invalid_argument &e) { - throw RuntimeError("Could not convert string to frequency"); - } - if (unit.empty() || unit == "MHz") { - return static_cast(fval * 1000000.0); - } else if (unit == "kHz") { - return static_cast(fval * 1000.0); - } else if (unit == "Hz") { - return static_cast(fval); - } else { - throw RuntimeError("Unknown unit: " + unit + - ". Supported units: MHz, kHz, Hz"); - } -} - } // namespace sls \ No newline at end of file diff --git a/slsSupportLib/tests/test-ToString.cpp b/slsSupportLib/tests/test-ToString.cpp index e577423e4..d920838a0 100644 --- a/slsSupportLib/tests/test-ToString.cpp +++ b/slsSupportLib/tests/test-ToString.cpp @@ -59,12 +59,12 @@ TEST_CASE("conversion from duration to string", "[support]") { } TEST_CASE("conversion from frequency to string", "[support]") { - REQUIRE(ToString(defs::Hz(150)) == "150 Hz"); - REQUIRE(ToString(defs::Hz(1500)) == "1.5 kHz"); - REQUIRE(ToString(defs::Hz(1500000)) == "1.5 MHz"); - REQUIRE(ToString(defs::Hz(150), "Hz") == "150 Hz"); - REQUIRE(ToString(defs::Hz(150), "kHz") == "0.15 kHz"); - REQUIRE(ToString(defs::Hz(150), "MHz") == "0.00015 MHz"); + REQUIRE(ToString(defs::Hz(150)) == "150Hz"); + REQUIRE(ToString(defs::Hz(1500)) == "1.5kHz"); + REQUIRE(ToString(defs::Hz(1500000)) == "1.5MHz"); + REQUIRE(ToString(defs::Hz(150), "Hz") == "150Hz"); + REQUIRE(ToString(defs::Hz(150), "kHz") == "0.15kHz"); + REQUIRE(ToString(defs::Hz(150), "MHz") == "0.00015MHz"); } TEST_CASE("Convert vector of time", "[support]") { @@ -147,9 +147,9 @@ TEST_CASE("string to std::chrono::duration", "[support]") { } TEST_CASE("string to frequency", "[support]") { - REQUIRE(StringTo("150", "Hz") == defs::Hz(150)); REQUIRE(StringTo("150Hz") == defs::Hz(150)); - REQUIRE(StringTo("1.5 kHz") == defs::Hz(1500)); + REQUIRE(StringTo("150Hz") == defs::Hz(150)); + REQUIRE(StringTo("1.5kHz") == defs::Hz(1500)); REQUIRE(StringTo("1.5MHz") == defs::Hz(1500000)); REQUIRE_THROWS(StringTo("5xs")); REQUIRE_THROWS(StringTo("asvn"));