From 17c5375d813eac3b33903db01bed87dd60a2564d Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 18 Sep 2024 17:00:30 +0200 Subject: [PATCH] skeleton of implementing get/set next frame number in G2 (firmware only has set, no get --- python/slsdet/detector.py | 2 +- .../gotthard2DetectorServer/RegisterDefs.h | 5 + .../slsDetectorFunctionList.c | 209 ++++++++++-------- .../slsDetectorServer_defs.h | 1 + .../include/slsDetectorFunctionList.h | 2 +- .../src/slsDetectorServer_funcs.c | 4 +- slsDetectorSoftware/generator/commands.yaml | 2 +- slsDetectorSoftware/include/sls/Detector.h | 6 +- slsDetectorSoftware/src/Detector.cpp | 3 +- .../tests/Caller/test-Caller.cpp | 2 +- 10 files changed, 136 insertions(+), 100 deletions(-) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 12dcc68f6..a7caa82d2 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -743,7 +743,7 @@ def rx_framescaught(self): @property @element def nextframenumber(self): - """[Eiger][Jungfrau][Moench][CTB][Xilinx CTB] Next frame number. Stopping acquisition might result in different frame numbers for different modules. """ + """[Eiger][Jungfrau][Moench][CTB][Xilinx CTB][Gotthard2] Next frame number. Stopping acquisition might result in different frame numbers for different modules. So, after stopping, next frame number (max + 1) is set for all the modules afterwards.""" return self.getNextFrameNumber() @nextframenumber.setter diff --git a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h index 097238426..6e46284fd 100644 --- a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h @@ -135,11 +135,16 @@ #define DTA_OFFSET_REG (0x0A * REG_OFFSET + BASE_CONTROL) +/** Module ID Register */ #define MOD_ID_REG (0x0B * REG_OFFSET + BASE_CONTROL) #define MOD_ID_OFST (0) #define MOD_ID_MSK (0x0000FFFF << MOD_ID_OFST) +/** Next Frame Number Register */ +#define FRAME_NUMBER_LSB_REG (0x0C * REG_OFFSET + BASE_CONTROL) +#define FRAME_NUMBER_MSB_REG (0x0D * REG_OFFSET + BASE_CONTROL) + /* ASIC registers --------------------------------------------------*/ /* ASIC Config register */ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 7038591e4..76f196405 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -45,7 +45,6 @@ char initErrorMessage[MAX_STR_LENGTH]; #ifdef VIRTUAL pthread_t pthread_virtual_tid; -int64_t virtual_currentFrameNumber = 2; int virtual_moduleid = 0; #endif @@ -75,6 +74,7 @@ int filterResistor = 0; int cdsGain = 0; int detPos[2] = {}; int chipConfigured = 0; +uint64_t nextFrameNumber = 0; int isInitCheckDone() { return initCheckDone; } @@ -424,6 +424,7 @@ void setupDetector() { detPos[0] = 0; detPos[1] = 0; chipConfigured = 0; + nextFrameNumber = 0; thisSettings = UNINITIALIZED; injectedChannelsOffset = 0; @@ -528,6 +529,7 @@ void setupDetector() { setSettings(DEFAULT_SETTINGS); // Initialization of acquistion parameters + setNextFrameNumber(DEFAULT_FRAME_NUMBER); setNumFrames(DEFAULT_NUM_FRAMES); setNumTriggers(DEFAULT_NUM_CYCLES); setNumBursts(DEFAULT_NUM_BURSTS); @@ -1068,6 +1070,21 @@ int getDynamicRange(int *retval) { } /* parameters - timer */ + +int setNextFrameNumber(uint64_t value) { + LOG(logINFO, + ("Setting next frame number: %lu\n", value)); + setU64BitReg(value, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); + nextFrameNumber = value; + return OK; +} + +int getNextFrameNumber(uint64_t *value) { + // TODO: handle triggers/bursts + *value = nextFrameNumber - (getNumFramesLeft() + 1); + return OK; +} + void setNumFrames(int64_t val) { if (val > 0) { numFramesReg = val; @@ -3360,6 +3377,12 @@ int startStateMachine() { // start state machine bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STRT_ACQSTN_MSK); + // increment the current frame number by (#frames x #triggers) + // updated when stopped + // updating here also take care of non blocking acquisitions + //TODO handle bursts + nextFrameNumber += getNumFrames() * getNumTriggers(); + LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG))); return OK; } @@ -3427,107 +3450,113 @@ void *start_timer(void *arg) { *((uint16_t *)(vetoData + i)) = i; } - int iRxEntry = firstDest; - // loop over number of repeats - for (int repeatNr = 0; repeatNr != numRepeats; ++repeatNr) { + { + uint64_t frameNr = 0; + getNextFrameNumber(&frameNr); - struct timespec rbegin, rend; - clock_gettime(CLOCK_REALTIME, &rbegin); + int iRxEntry = firstDest; + // loop over number of repeats + for (int repeatNr = 0; repeatNr != numRepeats; ++repeatNr) { - // loop over number of frames - for (int frameNr = 0; frameNr != numFrames; ++frameNr) { + struct timespec rbegin, rend; + clock_gettime(CLOCK_REALTIME, &rbegin); - // check if manual stop - if (sharedMemory_getStop() == 1) { - break; - } + // loop over number of frames + for (int iframes = 0; iframes != numFrames; ++iframes) { - // change gain and data for every frame - { - const int nchannels = NCHIP * NCHAN; - int gainVal = 0; - for (int i = 0; i < nchannels; ++i) { - if ((i % nchannels) < 400) { - gainVal = 1 + frameNr; - } else if ((i % nchannels) < 800) { - gainVal = 2 + frameNr; - } else { - gainVal = 3 + frameNr; + // check if manual stop + if (sharedMemory_getStop() == 1) { + setNextFrameNumber(frameNr + (repeatNr * numFrames) + iframes + 1); + break; + } + + // change gain and data for every frame + { + const int nchannels = NCHIP * NCHAN; + int gainVal = 0; + for (int i = 0; i < nchannels; ++i) { + if ((i % nchannels) < 400) { + gainVal = 1 + iframes; + } else if ((i % nchannels) < 800) { + gainVal = 2 + iframes; + } else { + gainVal = 3 + iframes; + } + int dataVal = + *((uint16_t *)(imageData + i * sizeof(uint16_t))); + dataVal += iframes; + int channelVal = + (dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST); + *((uint16_t *)(imageData + i * sizeof(uint16_t))) = + (uint16_t)channelVal; } - int dataVal = - *((uint16_t *)(imageData + i * sizeof(uint16_t))); - dataVal += frameNr; - int channelVal = - (dataVal & ~GAIN_VAL_MSK) | (gainVal << GAIN_VAL_OFST); - *((uint16_t *)(imageData + i * sizeof(uint16_t))) = - (uint16_t)channelVal; } - } - // sleep for exposure time - struct timespec begin, end; - clock_gettime(CLOCK_REALTIME, &begin); - usleep(expUs); - - // first interface - char packetData[packetsize]; - memset(packetData, 0, packetsize); - // set header - sls_detector_header *header = (sls_detector_header *)(packetData); - header->detType = (uint16_t)myDetectorType; - header->version = SLS_DETECTOR_HEADER_VERSION; - header->frameNumber = virtual_currentFrameNumber; - header->packetNumber = 0; - header->modId = virtual_moduleid; - header->row = detPos[Y]; - header->column = detPos[X]; - // fill data - memcpy(packetData + sizeof(sls_detector_header), imageData, - datasize); - // send 1 packet = 1 frame - sendUDPPacket(iRxEntry, 0, packetData, packetsize); - - // second interface (veto) - char packetData2[vetopacketsize]; - memset(packetData2, 0, vetopacketsize); - if (i10gbe) { + // sleep for exposure time + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + usleep(expUs); + + // first interface + char packetData[packetsize]; + memset(packetData, 0, packetsize); // set header - veto_header *header = (veto_header *)(packetData2); - header->frameNumber = virtual_currentFrameNumber; - header->bunchId = 0; + sls_detector_header *header = (sls_detector_header *)(packetData); + header->detType = (uint16_t)myDetectorType; + header->version = SLS_DETECTOR_HEADER_VERSION; + header->frameNumber = frameNr + (repeatNr * numFrames) + iframes; + header->packetNumber = 0; + header->modId = virtual_moduleid; + header->row = detPos[Y]; + header->column = detPos[X]; // fill data - memcpy(packetData2 + sizeof(veto_header), vetoData, - vetodatasize); + memcpy(packetData + sizeof(sls_detector_header), imageData, + datasize); // send 1 packet = 1 frame - sendUDPPacket(iRxEntry, 1, packetData2, vetopacketsize); - } - LOG(logINFO, - ("Sent frame %s: %d (bursts/ triggers: %d) [%lld] to E%d\n", - (i10gbe ? "(+veto)" : ""), frameNr, repeatNr, - (long long unsigned int)virtual_currentFrameNumber, iRxEntry)); - clock_gettime(CLOCK_REALTIME, &end); - int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + - (end.tv_nsec - begin.tv_nsec)); - - // sleep for (period - exptime) - if (frameNr < numFrames) { // if there is a next frame - if (periodNs > timeNs) { - usleep((periodNs - timeNs) / 1000); + sendUDPPacket(iRxEntry, 0, packetData, packetsize); + + // second interface (veto) + char packetData2[vetopacketsize]; + memset(packetData2, 0, vetopacketsize); + if (i10gbe) { + // set header + veto_header *header = (veto_header *)(packetData2); + header->frameNumber = frameNr + (repeatNr * numFrames) + iframes; + header->bunchId = 0; + // fill data + memcpy(packetData2 + sizeof(veto_header), vetoData, + vetodatasize); + // send 1 packet = 1 frame + sendUDPPacket(iRxEntry, 1, packetData2, vetopacketsize); + } + LOG(logINFO, + ("Sent frame %s: %d (bursts/ triggers: %d) [%lld] to E%d\n", + (i10gbe ? "(+veto)" : ""), frameNr, repeatNr, (frameNr + (repeatNr * numFrames) + iframe), iRxEntry)); + clock_gettime(CLOCK_REALTIME, &end); + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + // sleep for (period - exptime) + if (iframes < numFrames) { // if there is a next frame + if (periodNs > timeNs) { + usleep((periodNs - timeNs) / 1000); + } + } + ++iRxEntry; + if (iRxEntry == numUdpDestinations) { + iRxEntry = 0; } } - ++virtual_currentFrameNumber; - ++iRxEntry; - if (iRxEntry == numUdpDestinations) { - iRxEntry = 0; - } - } - clock_gettime(CLOCK_REALTIME, &rend); - int64_t timeNs = ((rend.tv_sec - rbegin.tv_sec) * 1E9 + - (rend.tv_nsec - rbegin.tv_nsec)); + setNextFrameNumber(frameNr + (repeatNr * numFrames) + iframes + 1); + + clock_gettime(CLOCK_REALTIME, &rend); + int64_t timeNs = ((rend.tv_sec - rbegin.tv_sec) * 1E9 + + (rend.tv_nsec - rbegin.tv_nsec)); - // sleep for (repeatPeriodNs - time remaining) - if (repeatNr < numRepeats) { // if there is a next repeat - if (repeatPeriodNs > timeNs) { - usleep((repeatPeriodNs - timeNs) / 1000); + // sleep for (repeatPeriodNs - time remaining) + if (repeatNr < numRepeats) { // if there is a next repeat + if (repeatPeriodNs > timeNs) { + usleep((repeatPeriodNs - timeNs) / 1000); + } } } } diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index de229932a..3def17da8 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -61,6 +61,7 @@ #define DEFAULT_BURST_MODE (BURST_INTERNAL) #define DEFAULT_FILTER_RESISTOR (0) #define DEFAILT_CDS_GAIN (0) +#define DEFAULT_FRAME_NUMBER (1) #define DEFAULT_NUM_FRAMES (1) #define DEFAULT_NUM_CYCLES (1) #define DEFAULT_NUM_BURSTS (1) diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index af3177878..ac59a0c55 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -270,7 +270,7 @@ int selectStoragecellStart(int pos); int getMaxStoragecellStart(); #endif #if defined(JUNGFRAUD) || defined(MOENCHD) || defined(EIGERD) || \ - defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) + defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) || defined(GOTTHARD2D) int setNextFrameNumber(uint64_t value); int getNextFrameNumber(uint64_t *value); #endif diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index acaa051c0..4eac67218 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4711,7 +4711,7 @@ int set_next_frame_number(int file_des) { LOG(logDEBUG1, ("Setting next frame number to %llu\n", arg)); #if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(MOENCHD) && \ - !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD) + !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD) && !defined(GOTTHARD2D) functionNotImplemented(); #else // only set @@ -4790,7 +4790,7 @@ int get_next_frame_number(int file_des) { LOG(logDEBUG1, ("Getting next frame number \n")); #if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(MOENCHD) && \ - !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD) + !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD) && !defined(GOTTHARD2D) functionNotImplemented(); #else // get diff --git a/slsDetectorSoftware/generator/commands.yaml b/slsDetectorSoftware/generator/commands.yaml index ccf52818e..2cdfc6f68 100644 --- a/slsDetectorSoftware/generator/commands.yaml +++ b/slsDetectorSoftware/generator/commands.yaml @@ -764,7 +764,7 @@ readnrows: function: setReadNRows nextframenumber: - help: "[n_value]\n\t[Eiger][Jungfrau][Moench][Ctb][Xilinx Ctb] Next frame number. Stopping acquisition might result in different frame numbers for different modules." + help: "[n_value]\n\t[Eiger][Jungfrau][Moench][Ctb][Xilinx Ctb][Gotthard2] Next frame number. Stopping acquisition might result in different frame numbers for different modules. So, after stopping, next frame number (max + 1) is set for all the modules afterwards." inherit_actions: INTEGER_COMMAND_VEC_ID actions: GET: diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 9c01f2b30..5de374c97 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -658,11 +658,11 @@ class Detector { Result> getRxCurrentFrameIndex(Positions pos = {}) const; - /** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB] */ + /** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB][Gotthard2] */ Result getNextFrameNumber(Positions pos = {}) const; - /** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB] Stopping acquisition might - * result in different frame numbers for different modules.*/ + /** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB][Gotthard2] Stopping acquisition might + * result in different frame numbers for different modules. So, after stopping, next frame number (max + 1) is set for all the modules afterwards.*/ void setNextFrameNumber(uint64_t value, Positions pos = {}); /** [Eiger][Mythen3][Jungfrau][Moench] Sends an internal software trigger to diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index a20a54c74..44e02624c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -910,7 +910,8 @@ void Detector::stopDetector(Positions pos) { case defs::JUNGFRAU: case defs::MOENCH: case defs::CHIPTESTBOARD: - case defs::XILINX_CHIPTESTBOARD: { + case defs::XILINX_CHIPTESTBOARD: + case defs::GOTTHARD2: { auto res = getNextFrameNumber(pos); if (!res.equal()) { uint64_t maxVal = 0; diff --git a/slsDetectorSoftware/tests/Caller/test-Caller.cpp b/slsDetectorSoftware/tests/Caller/test-Caller.cpp index 8502e3fa8..0707a3b23 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller.cpp @@ -2367,7 +2367,7 @@ TEST_CASE("CALLER::nextframenumber", "[.cmdcall]") { auto det_type = det.getDetectorType().squash(); if (det_type == defs::EIGER || det_type == defs::JUNGFRAU || det_type == defs::MOENCH || det_type == defs::CHIPTESTBOARD || - det_type == defs::XILINX_CHIPTESTBOARD) { + det_type == defs::XILINX_CHIPTESTBOARD || det_type == defs::GOTTHARD2) { auto prev_sfnum = det.getNextFrameNumber(); REQUIRE_THROWS(caller.call("nextframenumber", {"0"}, -1, PUT)); {