diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 89d38f569..2212fc22f 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -7255,7 +7255,8 @@ int get_receiver_parameters(int file_des) { // dynamic range ret = getDynamicRange(&i32); if (ret == FAIL) { - i32 = 0; + sprintf(mess, "Could not get dynamic range.\n"); + return sendError(file_des); } n += sendData(file_des, &i32, sizeof(i32), INT32); if (n < 0) @@ -7434,6 +7435,20 @@ int get_receiver_parameters(int file_des) { u32 = 0; #endif n += sendData(file_des, &u32, sizeof(u32), INT32); + if (n < 0) + return printSocketReadError(); + + // readout speed +#if !defined(CHIPTESTBOARDD) && !defined(XILINX_CHIPTESTBOARDD) + ret = getReadoutSpeed(&i32); + if (ret == FAIL) { + sprintf(mess, "Could not get readout speed.\n"); + return sendError(file_des); + } else { + i32 = 0; + } +#endif + n += sendData(file_des, &i32, sizeof(i32), INT32); if (n < 0) return printSocketReadError(); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 440386080..f6cb90b62 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -749,6 +749,9 @@ slsDetectorDefs::speedLevel Module::getReadoutSpeed() const { void Module::setReadoutSpeed(speedLevel value) { sendToDetector(F_SET_READOUT_SPEED, value, nullptr); + if (shm()->useReceiverFlag) { + sendToReceiver(F_SET_RECEIVER_READOUT_SPEED, value, nullptr); + } } int Module::getClockDivider(int clkIndex) const { diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 902870a8f..41c54e2e5 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -221,7 +221,7 @@ int ClientInterface::functionTable(){ flist[F_GET_RECEIVER_DBIT_REORDER] = &ClientInterface::get_dbit_reorder; flist[F_SET_RECEIVER_DBIT_REORDER] = &ClientInterface::set_dbit_reorder; flist[F_RECEIVER_GET_ROI_METADATA] = &ClientInterface::get_roi_metadata; - + flist[F_SET_RECEIVER_READOUT_SPEED] = &ClientInterface::set_readout_speed; for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << @@ -411,6 +411,8 @@ int ClientInterface::setup_receiver(Interface &socket) { impl()->setReadoutMode(arg.roMode); impl()->setTenGigaADCEnableMask(arg.adc10gMask); impl()->setTransceiverEnableMask(arg.transceiverMask); + } else { + impl()->setReadoutSpeed(arg.readoutSpeed); } if (detType == CHIPTESTBOARD) { impl()->setADCEnableMask(arg.adcMask); @@ -1851,4 +1853,33 @@ int ClientInterface::get_roi_metadata(Interface &socket) { return OK; } +int ClientInterface::set_readout_speed(Interface &socket) { + auto value = socket.Receive(); + verifyIdle(socket); + switch (detType) { + case GOTTHARD2: + if (value != G2_108MHZ && value != G2_144MHZ) + throw RuntimeError("Invalid readout speed for GOTTHARD2: " + + std::to_string(value)); + break; + + case EIGER: + case JUNGFRAU: + case MYTHEN3: + case MOENCH: + if (value < 0 || value > QUARTER_SPEED) { + throw RuntimeError("Invalid readout speed: " + + std::to_string(value)); + } + break; + + default: + functionNotImplemented(); + } + + LOG(logDEBUG1) << "Setting readout speed to " << value; + impl()->setReadoutSpeed(static_cast(value)); + return socket.Send(OK); +} + } // namespace sls diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index e17a3ab85..f2dbaa764 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -167,6 +167,7 @@ class ClientInterface : private virtual slsDetectorDefs { int get_dbit_reorder(ServerInterface &socket); int set_dbit_reorder(ServerInterface &socket); int get_roi_metadata(ServerInterface &socket); + int set_readout_speed(ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index faf3bf031..82744bc23 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -983,6 +983,7 @@ void Implementation::StartMasterWriter() { masterAttributes.gateDelayArray[2] = gateDelay3; masterAttributes.gates = numberOfGates; masterAttributes.additionalJsonHeader = additionalJsonHeader; + masterAttributes.readoutSpeed = readoutSpeed; // create master file masterFileName = dataProcessor[0]->CreateMasterFile( @@ -1781,6 +1782,15 @@ void Implementation::setTransceiverEnableMask(uint32_t mask) { LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame); } +slsDetectorDefs::speedLevel Implementation::getReadoutSpeed() const { + return readoutSpeed; +} + +void Implementation::setReadoutSpeed(const slsDetectorDefs::speedLevel i) { + readoutSpeed = i; + LOG(logINFO) << "Readout Speed: " << ToString(readoutSpeed); +} + /************************************************** * * * Callbacks * diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 31359930f..2699bbfc4 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -256,10 +256,12 @@ class Implementation : private virtual slsDetectorDefs { bool getDbitReorder() const; /* [Ctb] */ void setDbitReorder(const bool reorder); - uint32_t getTransceiverEnableMask() const; /* [Ctb] */ void setTransceiverEnableMask(const uint32_t mask); + speedLevel getReadoutSpeed() const; + /* [Eiger][Jungfrau][Moench][Mythen3][Gotthard2]*/ + void setReadoutSpeed(const speedLevel i); /************************************************** * * @@ -369,6 +371,7 @@ class Implementation : private virtual slsDetectorDefs { int thresholdEnergyeV{-1}; std::array thresholdAllEnergyeV = {{-1, -1, -1}}; std::vector rateCorrections; + speedLevel readoutSpeed{FULL_SPEED}; // callbacks void (*startAcquisitionCallBack)(const startCallbackHeader, diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index 211b6f439..38af32c0f 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -562,6 +562,16 @@ void MasterAttributes::WriteHDF5TransceiverSamples(H5::Group *group) { "Transceiver Samples", H5::PredType::NATIVE_INT, dataspace); dataset.write(&transceiverSamples, H5::PredType::NATIVE_INT); } + +void MasterAttributes::WriteHDF5ReadoutSpeed(H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::StrType strdatatype(H5::PredType::C_S1, 256); + H5::DataSet dataset = + group->createDataSet("Readout Speed", strdatatype, dataspace); + char c[1024]{}; + strcpy_safe(c, ToString(readoutSpeed)); + dataset.write(c, strdatatype); +} #endif void MasterAttributes::GetJungfrauBinaryAttributes( @@ -575,6 +585,8 @@ void MasterAttributes::GetJungfrauBinaryAttributes( w->Uint(numUDPInterfaces); w->Key("Number of rows"); w->Uint(readNRows); + w->Key("Readout Speed"); + w->String(ToString(readoutSpeed).c_str()); } #ifdef HDF5C @@ -584,6 +596,7 @@ void MasterAttributes::WriteJungfrauHDF5Attributes(H5::Group *group) { MasterAttributes::WriteHDF5Period(group); MasterAttributes::WriteHDF5NumUDPInterfaces(group); MasterAttributes::WriteHDF5ReadNRows(group); + MasterAttributes::WriteHDF5ReadoutSpeed(group); } #endif @@ -598,6 +611,8 @@ void MasterAttributes::GetMoenchBinaryAttributes( w->Uint(numUDPInterfaces); w->Key("Number of rows"); w->Uint(readNRows); + w->Key("Readout Speed"); + w->String(ToString(readoutSpeed).c_str()); } #ifdef HDF5C @@ -607,6 +622,7 @@ void MasterAttributes::WriteMoenchHDF5Attributes(H5::Group *group) { MasterAttributes::WriteHDF5Period(group); MasterAttributes::WriteHDF5NumUDPInterfaces(group); MasterAttributes::WriteHDF5ReadNRows(group); + MasterAttributes::WriteHDF5ReadoutSpeed(group); } #endif @@ -633,6 +649,8 @@ void MasterAttributes::GetEigerBinaryAttributes( w->Int(readNRows); w->Key("Rate Corrections"); w->String(ToString(ratecorr).c_str()); + w->Key("Readout Speed"); + w->String(ToString(readoutSpeed).c_str()); } #ifdef HDF5C @@ -648,6 +666,7 @@ void MasterAttributes::WriteEigerHDF5Attributes(H5::Group *group) { MasterAttributes::WriteHDF5SubQuad(group); MasterAttributes::WriteHDF5ReadNRows(group); MasterAttributes::WriteHDF5RateCorrections(group); + MasterAttributes::WriteHDF5ReadoutSpeed(group); } #endif @@ -674,6 +693,8 @@ void MasterAttributes::GetMythen3BinaryAttributes( w->Uint(gates); w->Key("Threshold Energies"); w->String(ToString(thresholdAllEnergyeV).c_str()); + w->Key("Readout Speed"); + w->String(ToString(readoutSpeed).c_str()); } #ifdef HDF5C @@ -687,6 +708,7 @@ void MasterAttributes::WriteMythen3HDF5Attributes(H5::Group *group) { MasterAttributes::WriteHDF5GateDelayArray(group); MasterAttributes::WriteHDF5Gates(group); MasterAttributes::WriteHDF5ThresholdEnergies(group); + MasterAttributes::WriteHDF5ReadoutSpeed(group); } #endif @@ -699,6 +721,8 @@ void MasterAttributes::GetGotthard2BinaryAttributes( w->String(ToString(period).c_str()); w->Key("Burst Mode"); w->String(ToString(burstMode).c_str()); + w->Key("Readout Speed"); + w->String(ToString(readoutSpeed).c_str()); } #ifdef HDF5C @@ -707,6 +731,7 @@ void MasterAttributes::WriteGotthard2HDF5Attributes(H5::Group *group) { MasterAttributes::WriteHDF5Exptime(group); MasterAttributes::WriteHDF5Period(group); MasterAttributes::WriteHDF5BurstMode(group); + MasterAttributes::WriteHDF5ReadoutSpeed(group); } #endif diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index f195ee70a..bda071326 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -64,6 +64,7 @@ class MasterAttributes { uint32_t gates; std::map additionalJsonHeader; uint64_t framesInFile{0}; + slsDetectorDefs::speedLevel readoutSpeed{slsDetectorDefs::FULL_SPEED}; MasterAttributes() = default; ~MasterAttributes() = default; @@ -111,6 +112,7 @@ class MasterAttributes { void WriteHDF5TransceiverMask(H5::Group *group); void WriteHDF5TransceiverFlag(H5::Group *group); void WriteHDF5TransceiverSamples(H5::Group *group); + void WriteHDF5ReadoutSpeed(H5::Group *group); #endif void GetJungfrauBinaryAttributes( diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 942774bbf..0e1e5cc80 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -663,6 +663,7 @@ enum streamingInterface { scanParameters scanParams{}; int transceiverSamples{0}; uint32_t transceiverMask{0}; + speedLevel readoutSpeed{FULL_SPEED}; } __attribute__((packed)); #endif diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index 20688941c..6d49fee7e 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -413,6 +413,7 @@ enum detFuncs { F_GET_RECEIVER_DBIT_REORDER, F_SET_RECEIVER_DBIT_REORDER, F_RECEIVER_GET_ROI_METADATA, + F_SET_RECEIVER_READOUT_SPEED, NUM_REC_FUNCTIONS }; @@ -822,6 +823,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_RECEIVER_DBIT_REORDER: return "F_GET_RECEIVER_DBIT_REORDER"; case F_SET_RECEIVER_DBIT_REORDER: return "F_SET_RECEIVER_DBIT_REORDER"; case F_RECEIVER_GET_ROI_METADATA: return "F_RECEIVER_GET_ROI_METADATA"; + case F_SET_RECEIVER_READOUT_SPEED: return "F_SET_RECEIVER_READOUT_SPEED"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function"; diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 212514f6f..98790f7cd 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -89,6 +89,7 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) { << "scanParams:" << ToString(r.scanParams) << std::endl << "transceiverSamples:" << r.transceiverSamples << std::endl << "transceiverMask:" << r.transceiverMask << std::endl + << "readoutSpeed:" << ToString(r.readoutSpeed) << std::endl << ']'; return oss.str(); }