From d616549f874bdc4bb69bc20e62ea2f5f3d8cce28 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 29 Apr 2026 16:42:54 +0200 Subject: [PATCH] tolerance process --- slsDetectorServers/CMakeLists.txt | 2 +- .../slsDetectorFunctionList.c | 75 +++++++++++-------- .../slsDetectorFunctionList.h | 8 +- .../slsDetectorServer/include/common.h | 12 +++ .../slsDetectorServer/src/common.c | 14 ++++ .../slsDetectorServer/src/loadPattern.c | 36 +++++---- .../src/slsDetectorServer_funcs.c | 24 ------ .../Caller/test-Caller-chiptestboard.cpp | 13 ++++ 8 files changed, 107 insertions(+), 77 deletions(-) diff --git a/slsDetectorServers/CMakeLists.txt b/slsDetectorServers/CMakeLists.txt index 9d1db734c..19aa10162 100644 --- a/slsDetectorServers/CMakeLists.txt +++ b/slsDetectorServers/CMakeLists.txt @@ -11,7 +11,7 @@ install(TARGETS slsProjectCSettings PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) add_subdirectory(ctbDetectorServer) -add_subdirectory(xilinx_ctbDetectorServer) +#add_subdirectory(xilinx_ctbDetectorServer) add_subdirectory(eigerDetectorServer) add_subdirectory(jungfrauDetectorServer) add_subdirectory(mythen3DetectorServer) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index d7ae8970d..b9b1e8e73 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -1137,12 +1137,8 @@ int getNumTransceiverSamples() { return ntSamples; } int setExpTime(int64_t val) { setPatternWaitInterval(0, val); - - // Tolerance: three clock periods in ns. int64_t retval = getExpTime(); - int64_t toleranceNs = 3 * (1000000000 / clkFrequency[RUN_CLK]); - int64_t diff = val - retval; - if (diff < -toleranceNs || diff > toleranceNs) { + if (retval != val) { return FAIL; } return OK; @@ -1150,55 +1146,68 @@ int setExpTime(int64_t val) { int64_t getExpTime() { return getPatternWaitInterval(0); } -int setPeriod(int64_t val) { +int setPeriod(int64_t val, char *mess) { if (val < 0) { - LOG(logERROR, ("Invalid period: %lld ns\n", (long long int)val)); + sprintf(mess, "Invalid period: %lld ns\n", (long long int)val); + LOG(logERROR, (mess)); return FAIL; } LOG(logINFO, ("Setting period %lld ns\n", (long long int)val)); - val *= (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); - set64BitReg(val, PERIOD_LSB_REG, PERIOD_MSB_REG); + uint64_t numClocks = ns_to_clocks(val, clkFrequency[SYNC_CLK]); + set64BitReg(numClocks, PERIOD_LSB_REG, PERIOD_MSB_REG); // validate for tolerance - int64_t retval = getPeriod(); - val /= (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); - int64_t toleranceNs = 3 * (1000000000 / clkFrequency[SYNC_CLK]); - int64_t diff = val - retval; - if (diff < -toleranceNs || diff > toleranceNs) { + int64_t retval = 0; + int ret = getPeriod(&retval, mess); + if (ret == FAIL) { return FAIL; } + validate64_timer(&ret, mess, val, retval, clkFrequency[SYNC_CLK], "period"); + return ret; +} + +int getPeriod(int64_t *retval, char *mess) { + if (clkFrequency[SYNC_CLK] == 0) { + sprintf(mess, "Cannot get period. Sync clock frequency is 0.\n"); + LOG(logERROR, (mess)); + return FAIL; + } + uint64_t numClocks = get64BitReg(PERIOD_LSB_REG, PERIOD_MSB_REG); + *retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]); return OK; } -int64_t getPeriod() { - return get64BitReg(PERIOD_LSB_REG, PERIOD_MSB_REG) / - (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); -} - -int setDelayAfterTrigger(int64_t val) { +int setDelayAfterTrigger(int64_t val, char *mess) { if (val < 0) { - LOG(logERROR, - ("Invalid delay after trigger: %lld ns\n", (long long int)val)); + sprintf(mess, "Invalid delay after trigger: %lld ns\n", + (long long int)val); + LOG(logERROR, (mess)); return FAIL; } LOG(logINFO, ("Setting delay after trigger %lld ns\n", (long long int)val)); - val *= (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); - set64BitReg(val, DELAY_LSB_REG, DELAY_MSB_REG); + uint64_t numClocks = ns_to_clocks(val, clkFrequency[SYNC_CLK]); + set64BitReg(numClocks, DELAY_LSB_REG, DELAY_MSB_REG); // validate for tolerance - int64_t retval = getDelayAfterTrigger(); - val /= (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); - int64_t toleranceNs = 3 * (1000000000 / clkFrequency[SYNC_CLK]); - int64_t diff = val - retval; - if (diff < -toleranceNs || diff > toleranceNs) { + int64_t retval = 0; + int ret = getDelayAfterTrigger(&retval, mess); + if (ret == FAIL) { return FAIL; } - return OK; + validate64_timer(&ret, mess, val, retval, clkFrequency[SYNC_CLK], + "delay after trigger"); + return ret; } -int64_t getDelayAfterTrigger() { - return get64BitReg(DELAY_LSB_REG, DELAY_MSB_REG) / - (NS_TO_CLK_CYCLE * clkFrequency[SYNC_CLK]); +int getDelayAfterTrigger(int64_t *retval, char *mess) { + if (clkFrequency[SYNC_CLK] == 0) { + sprintf(mess, "Cannot get period. Sync clock frequency is 0.\n"); + LOG(logERROR, (mess)); + return FAIL; + } + uint64_t numClocks = get64BitReg(DELAY_LSB_REG, DELAY_MSB_REG); + *retval = clocks_to_ns(numClocks, clkFrequency[SYNC_CLK]); + return OK; } int64_t getNumFramesLeft() { diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h index 3dccdf8c1..10fc4f155 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h @@ -100,8 +100,8 @@ void setNumTriggers(int64_t val); int64_t getNumTriggers(); int setExpTime(int64_t val); int64_t getExpTime(); -int setPeriod(int64_t val); -int64_t getPeriod(); +int setPeriod(int64_t val, char *mess); +int getPeriod(int64_t *retval, char *mess); int setNumAnalogSamples(int val); int getNumAnalogSamples(); int setNumDigitalSamples(int val); @@ -111,8 +111,8 @@ int getNumTransceiverSamples(); int64_t getNumFramesLeft(); int64_t getNumTriggersLeft(); -int setDelayAfterTrigger(int64_t val); -int64_t getDelayAfterTrigger(); +int setDelayAfterTrigger(int64_t val, char *mess); +int getDelayAfterTrigger(int64_t *retval, char *mess); int64_t getDelayAfterTriggerLeft(); int64_t getPeriodLeft(); int64_t getFramesFromStart(); diff --git a/slsDetectorServers/slsDetectorServer/include/common.h b/slsDetectorServers/slsDetectorServer/include/common.h index 7c6139f16..fd996c4bd 100644 --- a/slsDetectorServers/slsDetectorServer/include/common.h +++ b/slsDetectorServers/slsDetectorServer/include/common.h @@ -21,6 +21,15 @@ enum numberMode { DEC, HEX }; enum PROGRAM_INDEX { PROGRAM_FPGA, PROGRAM_KERNEL, PROGRAM_SERVER }; +#define NS_PER_SEC 1000000000ULL +#define HALF_NS_PER_SEC (NS_PER_SEC / 2) +static inline uint64_t ns_to_clocks(uint64_t t, uint32_t freq_hz) { + return (t * (uint64_t)freq_hz + HALF_NS_PER_SEC) / NS_PER_SEC; +} +static inline uint64_t clocks_to_ns(uint64_t clocks, uint32_t freq_hz) { + return (clocks * (uint64_t)NS_PER_SEC + freq_hz / 2) / freq_hz; +} + /** * Convert a value from a range to a different range (eg voltage to dac or vice * versa) @@ -48,6 +57,9 @@ void validate(int *ret, char *mess, int arg, int retval, char *modename, void validate64(int *ret, char *mess, int64_t arg, int64_t retval, char *modename, enum numberMode nummode); +void validate64_timer(int *ret, char *message, uint64_t arg, uint64_t retval, + uint32_t runclk_hz, char *modename); + int getModuleIdInFile(int *ret, char *mess, char *fileName); int verifyChecksumFromBuffer(char *mess, char *functionType, char *clientChecksum, char *buffer, ssize_t bytes); diff --git a/slsDetectorServers/slsDetectorServer/src/common.c b/slsDetectorServers/slsDetectorServer/src/common.c index 2bfc79bb7..327546b89 100644 --- a/slsDetectorServers/slsDetectorServer/src/common.c +++ b/slsDetectorServers/slsDetectorServer/src/common.c @@ -230,6 +230,20 @@ void validate64(int *ret, char *mess, int64_t arg, int64_t retval, } } +void validate64_timer(int *ret, char *message, uint64_t arg, uint64_t retval, + uint32_t clk_hz, char *modename) { + uint64_t arg_clks = ns_to_clocks(arg, clk_hz); + uint64_t retval_clks = ns_to_clocks(retval, clk_hz); + int64_t diff = (int64_t)retval_clks - (int64_t)arg_clks; + if (diff < 0) { + diff = -diff; + } + // tolerance = 1 clock + if (diff > 1) { + validate64(ret, message, arg, retval, modename, DEC); + } +} + int getModuleIdInFile(int *ret, char *mess, char *fileName) { const int fileNameSize = 128; char fname[fileNameSize]; diff --git a/slsDetectorServers/slsDetectorServer/src/loadPattern.c b/slsDetectorServers/slsDetectorServer/src/loadPattern.c index 9b5eb25c9..17c0d003d 100644 --- a/slsDetectorServers/slsDetectorServer/src/loadPattern.c +++ b/slsDetectorServers/slsDetectorServer/src/loadPattern.c @@ -277,6 +277,14 @@ int validate_getPatternWaitClocksAndInterval(char *message, int level, *waittime = getPatternWaitClocks(level); } else { *waittime = getPatternWaitInterval(level); + if (*waittime == (uint64_t)-1) { + sprintf( + message, + "Cannot get pattern wait interval for level %d. runclk is 0.\n", + level); + LOG(logERROR, (message)); + return FAIL; + } } return OK; } @@ -297,7 +305,7 @@ uint64_t getPatternWaitClocks(int level) { uint64_t getPatternWaitInterval(int level) { uint64_t numClocks = getPatternWaitClocks(level); - int runclk = 0; + uint32_t runclk = 0; #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) runclk = clkFrequency[RUN_CLK]; #elif MYTHEN3D @@ -307,9 +315,7 @@ uint64_t getPatternWaitInterval(int level) { LOG(logERROR, ("runclk is 0. Cannot divide by 0. Returning -1.\n")); return -1; } - double conv = NS_TO_CLK_CYCLE * runclk; - uint64_t waitNs = (uint64_t)(numClocks / conv + 0.5); - return waitNs; + return clocks_to_ns(numClocks, runclk); } int validate_setPatternWaitClocksAndInterval(char *message, int level, @@ -346,18 +352,18 @@ int validate_setPatternWaitClocksAndInterval(char *message, int level, if (clocks) { validate64(&ret, message, waittime, retval, mode, DEC); } else { + uint32_t runclk = 0; #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) - int runclk = 0; runclk = clkFrequency[RUN_CLK]; - - int64_t toleranceNs = 3 * (1000000000 / runclk); - int64_t diff = (int64_t)waittime - (int64_t)retval; - if (diff < -toleranceNs || diff > toleranceNs) { - validate64(&ret, message, waittime, retval, mode, DEC); - } -#else - validate64(&ret, message, waittime, retval, mode, DEC); +#elif MYTHEN3D + runclk = clkDivider[SYSTEM_C0]; #endif + if (retval == (uint64_t)-1) { + sprintf(message, "runclk is 0. Cannot divide by 0 for patttern " + "wait interval.\n"); + return FAIL; + } + validate64_timer(&ret, message, waittime, retval, runclk, mode); } return ret; } @@ -393,13 +399,13 @@ void setPatternWaitInterval(int level, uint64_t t) { #endif ("Setting Pattern Wait Time (level:%d) :%lld ns\n", level, (long long int)t)); - int runclk = 0; + uint32_t runclk = 0; #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) runclk = clkFrequency[RUN_CLK]; #elif MYTHEN3D runclk = clkDivider[SYSTEM_C0]; #endif - uint64_t numClocks = (uint64_t)(t * (NS_TO_CLK_CYCLE * runclk) + 0.5); + uint64_t numClocks = ns_to_clocks(t, runclk); setPatternWaitClocks(level, numClocks); } diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index e80c2cbc8..6b4c5ad26 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -3306,10 +3306,6 @@ int set_pattern_wait_clocks(int file_des) { if (ret == OK) { ret = validate_getPatternWaitClocksAndInterval(mess, loopLevel, &retval, 1); - if ((int64_t)timeval != GET_FLAG) { - validate64(&ret, mess, (int64_t)timeval, retval, - "set pattern wait clocks", DEC); - } } } #endif @@ -10898,26 +10894,6 @@ int set_pattern_wait_interval(int file_des) { if (Server_VerifyLock() == OK) { ret = validate_setPatternWaitClocksAndInterval(mess, loopLevel, timeval, 0); - if (ret == OK) { - uint64_t retval = 0; - ret = validate_getPatternWaitClocksAndInterval(mess, loopLevel, - &retval, 0); - if (ret == OK) { // is this not already validated ? why do this - // again here ? -#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) - int runclk = getFrequency(RUN_CLK); - int64_t toleranceNs = 3 * (1000000000 / runclk); - int64_t diff = (int64_t)timeval - (int64_t)retval; - if (diff < -toleranceNs || diff > toleranceNs) { - validate64(&ret, mess, (int64_t)timeval, retval, - "set pattern wait interval", DEC); - } -#else - validate64(&ret, mess, (int64_t)timeval, retval, - "set pattern wait interval", DEC); -#endif - } - } } #endif diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp index 81a8a6109..cdfcc2e92 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp @@ -1048,8 +1048,21 @@ TEST_CASE("runclk", "[.detectorintegration]") { caller.call("runclk", {}, -1, GET, oss); REQUIRE(oss.str() == "runclk 15.75MHz\n"); } + // tolerance + auto prev_exptime = det.getExptime(); + auto prev_period = det.getPeriod(); + auto prev_delay = det.getDelayAfterTrigger(); + { + caller.call("runclk", {"80", "MHz"}, -1, PUT); + REQUIRE_NOTHROW(caller.call("exptime", {"10012", "ns"}, -1, PUT)); + REQUIRE_NOTHROW(caller.call("period", {"10012", "ns"}, -1, PUT)); + REQUIRE_NOTHROW(caller.call("delay", {"10012", "ns"}, -1, PUT)); + } for (int i = 0; i != det.size(); ++i) { det.setRUNClock(prev_val[i], {i}); + det.setExptime(prev_exptime[i], {i}); + det.setPeriod(prev_period[i], {i}); + det.setDelayAfterTrigger(prev_delay[i], {i}); } } else { // clock index might work