Skip to content

Commit

Permalink
skeleton of implementing get/set next frame number in G2 (firmware on…
Browse files Browse the repository at this point in the history
…ly has set, no get
  • Loading branch information
thattil committed Sep 18, 2024
1 parent 33b8e08 commit 17c5375
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 100 deletions.
2 changes: 1 addition & 1 deletion python/slsdet/detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
209 changes: 119 additions & 90 deletions slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -75,6 +74,7 @@ int filterResistor = 0;
int cdsGain = 0;
int detPos[2] = {};
int chipConfigured = 0;
uint64_t nextFrameNumber = 0;

int isInitCheckDone() { return initCheckDone; }

Expand Down Expand Up @@ -424,6 +424,7 @@ void setupDetector() {
detPos[0] = 0;
detPos[1] = 0;
chipConfigured = 0;
nextFrameNumber = 0;

thisSettings = UNINITIALIZED;
injectedChannelsOffset = 0;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion slsDetectorSoftware/generator/commands.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions slsDetectorSoftware/include/sls/Detector.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,11 @@ class Detector {
Result<std::vector<int64_t>>
getRxCurrentFrameIndex(Positions pos = {}) const;

/** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB] */
/** [Eiger][Jungfrau][Moench][CTB][Xilinx CTB][Gotthard2] */
Result<uint64_t> 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
Expand Down
3 changes: 2 additions & 1 deletion slsDetectorSoftware/src/Detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion slsDetectorSoftware/tests/Caller/test-Caller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
{
Expand Down

0 comments on commit 17c5375

Please sign in to comment.