default to MHz, removed space between units for consistency with timers, min and max checks for clks
Build on RHEL9 docker image / build (push) Successful in 3m57s
Build on RHEL8 docker image / build (push) Successful in 4m46s
Run Simulator Tests on local RHEL9 / build (push) Failing after 14m34s
Run Simulator Tests on local RHEL8 / build (push) Failing after 16m51s

This commit is contained in:
2026-04-15 14:51:39 +02:00
parent b0b2991241
commit f253296c23
7 changed files with 96 additions and 48 deletions
@@ -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)
@@ -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) {
@@ -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
@@ -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});
+12 -9
View File
@@ -111,13 +111,19 @@ typename std::enable_if<is_frequency<T>::value, std::string>::type
ToString(T f, const std::string &unit) {
double val = static_cast<double>(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<double>(1e3)) << ' ' << unit;
else if (unit == "MHz")
os << val / (static_cast<double>(1e6)) << ' ' << unit;
if (unitLower == "hz")
os << val << unit;
else if (unitLower == "khz")
os << val / (static_cast<double>(1e3)) << unit;
else if (unitLower == "mhz")
os << val / (static_cast<double>(1e6)) << unit;
else
throw std::runtime_error("Unknown unit: " + unit);
return os.str();
@@ -412,7 +418,4 @@ std::vector<T> StringTo(const std::vector<std::string> &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
-19
View File
@@ -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<int>(fval * 1000000.0);
} else if (unit == "kHz") {
return static_cast<int>(fval * 1000.0);
} else if (unit == "Hz") {
return static_cast<int>(fval);
} else {
throw RuntimeError("Unknown unit: " + unit +
". Supported units: MHz, kHz, Hz");
}
}
} // namespace sls
+8 -8
View File
@@ -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<defs::Hz>("150", "Hz") == defs::Hz(150));
REQUIRE(StringTo<defs::Hz>("150Hz") == defs::Hz(150));
REQUIRE(StringTo<defs::Hz>("1.5 kHz") == defs::Hz(1500));
REQUIRE(StringTo<defs::Hz>("150Hz") == defs::Hz(150));
REQUIRE(StringTo<defs::Hz>("1.5kHz") == defs::Hz(1500));
REQUIRE(StringTo<defs::Hz>("1.5MHz") == defs::Hz(1500000));
REQUIRE_THROWS(StringTo<defs::Hz>("5xs"));
REQUIRE_THROWS(StringTo<defs::Hz>("asvn"));