1. Ctb transceiver ro (#773)

*  transceiverenable, tsamples, romode for tranceiver and digital_transceiver

* 202 spec instr only for transceiver mode

* removed check for empty in trans readout and clean memory before reading from fifo

* ctb read fifo strobe for all after reading all channels, adding 1us after selecting channel, changing fw date

* updated 10gb transceiver enable

----
* added transceiver (tsamples, romode(transceiver, digital_transceiver), transceiverenable (mask)

* clean memory before reading from fifo (for analog and digital as well)

* read fifo then read strobe (also corresp fw) fixes number of reads (also for analg and digital)-> increases all pipelines by 1

* fixed bug in rearranging digital data in receiver

* fixed bug in streaming size of data after rearranging

* fixed bug in setbit, clearbit,and getbit

* status checks fifo before returning idle (transmitting if data in fifo if transceiver more enabled)

* soem matterhorn specifics that will need to be put into pattern in a month or two. this is temporary.

* NOTE: breaking api. rxParameters struct has transceiverenabel and tsamples given from det to receiver
This commit is contained in:
maliakal_d 2023-07-14 16:29:21 +02:00 committed by GitHub
parent a56be25500
commit c628ae2192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 1118 additions and 238 deletions

View File

@ -3180,12 +3180,22 @@ class Detector(CppDetectorApi):
def adcenable10g(self, value): def adcenable10g(self, value):
ut.set_using_dict(self.setTenGigaADCEnableMask, value) ut.set_using_dict(self.setTenGigaADCEnableMask, value)
@property
@element
def transceiverenable(self):
"""[Ctb] Transceiver Enable Mask. Enable for each 4 transceiver channel."""
return self.getTransceiverEnableMask()
@transceiverenable.setter
def transceiverenable(self, value):
ut.set_using_dict(self.setTransceiverEnableMask, value)
#TODO: remove this command or throw if it doesnt match with digital and transceiver
@property @property
@element @element
def samples(self): def samples(self):
""" """
[CTB] Number of samples (both analog and digitial) expected. \n [CTB] Number of samples (only analog) expected. \n
""" """
return self.getNumberOfAnalogSamples() return self.getNumberOfAnalogSamples()
@ -3211,7 +3221,7 @@ class Detector(CppDetectorApi):
Note Note
------ ------
Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL, TRANSCEIVER_ONLY, DIGITAL_AND_TRANSCEIVER
Default: ANALOG_ONLY Default: ANALOG_ONLY
Example Example
@ -3246,6 +3256,16 @@ class Detector(CppDetectorApi):
def dsamples(self, N): def dsamples(self, N):
ut.set_using_dict(self.setNumberOfDigitalSamples, N) ut.set_using_dict(self.setNumberOfDigitalSamples, N)
@property
@element
def tsamples(self):
"""[CTB] Number of transceiver samples expected. """
return self.getNumberOfTransceiverSamples()
@tsamples.setter
def tsamples(self, N):
ut.set_using_dict(self.setNumberOfTransceiverSamples, N)
@property @property
@element @element
def dbitphase(self): def dbitphase(self):

View File

@ -1556,6 +1556,14 @@ void init_det(py::module &m) {
(void (Detector::*)(uint32_t, sls::Positions)) & (void (Detector::*)(uint32_t, sls::Positions)) &
Detector::setTenGigaADCEnableMask, Detector::setTenGigaADCEnableMask,
py::arg(), py::arg() = Positions{}); py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getTransceiverEnableMask",
(Result<uint32_t>(Detector::*)(sls::Positions) const) &
Detector::getTransceiverEnableMask,
py::arg() = Positions{});
CppDetectorApi.def("setTransceiverEnableMask",
(void (Detector::*)(uint32_t, sls::Positions)) &
Detector::setTransceiverEnableMask,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getNumberOfDigitalSamples", CppDetectorApi.def("getNumberOfDigitalSamples",
(Result<int>(Detector::*)(sls::Positions) const) & (Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfDigitalSamples, Detector::getNumberOfDigitalSamples,
@ -1564,6 +1572,14 @@ void init_det(py::module &m) {
(void (Detector::*)(int, sls::Positions)) & (void (Detector::*)(int, sls::Positions)) &
Detector::setNumberOfDigitalSamples, Detector::setNumberOfDigitalSamples,
py::arg(), py::arg() = Positions{}); py::arg(), py::arg() = Positions{});
CppDetectorApi.def("getNumberOfTransceiverSamples",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfTransceiverSamples,
py::arg() = Positions{});
CppDetectorApi.def("setNumberOfTransceiverSamples",
(void (Detector::*)(int, sls::Positions)) &
Detector::setNumberOfTransceiverSamples,
py::arg(), py::arg() = Positions{});
CppDetectorApi.def( CppDetectorApi.def(
"getReadoutMode", "getReadoutMode",
(Result<defs::readoutMode>(Detector::*)(sls::Positions) const) & (Result<defs::readoutMode>(Detector::*)(sls::Positions) const) &

View File

@ -242,6 +242,10 @@ void init_enums(py::module &m) {
.value("DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY) .value("DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY)
.value("ANALOG_AND_DIGITAL", .value("ANALOG_AND_DIGITAL",
slsDetectorDefs::readoutMode::ANALOG_AND_DIGITAL) slsDetectorDefs::readoutMode::ANALOG_AND_DIGITAL)
.value("TRANSCEIVER_ONLY",
slsDetectorDefs::readoutMode::TRANSCEIVER_ONLY)
.value("DIGITAL_AND_TRANSCEIVER",
slsDetectorDefs::readoutMode::DIGITAL_AND_TRANSCEIVER)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel") py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel")

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
// clang-format off
/* Definitions for FPGA */ /* Definitions for FPGA */
#define MEM_MAP_SHIFT 1 #define MEM_MAP_SHIFT 1
@ -96,7 +97,8 @@
#define FIFO_DATA_HRDWR_SRL_NMBR_MSK \ #define FIFO_DATA_HRDWR_SRL_NMBR_MSK \
(0x0000FFFF << FIFO_DATA_HRDWR_SRL_NMBR_OFST) (0x0000FFFF << FIFO_DATA_HRDWR_SRL_NMBR_OFST)
// #define FIFO_DATA_WRD_OFST (16) // #define FIFO_DATA_WRD_OFST (16)
//#define FIFO_DATA_WRD_MSK (0x0000FFFF << FIFO_DATA_WRD_OFST) // #define FIFO_DATA_WRD_MSK (0x0000FFFF <<
// FIFO_DATA_WRD_OFST)
/* FIFO Status RO register TODO */ /* FIFO Status RO register TODO */
#define FIFO_STATUS_REG (0x07 << MEM_MAP_SHIFT) #define FIFO_STATUS_REG (0x07 << MEM_MAP_SHIFT)
@ -184,14 +186,28 @@
#define POWER_STATUS_ALRT_OFST (27) #define POWER_STATUS_ALRT_OFST (27)
#define POWER_STATUS_ALRT_MSK (0x0000001F << POWER_STATUS_ALRT_OFST) #define POWER_STATUS_ALRT_MSK (0x0000001F << POWER_STATUS_ALRT_OFST)
/* FIFO Transceiver In Status RO register */
#define FIFO_TIN_STATUS_REG (0x30 << MEM_MAP_SHIFT)
#define FIFO_TIN_STATUS_FIFO_EMPTY_1_OFST (4)
#define FIFO_TIN_STATUS_FIFO_EMPTY_1_MSK (0x00000001 << FIFO_TIN_STATUS_FIFO_EMPTY_1_OFST)
#define FIFO_TIN_STATUS_FIFO_EMPTY_2_OFST (5)
#define FIFO_TIN_STATUS_FIFO_EMPTY_2_MSK (0x00000001 << FIFO_TIN_STATUS_FIFO_EMPTY_2_OFST)
#define FIFO_TIN_STATUS_FIFO_EMPTY_3_OFST (6)
#define FIFO_TIN_STATUS_FIFO_EMPTY_3_MSK (0x00000001 << FIFO_TIN_STATUS_FIFO_EMPTY_3_OFST)
#define FIFO_TIN_STATUS_FIFO_EMPTY_4_OFST (7)
#define FIFO_TIN_STATUS_FIFO_EMPTY_4_MSK (0x00000001 << FIFO_TIN_STATUS_FIFO_EMPTY_4_OFST)
#define FIFO_TIN_STATUS_FIFO_EMPTY_ALL_MSK (0x0000000F << FIFO_TIN_STATUS_FIFO_EMPTY_1_OFST)
/* FIFO Transceiver In 64 bit RO register */
#define FIFO_TIN_LSB_REG (0x31 << MEM_MAP_SHIFT)
#define FIFO_TIN_MSB_REG (0x32 << MEM_MAP_SHIFT)
/* FIFO Digital In Status RO register */ /* FIFO Digital In Status RO register */
#define FIFO_DIN_STATUS_REG (0x3B << MEM_MAP_SHIFT) #define FIFO_DIN_STATUS_REG (0x3B << MEM_MAP_SHIFT)
#define FIFO_DIN_STATUS_FIFO_FULL_OFST (30) #define FIFO_DIN_STATUS_FIFO_FULL_OFST (30)
#define FIFO_DIN_STATUS_FIFO_FULL_MSK \ #define FIFO_DIN_STATUS_FIFO_FULL_MSK (0x00000001 << FIFO_DIN_STATUS_FIFO_FULL_OFST)
(0x00000001 << FIFO_DIN_STATUS_FIFO_FULL_OFST)
#define FIFO_DIN_STATUS_FIFO_EMPTY_OFST (31) #define FIFO_DIN_STATUS_FIFO_EMPTY_OFST (31)
#define FIFO_DIN_STATUS_FIFO_EMPTY_MSK \ #define FIFO_DIN_STATUS_FIFO_EMPTY_MSK (0x00000001 << FIFO_DIN_STATUS_FIFO_EMPTY_OFST)
(0x00000001 << FIFO_DIN_STATUS_FIFO_EMPTY_OFST)
/* FIFO Digital In 64 bit RO register */ /* FIFO Digital In 64 bit RO register */
#define FIFO_DIN_LSB_REG (0x3C << MEM_MAP_SHIFT) #define FIFO_DIN_LSB_REG (0x3C << MEM_MAP_SHIFT)
@ -249,11 +265,13 @@
#define DUMMY_FIFO_CHNNL_SLCT_OFST (0) #define DUMMY_FIFO_CHNNL_SLCT_OFST (0)
#define DUMMY_FIFO_CHNNL_SLCT_MSK (0x0000003F << DUMMY_FIFO_CHNNL_SLCT_OFST) #define DUMMY_FIFO_CHNNL_SLCT_MSK (0x0000003F << DUMMY_FIFO_CHNNL_SLCT_OFST)
#define DUMMY_ANLG_FIFO_RD_STRBE_OFST (8) #define DUMMY_ANLG_FIFO_RD_STRBE_OFST (8)
#define DUMMY_ANLG_FIFO_RD_STRBE_MSK \ #define DUMMY_ANLG_FIFO_RD_STRBE_MSK (0x00000001 << DUMMY_ANLG_FIFO_RD_STRBE_OFST)
(0x00000001 << DUMMY_ANLG_FIFO_RD_STRBE_OFST)
#define DUMMY_DGTL_FIFO_RD_STRBE_OFST (9) #define DUMMY_DGTL_FIFO_RD_STRBE_OFST (9)
#define DUMMY_DGTL_FIFO_RD_STRBE_MSK \ #define DUMMY_DGTL_FIFO_RD_STRBE_MSK (0x00000001 << DUMMY_DGTL_FIFO_RD_STRBE_OFST)
(0x00000001 << DUMMY_DGTL_FIFO_RD_STRBE_OFST) #define DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_OFST (12)
#define DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_MSK (0x00000003 << DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_OFST)
#define DUMMY_TRNSCVR_FIFO_RD_STRBE_OFST (14)
#define DUMMY_TRNSCVR_FIFO_RD_STRBE_MSK (0x00000001 << DUMMY_TRNSCVR_FIFO_RD_STRBE_OFST)
/* Receiver IP Address RW register */ /* Receiver IP Address RW register */
#define RX_IP_REG (0x45 << MEM_MAP_SHIFT) #define RX_IP_REG (0x45 << MEM_MAP_SHIFT)
@ -302,6 +320,9 @@
#define CONFIG_DSBL_ANLG_OTPT_MSK (0x00000001 << CONFIG_DSBL_ANLG_OTPT_OFST) #define CONFIG_DSBL_ANLG_OTPT_MSK (0x00000001 << CONFIG_DSBL_ANLG_OTPT_OFST)
#define CONFIG_ENBLE_DGTL_OTPT_OFST (9) #define CONFIG_ENBLE_DGTL_OTPT_OFST (9)
#define CONFIG_ENBLE_DGTL_OTPT_MSK (0x00000001 << CONFIG_ENBLE_DGTL_OTPT_OFST) #define CONFIG_ENBLE_DGTL_OTPT_MSK (0x00000001 << CONFIG_ENBLE_DGTL_OTPT_OFST)
#define CONFIG_ENBLE_TRNSCVR_OTPT_OFST (10)
#define CONFIG_ENBLE_TRNSCVR_OTPT_MSK \
(0x00000001 << CONFIG_ENBLE_TRNSCVR_OTPT_OFST)
#define CONFIG_GB10_SND_UDP_OFST (12) #define CONFIG_GB10_SND_UDP_OFST (12)
#define CONFIG_GB10_SND_UDP_MSK (0x00000001 << CONFIG_GB10_SND_UDP_OFST) #define CONFIG_GB10_SND_UDP_MSK (0x00000001 << CONFIG_GB10_SND_UDP_OFST)
@ -333,8 +354,9 @@
#define CONTROL_STRT_EXPSR_MSK (0x00000001 << CONTROL_STRT_EXPSR_OFST) #define CONTROL_STRT_EXPSR_MSK (0x00000001 << CONTROL_STRT_EXPSR_OFST)
// #define CONTROL_STP_EXPSR_OFST (7) // #define CONTROL_STP_EXPSR_OFST (7)
// #define CONTROL_STP_EXPSR_MSK (0x00000001 << // #define CONTROL_STP_EXPSR_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST) #define CONTROL_STRT_TRN_OFST (8) #define // CONTROL_STP_RDT_OFST) #define CONTROL_STRT_TRN_OFST (8)
// CONTROL_STRT_TRN_MSK (0x00000001 << CONTROL_STRT_RDT_OFST) // #define CONTROL_STRT_TRN_MSK (0x00000001 <<
// CONTROL_STRT_RDT_OFST)
// #define CONTROL_STP_TRN_OFST (9) // #define CONTROL_STP_TRN_OFST (9)
// #define CONTROL_STP_TRN_MSK (0x00000001 << // #define CONTROL_STP_TRN_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST) // CONTROL_STP_RDT_OFST)
@ -457,8 +479,10 @@
#define POWER_HV_INTERNAL_SLCT_OFST (31) #define POWER_HV_INTERNAL_SLCT_OFST (31)
#define POWER_HV_INTERNAL_SLCT_MSK (0x00000001 << POWER_HV_INTERNAL_SLCT_OFST) #define POWER_HV_INTERNAL_SLCT_MSK (0x00000001 << POWER_HV_INTERNAL_SLCT_OFST)
/* Number of Words RW register TODO */ /* Number of samples from transceiver RW register */
#define NUMBER_OF_WORDS_REG (0x5F << MEM_MAP_SHIFT) #define SAMPLES_TRANSCEIVER_REG (0x5F << MEM_MAP_SHIFT)
#define SAMPLES_TRANSCEIVER_OFST (0)
#define SAMPLES_TRANSCEIVER_MSK (0x0000FFFF << SAMPLES_TRANSCEIVER_OFST)
/* Delay 64 bit RW register. t = DLY x 50 ns. */ /* Delay 64 bit RW register. t = DLY x 50 ns. */
#define DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT) #define DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT)
@ -482,7 +506,8 @@
// MEM_MAP_SHIFT) // Not used in FW // MEM_MAP_SHIFT) // Not used in FW
/* Gates 64 bit RW register */ /* Gates 64 bit RW register */
//#define GATES_LSB_REG (0x6A << MEM_MAP_SHIFT) // Not used // #define GATES_LSB_REG (0x6A << MEM_MAP_SHIFT) // Not
// used
// in FW #define GATES_MSB_REG (0x6B << MEM_MAP_SHIFT) // // in FW #define GATES_MSB_REG (0x6B << MEM_MAP_SHIFT) //
// Not used in FW // Not used in FW
@ -520,6 +545,9 @@
#define READOUT_10G_ENABLE_ANLG_MSK (0x000000FF << READOUT_10G_ENABLE_ANLG_OFST) #define READOUT_10G_ENABLE_ANLG_MSK (0x000000FF << READOUT_10G_ENABLE_ANLG_OFST)
#define READOUT_10G_ENABLE_DGTL_OFST (8) #define READOUT_10G_ENABLE_DGTL_OFST (8)
#define READOUT_10G_ENABLE_DGTL_MSK (0x00000001 << READOUT_10G_ENABLE_DGTL_OFST) #define READOUT_10G_ENABLE_DGTL_MSK (0x00000001 << READOUT_10G_ENABLE_DGTL_OFST)
#define READOUT_10G_ENABLE_TRNSCVR_OFST (9)
#define READOUT_10G_ENABLE_TRNSCVR_MSK \
(0x0000000F << READOUT_10G_ENABLE_TRNSCVR_OFST)
/* Digital Bit External Trigger RW register */ /* Digital Bit External Trigger RW register */
#define DBIT_EXT_TRG_REG (0x7B << MEM_MAP_SHIFT) #define DBIT_EXT_TRG_REG (0x7B << MEM_MAP_SHIFT)
@ -725,3 +753,5 @@
/* Round Robin */ /* Round Robin */
#define RXR_ENDPOINT_START_REG (0x1000 << MEM_MAP_SHIFT) #define RXR_ENDPOINT_START_REG (0x1000 << MEM_MAP_SHIFT)
// clang-format on

View File

@ -50,15 +50,18 @@ pthread_t pthread_virtual_tid;
int dataBytes = 0; int dataBytes = 0;
int analogDataBytes = 0; int analogDataBytes = 0;
int digitalDataBytes = 0; int digitalDataBytes = 0;
int transceiverDataBytes = 0;
char *analogData = 0; char *analogData = 0;
char *digitalData = 0; char *digitalData = 0;
char *transceiverData = 0;
char volatile *analogDataPtr = 0; char volatile *analogDataPtr = 0;
char volatile *digitalDataPtr = 0; char volatile *digitalDataPtr = 0;
char volatile *transceiverDataPtr = 0;
char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)]; char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)];
uint32_t adcEnableMask_1g = BIT32_MSK; uint32_t adcEnableMask_1g = BIT32_MSK;
// 10g readout // 10g readout
uint8_t adcEnableMask_10g = 0xFF; uint8_t adcEnableMask_10g = 0xFF;
uint32_t transceiverMask = DEFAULT_TRANSCEIVER_MASK;
int32_t clkPhase[NUM_CLOCKS] = {}; int32_t clkPhase[NUM_CLOCKS] = {};
uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200}; uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200};
@ -68,8 +71,10 @@ int vLimit = 0;
int highvoltage = 0; int highvoltage = 0;
int analogEnable = 1; int analogEnable = 1;
int digitalEnable = 0; int digitalEnable = 0;
int transceiverEnable = 0;
int naSamples = 1; int naSamples = 1;
int ndSamples = 1; int ndSamples = 1;
int ntSamples = 1;
int detPos[2] = {0, 0}; int detPos[2] = {0, 0};
int isInitCheckDone() { return initCheckDone; } int isInitCheckDone() { return initCheckDone; }
@ -468,6 +473,7 @@ void setupDetector() {
dataBytes = 0; dataBytes = 0;
analogDataBytes = 0; analogDataBytes = 0;
digitalDataBytes = 0; digitalDataBytes = 0;
transceiverDataBytes = 0;
if (analogData) { if (analogData) {
free(analogData); free(analogData);
analogData = 0; analogData = 0;
@ -476,8 +482,13 @@ void setupDetector() {
free(digitalData); free(digitalData);
digitalData = 0; digitalData = 0;
} }
if (transceiverData) {
free(transceiverData);
transceiverData = 0;
}
analogDataPtr = 0; analogDataPtr = 0;
digitalDataPtr = 0; digitalDataPtr = 0;
transceiverData = 0;
{ {
for (int i = 0; i < NUM_CLOCKS; ++i) { for (int i = 0; i < NUM_CLOCKS; ++i) {
clkPhase[i] = 0; clkPhase[i] = 0;
@ -493,10 +504,13 @@ void setupDetector() {
highvoltage = 0; highvoltage = 0;
adcEnableMask_1g = BIT32_MSK; adcEnableMask_1g = BIT32_MSK;
adcEnableMask_10g = 0xFF; adcEnableMask_10g = 0xFF;
transceiverMask = DEFAULT_TRANSCEIVER_MASK;
analogEnable = 1; analogEnable = 1;
digitalEnable = 0; digitalEnable = 0;
transceiverEnable = 0;
naSamples = 1; naSamples = 1;
ndSamples = 1; ndSamples = 1;
ntSamples = 1;
#ifdef VIRTUAL #ifdef VIRTUAL
sharedMemory_setStatus(IDLE); sharedMemory_setStatus(IDLE);
initializePatternWord(); initializePatternWord();
@ -575,6 +589,7 @@ void setupDetector() {
setNumAnalogSamples(DEFAULT_NUM_SAMPLES); setNumAnalogSamples(DEFAULT_NUM_SAMPLES);
setNumDigitalSamples( setNumDigitalSamples(
DEFAULT_NUM_SAMPLES); // update databytes and allocate ram DEFAULT_NUM_SAMPLES); // update databytes and allocate ram
setNumTransceiverSamples(DEFAULT_NUM_SAMPLES);
setNumFrames(DEFAULT_NUM_FRAMES); setNumFrames(DEFAULT_NUM_FRAMES);
setExpTime(DEFAULT_EXPTIME); setExpTime(DEFAULT_EXPTIME);
setNumTriggers(DEFAULT_NUM_CYCLES); setNumTriggers(DEFAULT_NUM_CYCLES);
@ -583,6 +598,8 @@ void setupDetector() {
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
setADCEnableMask(BIT32_MSK); setADCEnableMask(BIT32_MSK);
setADCEnableMask_10G(BIT32_MSK); setADCEnableMask_10G(BIT32_MSK);
setTransceiverEnableMask(DEFAULT_TRANSCEIVER_MASK);
if (setReadoutMode(ANALOG_ONLY) == FAIL) { if (setReadoutMode(ANALOG_ONLY) == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not set readout mode to analog only.\n"); "Could not set readout mode to analog only.\n");
@ -596,18 +613,22 @@ int updateDatabytesandAllocateRAM() {
int oldAnalogDataBytes = analogDataBytes; int oldAnalogDataBytes = analogDataBytes;
int oldDigitalDataBytes = digitalDataBytes; int oldDigitalDataBytes = digitalDataBytes;
int oldTranceiverDataBytes = transceiverDataBytes;
updateDataBytes(); updateDataBytes();
// update only if change in databytes // update only if change in databytes
if (analogDataBytes == oldAnalogDataBytes && if (analogDataBytes == oldAnalogDataBytes &&
digitalDataBytes == oldDigitalDataBytes) { digitalDataBytes == oldDigitalDataBytes &&
LOG(logDEBUG1, ("RAM size (Analog:%d, Digital:%d) already allocated. " transceiverDataBytes == oldTranceiverDataBytes) {
"Nothing to be done.\n", LOG(logDEBUG1,
analogDataBytes, digitalDataBytes)); ("RAM size (Analog:%d, Digital:%d, Transceiver:%d) already "
"allocated. Nothing to be done.\n",
analogDataBytes, digitalDataBytes, transceiverDataBytes));
return OK; return OK;
} }
// Zero databytes // Zero databytes
if (analogDataBytes == 0 && digitalDataBytes == 0) { if (analogDataBytes == 0 && digitalDataBytes == 0 &&
transceiverDataBytes == 0) {
LOG(logERROR, ("Can not allocate RAM for 0 bytes.\n")); LOG(logERROR, ("Can not allocate RAM for 0 bytes.\n"));
return FAIL; return FAIL;
} }
@ -620,6 +641,10 @@ int updateDatabytesandAllocateRAM() {
free(digitalData); free(digitalData);
digitalData = 0; digitalData = 0;
} }
if (transceiverData) {
free(transceiverData);
transceiverData = 0;
}
// allocate RAM // allocate RAM
if (analogDataBytes) { if (analogDataBytes) {
analogData = malloc(analogDataBytes); analogData = malloc(analogDataBytes);
@ -640,16 +665,29 @@ int updateDatabytesandAllocateRAM() {
"Probable cause: Memory Leak.\n")); "Probable cause: Memory Leak.\n"));
return FAIL; return FAIL;
} }
LOG(logINFO,
("\tDigital RAM allocated to %d bytes\n", digitalDataBytes));
}
if (transceiverDataBytes) {
transceiverData = malloc(transceiverDataBytes);
// cannot malloc
if (transceiverData == NULL) {
LOG(logERROR,
("Can not allocate transceiver data RAM for even 1 frame. "
"Probable cause: Memory Leak.\n"));
return FAIL;
}
LOG(logINFO, ("\tTransceiver RAM allocated to %d bytes\n",
transceiverDataBytes));
} }
LOG(logINFO, ("\tDigital RAM allocated to %d bytes\n", digitalDataBytes));
return OK; return OK;
} }
void updateDataBytes() { void updateDataBytes() {
int nachans = 0, ndchans = 0; int nachans = 0, ndchans = 0, ntchans = 0;
analogDataBytes = 0; analogDataBytes = 0;
digitalDataBytes = 0; digitalDataBytes = 0;
transceiverDataBytes = 0;
// analog // analog
if (analogEnable) { if (analogEnable) {
@ -672,10 +710,20 @@ void updateDataBytes() {
LOG(logINFO, ("\t#Digital Channels:%d, Databytes:%d\n", ndchans, LOG(logINFO, ("\t#Digital Channels:%d, Databytes:%d\n", ndchans,
digitalDataBytes)); digitalDataBytes));
} }
// transceiver
if (transceiverEnable) {
for (int ichan = 0; ichan < NCHAN_TRANSCEIVER; ++ichan) {
if (transceiverMask & (1 << ichan))
++ntchans;
}
transceiverDataBytes =
ntchans * (NBITS_PER_TRANSCEIVER / 8) * ntSamples;
LOG(logINFO, ("\t#Transceiver Channels:%d, Databytes:%d\n", ntchans,
transceiverDataBytes));
}
// total // total
int nchans = nachans + ndchans; int nchans = nachans + ndchans + ntchans;
dataBytes = analogDataBytes + digitalDataBytes; dataBytes = analogDataBytes + digitalDataBytes + transceiverDataBytes;
LOG(logINFO, LOG(logINFO,
("\t#Total Channels:%d, Total Databytes:%d\n", nchans, dataBytes)); ("\t#Total Channels:%d, Total Databytes:%d\n", nchans, dataBytes));
@ -723,10 +771,6 @@ int getDynamicRange(int *retval) {
} }
int setADCEnableMask(uint32_t mask) { int setADCEnableMask(uint32_t mask) {
if (mask == 0u) {
LOG(logERROR, ("Cannot set 1gb adc mask to 0\n"));
return FAIL;
}
LOG(logINFO, ("Setting adcEnableMask 1G to 0x%08x\n", mask)); LOG(logINFO, ("Setting adcEnableMask 1G to 0x%08x\n", mask));
adcEnableMask_1g = mask; adcEnableMask_1g = mask;
// 1Gb enabled // 1Gb enabled
@ -792,6 +836,20 @@ uint32_t getADCEnableMask_10G() {
return retval; return retval;
} }
int setTransceiverEnableMask(uint32_t mask) {
LOG(logINFO, ("Setting transceivermask to 0x%08x\n", mask));
transceiverMask = mask;
// 1Gb enabled
if (!enableTenGigabitEthernet(-1)) {
if (updateDatabytesandAllocateRAM() == FAIL) {
return FAIL;
}
}
return OK;
}
uint32_t getTransceiverEnableMask() { return transceiverMask; }
void setADCInvertRegister(uint32_t val) { void setADCInvertRegister(uint32_t val) {
LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val)); LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val));
bus_w(ADC_PORT_INVERT_REG, val); bus_w(ADC_PORT_INVERT_REG, val);
@ -829,6 +887,7 @@ int setExternalSampling(int val) {
int setReadoutMode(enum readoutMode mode) { int setReadoutMode(enum readoutMode mode) {
analogEnable = 0; analogEnable = 0;
digitalEnable = 0; digitalEnable = 0;
transceiverEnable = 0;
switch (mode) { switch (mode) {
case ANALOG_ONLY: case ANALOG_ONLY:
LOG(logINFO, ("Setting Analog Only Readout\n")); LOG(logINFO, ("Setting Analog Only Readout\n"));
@ -843,6 +902,15 @@ int setReadoutMode(enum readoutMode mode) {
analogEnable = 1; analogEnable = 1;
digitalEnable = 1; digitalEnable = 1;
break; break;
case TRANSCEIVER_ONLY:
LOG(logINFO, ("Setting Transceiver Only Readout\n"));
transceiverEnable = 1;
break;
case DIGITAL_AND_TRANSCEIVER:
LOG(logINFO, ("Setting Digital & Transceiver Readout\n"));
digitalEnable = 1;
transceiverEnable = 1;
break;
default: default:
LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", mode)); LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", mode));
return FAIL; return FAIL;
@ -850,30 +918,35 @@ int setReadoutMode(enum readoutMode mode) {
uint32_t addr = CONFIG_REG; uint32_t addr = CONFIG_REG;
uint32_t addr_readout_10g = READOUT_10G_ENABLE_REG; uint32_t addr_readout_10g = READOUT_10G_ENABLE_REG;
// default: analog only
bus_w(addr, bus_r(addr) & (~CONFIG_DSBL_ANLG_OTPT_MSK) & bus_w(addr, (bus_r(addr) | CONFIG_DSBL_ANLG_OTPT_MSK) &
(~CONFIG_ENBLE_DGTL_OTPT_MSK)); (~CONFIG_ENBLE_DGTL_OTPT_MSK) &
(~CONFIG_ENBLE_TRNSCVR_OTPT_MSK));
bus_w(addr_readout_10g, bus_r(addr_readout_10g) & bus_w(addr_readout_10g, bus_r(addr_readout_10g) &
(~READOUT_10G_ENABLE_ANLG_MSK) & (~READOUT_10G_ENABLE_ANLG_MSK) &
~(READOUT_10G_ENABLE_DGTL_MSK)); ~(READOUT_10G_ENABLE_DGTL_MSK) &
~(READOUT_10G_ENABLE_TRNSCVR_MSK));
if (analogEnable) {
bus_w(addr, bus_r(addr) & ~(CONFIG_DSBL_ANLG_OTPT_MSK));
bus_w(addr_readout_10g, bus_w(addr_readout_10g,
bus_r(addr_readout_10g) | bus_r(addr_readout_10g) |
((adcEnableMask_10g << READOUT_10G_ENABLE_ANLG_OFST) & ((adcEnableMask_10g << READOUT_10G_ENABLE_ANLG_OFST) &
READOUT_10G_ENABLE_ANLG_MSK)); READOUT_10G_ENABLE_ANLG_MSK));
// disable analog (digital only)
if (!analogEnable) {
bus_w(addr, bus_r(addr) | CONFIG_DSBL_ANLG_OTPT_MSK);
bus_w(addr_readout_10g,
bus_r(addr_readout_10g) & (~READOUT_10G_ENABLE_ANLG_MSK));
} }
// enable digital (analog and digital)
if (digitalEnable) { if (digitalEnable) {
bus_w(addr, bus_r(addr) | CONFIG_ENBLE_DGTL_OTPT_MSK); bus_w(addr, bus_r(addr) | CONFIG_ENBLE_DGTL_OTPT_MSK);
bus_w(addr_readout_10g, bus_w(addr_readout_10g,
bus_r(addr_readout_10g) | READOUT_10G_ENABLE_DGTL_MSK); bus_r(addr_readout_10g) | READOUT_10G_ENABLE_DGTL_MSK);
} }
if (transceiverEnable) {
bus_w(addr, bus_r(addr) | CONFIG_ENBLE_TRNSCVR_OTPT_MSK);
bus_w(addr_readout_10g,
bus_r(addr_readout_10g) |
((transceiverMask << READOUT_10G_ENABLE_TRNSCVR_OFST) &
READOUT_10G_ENABLE_TRNSCVR_MSK));
}
if (isControlServer) {
// 1Gb // 1Gb
if (!enableTenGigabitEthernet(-1)) { if (!enableTenGigabitEthernet(-1)) {
if (updateDatabytesandAllocateRAM() == FAIL) { if (updateDatabytesandAllocateRAM() == FAIL) {
@ -888,28 +961,47 @@ int setReadoutMode(enum readoutMode mode) {
adcEnableMask_10g != ((bus_r(READOUT_10G_ENABLE_REG) & adcEnableMask_10g != ((bus_r(READOUT_10G_ENABLE_REG) &
READOUT_10G_ENABLE_ANLG_MSK) >> READOUT_10G_ENABLE_ANLG_MSK) >>
READOUT_10G_ENABLE_ANLG_OFST)) { READOUT_10G_ENABLE_ANLG_OFST)) {
LOG(logERROR, ("Setting readout mode failed. Could not set 10g adc " LOG(logERROR,
("Setting readout mode failed. Could not set 10g adc "
"enable mask to 0x%x\n.", "enable mask to 0x%x\n.",
adcEnableMask_10g)); adcEnableMask_10g));
return FAIL; return FAIL;
} }
// validate transceivermask for 10g
if (transceiverEnable &&
transceiverMask != ((bus_r(READOUT_10G_ENABLE_REG) &
READOUT_10G_ENABLE_TRNSCVR_MSK) >>
READOUT_10G_ENABLE_TRNSCVR_OFST)) {
LOG(logERROR, ("Setting readout mode failed. Could not set 10g "
"transceiver enable mask to 0x%x\n.",
transceiverMask));
return FAIL;
}
}
} }
return OK; return OK;
} }
int getReadoutMode() { int getReadoutMode() {
if (analogEnable && digitalEnable) { if (analogEnable && digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Analog & Digita\n")); LOG(logDEBUG1, ("Getting readout: Analog & Digita\n"));
return ANALOG_AND_DIGITAL; return ANALOG_AND_DIGITAL;
} else if (analogEnable && !digitalEnable) { } else if (analogEnable && !digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Analog Only\n")); LOG(logDEBUG1, ("Getting readout: Analog Only\n"));
return ANALOG_ONLY; return ANALOG_ONLY;
} else if (!analogEnable && digitalEnable) { } else if (!analogEnable && digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Digital Only\n")); LOG(logDEBUG1, ("Getting readout: Digital Only\n"));
return DIGITAL_ONLY; return DIGITAL_ONLY;
} else if (!analogEnable && !digitalEnable && transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Transceiver Only\n"));
return TRANSCEIVER_ONLY;
} else if (!analogEnable && digitalEnable && transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Digital & Transceiver\n"));
return DIGITAL_AND_TRANSCEIVER;
} else { } else {
LOG(logERROR, LOG(logERROR, ("Read unknown readout (analog enable:%d digital "
("Read unknown readout (Both digital and analog are disabled)\n")); "enable:%d transceiver enable:%d)\n",
analogEnable, digitalEnable, transceiverEnable));
return -1; return -1;
} }
} }
@ -994,6 +1086,28 @@ int setNumDigitalSamples(int val) {
int getNumDigitalSamples() { return ndSamples; } int getNumDigitalSamples() { return ndSamples; }
int setNumTransceiverSamples(int val) {
if (val < 0) {
LOG(logERROR, ("Invalid transceiver samples: %d\n", val));
return FAIL;
}
LOG(logINFO, ("Setting number of transceiver samples %d\n", val));
ntSamples = val;
uint32_t addr = SAMPLES_TRANSCEIVER_REG;
bus_w(addr, bus_r(addr) & ~SAMPLES_TRANSCEIVER_MSK);
bus_w(addr, bus_r(addr) | ((val << SAMPLES_TRANSCEIVER_OFST) &
SAMPLES_TRANSCEIVER_MSK));
// 1Gb
if (!enableTenGigabitEthernet(-1)) {
if (updateDatabytesandAllocateRAM() == FAIL) {
return FAIL;
}
}
return OK;
}
int getNumTransceiverSamples() { return ntSamples; }
int setExpTime(int64_t val) { int setExpTime(int64_t val) {
if (val < 0) { if (val < 0) {
LOG(logERROR, ("Invalid exptime: %lld ns\n", (long long int)val)); LOG(logERROR, ("Invalid exptime: %lld ns\n", (long long int)val));
@ -2098,6 +2212,7 @@ int startStateMachine() {
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
return OK; return OK;
#endif #endif
int send_to_10g = enableTenGigabitEthernet(-1); int send_to_10g = enableTenGigabitEthernet(-1);
// 1 giga udp // 1 giga udp
if (send_to_10g == 0) { if (send_to_10g == 0) {
@ -2124,6 +2239,38 @@ int startStateMachine() {
~CONTROL_STRT_EXPSR_MSK); ~CONTROL_STRT_EXPSR_MSK);
LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG))); LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
// TODO: Temporary Matternhorn Specific ( will be moved to the pattern )
if (transceiverEnable) {
uint32_t addr = 0x202 << MEM_MAP_SHIFT;
bus_w(addr, bus_r(addr) | (1 << 1));
LOG(logINFOBLUE, ("Writing 1 to reg 0x202\n"))
usleep(1);
cleanFifos();
usleep(1);
}
return OK;
}
int startReadOut() {
LOG(logINFOBLUE, ("Starting Readout\n"));
#ifdef VIRTUAL
return startStateMachine();
#endif
int send_to_10g = enableTenGigabitEthernet(-1);
// 1 giga udp
if (send_to_10g == 0) {
// create udp socket
if (createUDPSocket(0) != OK) {
return FAIL;
}
// update header with modId, detType and version. Reset offset and fnum
createUDPPacketHeader(udpPacketData, getHardwareSerialNumber());
}
cleanFifos();
usleep(1);
return OK; return OK;
} }
@ -2188,6 +2335,7 @@ void *start_timer(void *arg) {
srcOffset += dataSize; srcOffset += dataSize;
sendUDPPacket(0, 0, packetData, packetSize); sendUDPPacket(0, 0, packetData, packetSize);
// LOG(logINFOBLUE, ("packetsize:%d\n", packetSize));
} }
LOG(logINFO, ("Sent frame: %d [%lld]\n", iframes, frameNr + iframes)); LOG(logINFO, ("Sent frame: %d [%lld]\n", iframes, frameNr + iframes));
clock_gettime(CLOCK_REALTIME, &end); clock_gettime(CLOCK_REALTIME, &end);
@ -2236,6 +2384,7 @@ int stopStateMachine() {
} }
enum runStatus getRunStatus() { enum runStatus getRunStatus() {
LOG(logDEBUG1, ("Getting status\n")); LOG(logDEBUG1, ("Getting status\n"));
// scan error or running // scan error or running
if (sharedMemory_getScanStatus() == ERROR) { if (sharedMemory_getScanStatus() == ERROR) {
@ -2291,6 +2440,7 @@ enum runStatus getRunStatus() {
// 1g might still be transmitting or reading from fifo (not virtual) // 1g might still be transmitting or reading from fifo (not virtual)
if (!enableTenGigabitEthernet(-1) && checkDataInFifo()) { if (!enableTenGigabitEthernet(-1) && checkDataInFifo()) {
LOG(logINFOBLUE, ("Status: Transmitting (Data in Fifo)\n"));
return TRANSMITTING; return TRANSMITTING;
} }
@ -2345,25 +2495,20 @@ void waitForAcquisitionEnd() {
void unsetFifoReadStrobes() { void unsetFifoReadStrobes() {
bus_w(DUMMY_REG, bus_r(DUMMY_REG) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK) & bus_w(DUMMY_REG, bus_r(DUMMY_REG) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK) &
(~DUMMY_DGTL_FIFO_RD_STRBE_MSK)); (~DUMMY_DGTL_FIFO_RD_STRBE_MSK) &
(~DUMMY_TRNSCVR_FIFO_RD_STRBE_MSK));
} }
void readSample(int ns) { int readSample(int ns) {
int sampleRead = 0;
uint32_t addr = DUMMY_REG; uint32_t addr = DUMMY_REG;
LOG(logDEBUG1, ("sample :%d\n", ns));
// read adcs // read adcs
if (analogEnable && ns < naSamples) { if (analogEnable && ns < naSamples) {
uint32_t fifoAddr = FIFO_DATA_REG; uint32_t fifoAddr = FIFO_DATA_REG;
// read strobe to all analog fifos
bus_w(addr, bus_r(addr) | DUMMY_ANLG_FIFO_RD_STRBE_MSK);
bus_w(addr, bus_r(addr) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK));
// wait for 1 us to latch different clocks of read and read strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
;
if (!(ns % 1000)) { if (!(ns % 1000)) {
LOG(logDEBUG1, ("Reading sample ns:%d of %d AEmtpy:0x%x AFull:0x%x " LOG(logDEBUG1, ("Reading sample ns:%d of %d AEmtpy:0x%x AFull:0x%x "
"Status:0x%x\n", "Status:0x%x\n",
@ -2384,6 +2529,11 @@ void readSample(int ns) {
bus_w(addr, bus_r(addr) | ((ich << DUMMY_FIFO_CHNNL_SLCT_OFST) & bus_w(addr, bus_r(addr) | ((ich << DUMMY_FIFO_CHNNL_SLCT_OFST) &
DUMMY_FIFO_CHNNL_SLCT_MSK)); DUMMY_FIFO_CHNNL_SLCT_MSK));
// wait for 1 us to latch different clocks of read and read
// strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
;
// read fifo and write it to current position of data pointer // read fifo and write it to current position of data pointer
*((uint16_t *)analogDataPtr) = bus_r16(fifoAddr); *((uint16_t *)analogDataPtr) = bus_r16(fifoAddr);
@ -2395,21 +2545,22 @@ void readSample(int ns) {
// increment pointer to data out destination // increment pointer to data out destination
analogDataPtr += 2; analogDataPtr += 2;
} sampleRead = 1;
} }
} }
// read digital output // read strobe to all analog fifos
if (digitalEnable && ns < ndSamples) { bus_w(addr, bus_r(addr) | DUMMY_ANLG_FIFO_RD_STRBE_MSK);
// read strobe to digital fifo bus_w(addr, bus_r(addr) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK));
bus_w(addr, bus_r(addr) | DUMMY_DGTL_FIFO_RD_STRBE_MSK);
bus_w(addr, bus_r(addr) & (~DUMMY_DGTL_FIFO_RD_STRBE_MSK));
// wait for 1 us to latch different clocks of read and read strobe // wait for 1 us to latch different clocks of read and read strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i) for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
; ;
}
// read digital output
if (digitalEnable && ns < ndSamples) {
// wait as it is connected directly to fifo running on a different clock
if (!(ns % 1000)) { if (!(ns % 1000)) {
LOG(logDEBUG1, LOG(logDEBUG1,
("Reading sample ns:%d of %d DEmtpy:%d DFull:%d Status:0x%x\n", ("Reading sample ns:%d of %d DEmtpy:%d DFull:%d Status:0x%x\n",
@ -2427,37 +2578,127 @@ void readSample(int ns) {
*((uint64_t *)digitalDataPtr) = *((uint64_t *)digitalDataPtr) =
get64BitReg(FIFO_DIN_LSB_REG, FIFO_DIN_MSB_REG); get64BitReg(FIFO_DIN_LSB_REG, FIFO_DIN_MSB_REG);
digitalDataPtr += 8; digitalDataPtr += 8;
sampleRead = 1;
// read strobe to digital fifo
bus_w(addr, bus_r(addr) | DUMMY_DGTL_FIFO_RD_STRBE_MSK);
bus_w(addr, bus_r(addr) & (~DUMMY_DGTL_FIFO_RD_STRBE_MSK));
// wait for 1 us to latch different clocks of read and read strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
;
} }
// read transceivers
if (transceiverEnable && ns < ntSamples) {
uint32_t tStatusAddr = FIFO_TIN_STATUS_REG;
if (!(ns % 1000)) {
LOG(logDEBUG1,
("Reading sample ns:%d of %d TReg:0x%x Status:0x%x\n", ns,
ntSamples, bus_r(tStatusAddr), bus_r(STATUS_REG)));
}
// loop through all channels
for (int ich = 0; ich < NCHAN_TRANSCEIVER; ++ich) {
// if channel is in enable mask
if ((1 << ich) & (transceiverMask)) {
int offset = FIFO_TIN_STATUS_FIFO_EMPTY_1_OFST + ich;
uint32_t mask = (1 << offset);
// int empty = ((bus_r(tStatusAddr) & mask) >> offset);
// if fifo not empty
// if (!empty) {
LOG(logDEBUG1,
("ns:%d Transceiver Fifo %d NOT Empty\n", ns, ich));
// unselect channel
bus_w(addr, bus_r(addr) & ~(DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_MSK));
// select channel
bus_w(addr, bus_r(addr) |
((ich << DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_OFST) &
DUMMY_TRNSCVR_FIFO_CHNNL_SLCT_MSK));
// wait for 1 us to latch different clocks of read and read
// strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
;
// read fifo and write it to current position of data
// pointer
*((uint64_t *)transceiverDataPtr) =
get64BitReg(FIFO_TIN_LSB_REG, FIFO_TIN_MSB_REG);
transceiverDataPtr += 8;
sampleRead = 1;
//}
}
}
// read strobe
bus_w(addr, bus_r(addr) | DUMMY_TRNSCVR_FIFO_RD_STRBE_MSK);
usleep(5 * 1000);
bus_w(addr, bus_r(addr) & (~DUMMY_TRNSCVR_FIFO_RD_STRBE_MSK));
// wait for 1 us to latch different clocks of read and read
// strobe
for (int i = 0; i < WAIT_TIME_1US_FOR_LOOP_CNT; ++i)
;
}
LOG(logDEBUG1, ("sample read:%d\n", sampleRead));
return sampleRead;
} }
uint32_t checkDataInFifo() { uint32_t checkDataInFifo() {
uint32_t dataPresent = 0; uint32_t dataPresent = 0;
if (analogEnable) { if (analogEnable) {
uint32_t analogFifoEmpty = bus_r(FIFO_EMPTY_REG); uint32_t fifoEmtpy = bus_r(FIFO_EMPTY_REG);
LOG(logDEBUG1, LOG(logDEBUG1,
("Analog Fifo Empty (32 channels): 0x%08x\n", analogFifoEmpty)); ("Analog Fifo Empty (32 channels): 0x%08x\n", fifoEmtpy));
dataPresent = (~analogFifoEmpty); dataPresent = (~fifoEmtpy);
} }
if (!dataPresent && digitalEnable) { if (!dataPresent && digitalEnable) {
int digitalFifoEmpty = int fifoEmtpy =
((bus_r(FIFO_DIN_STATUS_REG) & FIFO_DIN_STATUS_FIFO_EMPTY_MSK) >> ((bus_r(FIFO_DIN_STATUS_REG) & FIFO_DIN_STATUS_FIFO_EMPTY_MSK) >>
FIFO_DIN_STATUS_FIFO_EMPTY_OFST); FIFO_DIN_STATUS_FIFO_EMPTY_OFST);
LOG(logINFO, ("Digital Fifo Empty: %d\n", digitalFifoEmpty)); LOG(logDEBUG1, ("Digital Fifo Empty: %d\n", fifoEmtpy));
dataPresent = (digitalFifoEmpty ? 0 : 1); dataPresent = (fifoEmtpy ? 0 : 1);
} }
LOG(logDEBUG2, ("Data in Fifo :0x%x\n", dataPresent)); if (!dataPresent && transceiverEnable) {
int fifoEmtpy = 1;
for (int ich = 0; ich != 4; ++ich) {
if ((1 << ich) & (transceiverMask)) {
uint32_t mask = FIFO_TIN_STATUS_FIFO_EMPTY_1_MSK << ich;
int offset = FIFO_TIN_STATUS_FIFO_EMPTY_1_OFST + ich;
int iFifoEmpty =
((bus_r(FIFO_TIN_STATUS_REG) & mask) >> offset);
if (iFifoEmpty == 0) {
fifoEmtpy = 0;
}
}
}
LOG(logDEBUG1, ("Transceiver Fifo Empty: %d reg:0x%x\n", fifoEmtpy,
bus_r(FIFO_TIN_STATUS_REG)));
dataPresent = (fifoEmtpy ? 0 : 1);
}
LOG(logDEBUG1, ("Data in Fifo :0x%x\n", dataPresent));
return dataPresent; return dataPresent;
} }
// only called for starting of a new frame // only called for starting of a new frame
int checkFifoForEndOfAcquisition() { int checkFifoForEndOfAcquisition() {
LOG(logDEBUG1, ("Check for end of acq\n"));
uint32_t dataPresent = checkDataInFifo(); uint32_t dataPresent = checkDataInFifo();
LOG(logDEBUG2, ("status:0x%x\n", bus_r(STATUS_REG))); LOG(logDEBUG1, ("dataPresent:%d\n", dataPresent));
// as long as no data // as long as no data
while (!dataPresent) { while (!dataPresent) {
// acquisition done // acquisition done
if (!runBusy()) { if (!runBusy()) {
LOG(logDEBUG1, ("Not running\n"));
// wait to be sure there is no data in fifo // wait to be sure there is no data in fifo
usleep(WAIT_TME_US_FR_ACQDONE_REG); usleep(WAIT_TME_US_FR_ACQDONE_REG);
@ -2484,18 +2725,35 @@ int readFrameFromFifo() {
int ns = 0; int ns = 0;
// point the data pointer to the starting position of data // point the data pointer to the starting position of data
analogDataPtr = analogData; analogDataPtr = analogData;
memset(analogData, 0, analogDataBytes);
digitalDataPtr = digitalData; digitalDataPtr = digitalData;
memset(digitalData, 0, digitalDataBytes);
transceiverDataPtr = transceiverData;
memset(transceiverData, 0, transceiverDataBytes);
// no data for this frame // no data for this frame
/*if (!checkDataInFifo()) {
return FAIL;
}*/
// for startacquistiion
if (checkFifoForEndOfAcquisition() == FAIL) { if (checkFifoForEndOfAcquisition() == FAIL) {
return FAIL; return FAIL;
} }
// read Sample // read Sample
int maxSamples = (naSamples > ndSamples) ? naSamples : ndSamples; int maxSamples = 0;
if (analogEnable && naSamples > maxSamples)
maxSamples = naSamples;
if (digitalEnable && ndSamples > maxSamples)
maxSamples = ndSamples;
if (transceiverEnable && ntSamples > maxSamples)
maxSamples = ntSamples;
while (ns < maxSamples) { while (ns < maxSamples) {
// chceck if no data in fifo, return ns?//FIXME: ask Anna // chceck if no data in fifo, return ns?//FIXME: ask Anna
readSample(ns); if (!readSample(ns)) {
LOG(logWARNING, ("No more samples to read\n"));
return OK;
}
ns++; ns++;
} }
@ -2523,8 +2781,7 @@ int getTotalNumberOfChannels() {
} }
void getNumberOfChannels(int *nchanx, int *nchany) { void getNumberOfChannels(int *nchanx, int *nchany) {
int nachans = 0, ndchans = 0; int nachans = 0, ndchans = 0, ntchans = 0;
// analog channels (normal, analog/digital readout)
if (analogEnable) { if (analogEnable) {
uint32_t mask = uint32_t mask =
enableTenGigabitEthernet(-1) ? adcEnableMask_10g : adcEnableMask_1g; enableTenGigabitEthernet(-1) ? adcEnableMask_10g : adcEnableMask_1g;
@ -2539,12 +2796,19 @@ void getNumberOfChannels(int *nchanx, int *nchany) {
LOG(logDEBUG1, ("Analog Channels: %d\n", nachans)); LOG(logDEBUG1, ("Analog Channels: %d\n", nachans));
} }
// digital channels (digital, analog/digital readout)
if (digitalEnable) { if (digitalEnable) {
ndchans = 64; ndchans = 64;
LOG(logDEBUG, ("Digital Channels: %d\n", ndchans)); LOG(logDEBUG, ("Digital Channels: %d\n", ndchans));
} }
*nchanx = nachans + ndchans; if (transceiverEnable) {
for (int ich = 0; ich < NCHAN_TRANSCEIVER; ++ich) {
if ((transceiverMask & (1 << ich)) != 0U)
++ntchans;
}
LOG(logDEBUG1, ("Transceiver Channels: %d\n", ntchans));
}
*nchanx = nachans + ndchans + ntchans;
LOG(logDEBUG, ("Total #Channels: %d\n", *nchanx)); LOG(logDEBUG, ("Total #Channels: %d\n", *nchanx));
*nchany = 1; *nchany = 1;
} }

View File

@ -5,7 +5,7 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define MIN_REQRD_VRSN_T_RD_API 0x181130 #define MIN_REQRD_VRSN_T_RD_API 0x181130
#define REQRD_FRMWR_VRSN 0x230403 #define REQRD_FRMWR_VRSN 0x230705
#define NUM_HARDWARE_VERSIONS (1) #define NUM_HARDWARE_VERSIONS (1)
#define HARDWARE_VERSION_NUMBERS \ #define HARDWARE_VERSION_NUMBERS \
@ -18,9 +18,11 @@
#define CTRL_SRVR_INIT_TIME_US (2 * 1000 * 1000) #define CTRL_SRVR_INIT_TIME_US (2 * 1000 * 1000)
/* Hardware Definitions */ /* Hardware Definitions */
#define NCHAN (36) #define NCHAN (40)
#define NCHAN_ANALOG (32) #define NCHAN_ANALOG (32)
#define NCHAN_DIGITAL (64) #define NCHAN_DIGITAL (64)
#define NCHAN_TRANSCEIVER (4)
#define NBITS_PER_TRANSCEIVER (64)
#define NCHIP (1) #define NCHIP (1)
#define NDAC (24) #define NDAC (24)
#define NPWR (6) #define NPWR (6)
@ -52,6 +54,8 @@
#define DEFAULT_ADC_CLK (40) // 20 #define DEFAULT_ADC_CLK (40) // 20
#define DEFAULT_SYNC_CLK (40) // 20 #define DEFAULT_SYNC_CLK (40) // 20
#define DEFAULT_DBIT_CLK (200) #define DEFAULT_DBIT_CLK (200)
#define DEFAULT_TRANSCEIVER_MASK (0x3)
#define MAX_TRANSCEIVER_MASK (0xF)
#define UDP_HEADER_MAX_FRAME_VALUE (0xFFFFFFFFFFFF) #define UDP_HEADER_MAX_FRAME_VALUE (0xFFFFFFFFFFFF)

View File

@ -206,6 +206,8 @@ int setADCEnableMask(uint32_t mask);
uint32_t getADCEnableMask(); uint32_t getADCEnableMask();
void setADCEnableMask_10G(uint32_t mask); void setADCEnableMask_10G(uint32_t mask);
uint32_t getADCEnableMask_10G(); uint32_t getADCEnableMask_10G();
int setTransceiverEnableMask(uint32_t mask);
uint32_t getTransceiverEnableMask();
void setADCInvertRegister(uint32_t val); void setADCInvertRegister(uint32_t val);
uint32_t getADCInvertRegister(); uint32_t getADCInvertRegister();
#endif #endif
@ -287,6 +289,8 @@ int getNumAnalogSamples();
#ifdef CHIPTESTBOARDD #ifdef CHIPTESTBOARDD
int setNumDigitalSamples(int val); int setNumDigitalSamples(int val);
int getNumDigitalSamples(); int getNumDigitalSamples();
int setNumTransceiverSamples(int val);
int getNumTransceiverSamples();
#endif #endif
#ifdef MYTHEN3D #ifdef MYTHEN3D
void setCounterMask(uint32_t arg); void setCounterMask(uint32_t arg);
@ -677,7 +681,7 @@ int softwareTrigger();
#if defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD) #if defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD)
int softwareTrigger(int block); int softwareTrigger(int block);
#endif #endif
#if defined(EIGERD) || defined(MYTHEN3D) #if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD)
int startReadOut(); int startReadOut();
#endif #endif
enum runStatus getRunStatus(); enum runStatus getRunStatus();
@ -690,7 +694,7 @@ void waitForAcquisitionEnd();
int validateUDPSocket(); int validateUDPSocket();
void readandSendUDPFrames(); void readandSendUDPFrames();
void unsetFifoReadStrobes(); void unsetFifoReadStrobes();
void readSample(int ns); int readSample(int ns);
uint32_t checkDataInFifo(); uint32_t checkDataInFifo();
int checkFifoForEndOfAcquisition(); int checkFifoForEndOfAcquisition();
int readFrameFromFifo(); int readFrameFromFifo();

View File

@ -315,3 +315,7 @@ int get_frontend_firmware_version(int);
int get_bit(int); int get_bit(int);
int set_bit(int); int set_bit(int);
int clear_bit(int); int clear_bit(int);
int get_num_transceiver_samples(int);
int set_num_transceiver_samples(int);
int get_transceiver_enable(int);
int set_transceiver_enable(int);

View File

@ -21,11 +21,14 @@ extern const enum detectorType myDetectorType;
extern int analogDataBytes; extern int analogDataBytes;
extern int digitalDataBytes; extern int digitalDataBytes;
extern int transceiverDataBytes;
extern char *analogData; extern char *analogData;
extern char *digitalData; extern char *digitalData;
extern char *transceiverData;
int analogOffset = 0; int analogOffset = 0;
int digitalOffset = 0; int digitalOffset = 0;
int transceiverOffset = 0;
uint32_t udpPacketNumber = 0; uint32_t udpPacketNumber = 0;
uint64_t udpFrameNumber = 0; uint64_t udpFrameNumber = 0;
@ -51,27 +54,30 @@ void createUDPPacketHeader(char *buffer, uint16_t id) {
// reset offset // reset offset
analogOffset = 0; analogOffset = 0;
digitalOffset = 0; digitalOffset = 0;
transceiverOffset = 0;
// reset frame number // reset frame number
udpFrameNumber = 0; udpFrameNumber = 0;
} }
int fillUDPPacket(char *buffer) { int fillUDPPacket(char *buffer) {
LOG(logDEBUG2, LOG(logDEBUG2, ("Analog (databytes:%d, offset:%d)\n Digital (databytes:%d "
("Analog (databytes:%d, offset:%d)\n Digital (databytes:%d " "offset:%d)\n\n Transceiver (databytes:%d offset:%d)\n",
"offset:%d)\n", analogDataBytes, analogOffset, digitalDataBytes,
analogDataBytes, analogOffset, digitalDataBytes, digitalOffset)); digitalOffset, transceiverDataBytes, transceiverOffset));
// reached end of data for one frame // reached end of data for one frame
if (analogOffset >= analogDataBytes && digitalOffset >= digitalDataBytes) { if (analogOffset >= analogDataBytes && digitalOffset >= digitalDataBytes &&
transceiverOffset >= transceiverDataBytes) {
// reset offset // reset offset
analogOffset = 0; analogOffset = 0;
digitalOffset = 0; digitalOffset = 0;
transceiverOffset = 0;
return 0; return 0;
} }
sls_detector_header *header = (sls_detector_header *)(buffer); sls_detector_header *header = (sls_detector_header *)(buffer);
// update frame number, starts at 1 (reset packet number) // update frame number, starts at 1 (reset packet number)
if (analogOffset == 0 && digitalOffset == 0) { if (analogOffset == 0 && digitalOffset == 0 && transceiverOffset == 0) {
++udpFrameNumber; ++udpFrameNumber;
header->frameNumber = udpFrameNumber; header->frameNumber = udpFrameNumber;
udpPacketNumber = -1; udpPacketNumber = -1;
@ -117,10 +123,28 @@ int fillUDPPacket(char *buffer) {
freeBytes -= digitalBytes; freeBytes -= digitalBytes;
} }
// transceiver data
int transceiverBytes = 0;
if (freeBytes && transceiverOffset < transceiverDataBytes) {
// bytes to copy
transceiverBytes =
((transceiverOffset + freeBytes) <= transceiverDataBytes)
? freeBytes
: (transceiverDataBytes - transceiverOffset);
// copy
memcpy(buffer + sizeof(sls_detector_header) + analogBytes +
digitalBytes,
transceiverData + transceiverOffset, transceiverBytes);
// increment offset
transceiverOffset += transceiverBytes;
// decrement free bytes
freeBytes -= transceiverBytes;
}
// pad data // pad data
if (freeBytes) { if (freeBytes) {
memset(buffer + sizeof(sls_detector_header) + analogBytes + memset(buffer + sizeof(sls_detector_header) + analogBytes +
digitalBytes, digitalBytes + transceiverBytes,
0, freeBytes); 0, freeBytes);
LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", freeBytes, LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", freeBytes,
(long long int)udpFrameNumber, udpPacketNumber)); (long long int)udpFrameNumber, udpPacketNumber));

View File

@ -478,7 +478,10 @@ void function_table() {
flist[F_GET_BIT] = &get_bit; flist[F_GET_BIT] = &get_bit;
flist[F_SET_BIT] = &set_bit; flist[F_SET_BIT] = &set_bit;
flist[F_CLEAR_BIT] = &clear_bit; flist[F_CLEAR_BIT] = &clear_bit;
flist[F_GET_NUM_TRANSCEIVER_SAMPLES] = &get_num_transceiver_samples;
flist[F_SET_NUM_TRANSCEIVER_SAMPLES] = &set_num_transceiver_samples;
flist[F_GET_TRANSCEIVER_ENABLE_MASK] = &get_transceiver_enable;
flist[F_SET_TRANSCEIVER_ENABLE_MASK] = &set_transceiver_enable;
// check // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
LOG(logERROR, ("The last detector function enum has reached its " LOG(logERROR, ("The last detector function enum has reached its "
@ -1876,7 +1879,8 @@ int acquire(int blocking, int file_des) {
getNumAnalogSamples()); getNumAnalogSamples());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else if ((getReadoutMode() == ANALOG_AND_DIGITAL || } else if ((getReadoutMode() == ANALOG_AND_DIGITAL ||
getReadoutMode() == DIGITAL_ONLY) && getReadoutMode() == DIGITAL_ONLY ||
getReadoutMode() == DIGITAL_AND_TRANSCEIVER) &&
(getNumDigitalSamples() <= 0)) { (getNumDigitalSamples() <= 0)) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
@ -1884,6 +1888,16 @@ int acquire(int blocking, int file_des) {
"samples: %d.\n", "samples: %d.\n",
getNumDigitalSamples()); getNumDigitalSamples());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else if ((getReadoutMode() == TRANSCEIVER_ONLY ||
getReadoutMode() == DIGITAL_AND_TRANSCEIVER) &&
(getNumTransceiverSamples() <= 0)) {
ret = FAIL;
sprintf(
mess,
"Could not start acquisition. Invalid number of transceiver "
"samples: %d.\n",
getNumTransceiverSamples());
LOG(logERROR, (mess));
} else } else
#endif #endif
#ifdef EIGERD #ifdef EIGERD
@ -4275,23 +4289,15 @@ int set_adc_enable_mask(int file_des) {
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
if (arg == 0u) {
ret = FAIL;
sprintf(mess,
"Not allowed to set adc mask of 0 due to data readout. \n");
LOG(logERROR, (mess));
} else {
ret = setADCEnableMask(arg); ret = setADCEnableMask(arg);
if (ret == FAIL) { if (ret == FAIL) {
sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n", sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n", arg);
arg);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
uint32_t retval = getADCEnableMask(); uint32_t retval = getADCEnableMask();
if (arg != retval) { if (arg != retval) {
ret = FAIL; ret = FAIL;
sprintf( sprintf(mess,
mess,
"Could not set 1Gb ADC Enable mask. Set 0x%x, but read " "Could not set 1Gb ADC Enable mask. Set 0x%x, but read "
"0x%x\n", "0x%x\n",
arg, retval); arg, retval);
@ -4299,7 +4305,6 @@ int set_adc_enable_mask(int file_des) {
} }
} }
} }
}
#endif #endif
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
} }
@ -5662,6 +5667,8 @@ int set_readout_mode(int file_des) {
case ANALOG_ONLY: case ANALOG_ONLY:
case DIGITAL_ONLY: case DIGITAL_ONLY:
case ANALOG_AND_DIGITAL: case ANALOG_AND_DIGITAL:
case TRANSCEIVER_ONLY:
case DIGITAL_AND_TRANSCEIVER:
break; break;
default: default:
modeNotImplemented("Readout mode", (int)arg); modeNotImplemented("Readout mode", (int)arg);
@ -5946,7 +5953,7 @@ int get_clock_phase(int file_des) {
if (receiveData(file_des, args, sizeof(args), INT32) < 0) if (receiveData(file_des, args, sizeof(args), INT32) < 0)
return printSocketReadError(); return printSocketReadError();
LOG(logINFOBLUE, ("Getting clock (%d) phase %s \n", args[0], LOG(logDEBUG1, ("Getting clock (%d) phase %s \n", args[0],
(args[1] == 0 ? "" : "in degrees"))); (args[1] == 0 ? "" : "in degrees")));
#if !defined(CHIPTESTBOARDD) && !defined(JUNGFRAUD) && !defined(MOENCHD) && \ #if !defined(CHIPTESTBOARDD) && !defined(JUNGFRAUD) && !defined(MOENCHD) && \
@ -5972,7 +5979,7 @@ int get_clock_phase(int file_des) {
#if defined(GOTTHARD2D) || defined(MYTHEN3D) #if defined(GOTTHARD2D) || defined(MYTHEN3D)
if (ind < NUM_CLOCKS) { if (ind < NUM_CLOCKS) {
c = (enum CLKINDEX)ind; c = (enum CLKINDEX)ind;
LOG(logINFOBLUE, ("NUMclocks:%d c:%d\n", NUM_CLOCKS, c)); LOG(logDEBUG1, ("NUMclocks:%d c:%d\n", NUM_CLOCKS, c));
break; break;
} }
#endif #endif
@ -7384,6 +7391,26 @@ int get_receiver_parameters(int file_des) {
if (n < 0) if (n < 0)
return printSocketReadError(); return printSocketReadError();
n += sendData(file_des, &i64, sizeof(i64), INT64); n += sendData(file_des, &i64, sizeof(i64), INT64);
if (n < 0)
return printSocketReadError();
// transceiver samples
#ifdef CHIPTESTBOARDD
i32 = getNumTransceiverSamples();
#else
i32 = 0;
#endif
n += sendData(file_des, &i32, sizeof(i32), INT32);
if (n < 0)
return printSocketReadError();
// transceiver mask
#if defined(CHIPTESTBOARDD)
u32 = getTransceiverEnableMask();
#else
u32 = 0;
#endif
n += sendData(file_des, &u32, sizeof(u32), INT32);
if (n < 0) if (n < 0)
return printSocketReadError(); return printSocketReadError();
@ -8210,7 +8237,7 @@ int get_bursts_left(int file_des) {
int start_readout(int file_des) { int start_readout(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
#ifndef MYTHEN3D #if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD)
functionNotImplemented(); functionNotImplemented();
#else #else
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
@ -8241,6 +8268,25 @@ int start_readout(int file_des) {
#endif #endif
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} }
// only 1g real ctb needs to read from fifo
// to avoid blocking, in another thread
#if defined(CHIPTESTBOARDD) && !defined(VIRTUAL)
if (!enableTenGigabitEthernet(-1)) {
ret = validateUDPSocket();
if (ret == FAIL) {
strcpy(mess, "UDP socket not created!\n");
LOG(logERROR, (mess));
} else {
if (pthread_create(&pthread_tid_ctb_1g, NULL,
&start_reading_and_sending_udp_frames,
NULL)) {
ret = FAIL;
strcpy(mess, "Could not start read frames thread!\n");
LOG(logERROR, (mess));
}
}
}
#endif
} }
} }
#endif #endif
@ -10401,12 +10447,9 @@ int get_bit(int file_des) {
int nBit = (int)args[1]; int nBit = (int)args[1];
LOG(logDEBUG1, ("Getting bit %d of reg 0x%x\n", nBit, addr)); LOG(logDEBUG1, ("Getting bit %d of reg 0x%x\n", nBit, addr));
// only set
if (Server_VerifyLock() == OK) {
if (nBit < 0 || nBit > 31) { if (nBit < 0 || nBit > 31) {
ret = FAIL; ret = FAIL;
sprintf( sprintf(mess,
mess,
"Could not get bit. Bit nr %d out of range. Must be 0-31\n", "Could not get bit. Bit nr %d out of range. Must be 0-31\n",
nBit); nBit);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@ -10415,20 +10458,127 @@ int get_bit(int file_des) {
ret = getBit(addr, nBit, &retval); ret = getBit(addr, nBit, &retval);
LOG(logDEBUG1, ("retval: %d\n", retval)); LOG(logDEBUG1, ("retval: %d\n", retval));
if (ret == FAIL) { if (ret == FAIL) {
sprintf(mess, "Could not get bit %d.\n", nBit);
LOG(logERROR, (mess));
}
#else #else
#ifdef GOTTHARDD #ifdef GOTTHARDD
retval = readRegister16And32(addr); uint32_t regval = readRegister16And32(addr);
#else #else
retval = readRegister(addr); uint32_t regval = readRegister(addr);
#endif #endif
LOG(logDEBUG1, ("retval: %d\n", retval)); retval = (regval & (1 << nBit)) >> nBit;
if (retval & (1 << nBit)) { LOG(logDEBUG1, ("regval: 0x%x bit value:0%d\n", regval, retval));
#endif
}
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int get_num_transceiver_samples(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
#if !defined(CHIPTESTBOARDD)
functionNotImplemented();
#else
// get only
retval = getNumTransceiverSamples();
LOG(logDEBUG1, ("retval num transceiver samples %d\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_num_transceiver_samples(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Setting number of transceiver samples %d\n", arg));
#if !defined(CHIPTESTBOARDD)
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
ret = setNumTransceiverSamples(arg);
if (ret == FAIL) {
sprintf(
mess,
"Could not set number of transceiver samples to %d. Could not "
"allocate RAM\n",
arg);
LOG(logERROR, (mess));
} else {
int retval = getNumTransceiverSamples();
LOG(logDEBUG1, ("retval num transceiver samples %d\n", retval));
validate(&ret, mess, arg, retval,
"set number of transceiver samples", DEC);
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int set_transceiver_enable(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
uint32_t arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Setting Transceiver Enable Mask to %u\n", arg));
#if (!defined(CHIPTESTBOARDD))
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
if (arg > MAX_TRANSCEIVER_MASK) {
ret = FAIL; ret = FAIL;
#endif sprintf(mess, "Invalid Transceiver Mask. Max: 0x%x\n",
sprintf(mess, "Could not get bit %d.\n", nBit); MAX_TRANSCEIVER_MASK);
LOG(logERROR, (mess));
} else {
ret = setTransceiverEnableMask(arg);
if (ret == FAIL) {
sprintf(mess,
"Could not set Transceiver Enable mask to 0x%x.\n",
arg);
LOG(logERROR, (mess));
} else {
uint32_t retval = getTransceiverEnableMask();
if (arg != retval) {
ret = FAIL;
sprintf(mess,
"Could not set Transceiver Enable mask. Set 0x%x, "
"but read "
"0x%x\n",
arg, retval);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} }
} }
} }
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_transceiver_enable(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
uint32_t retval = -1;
LOG(logDEBUG1, ("Getting Transceiver Enable Mask \n"));
#if (!defined(CHIPTESTBOARDD))
functionNotImplemented();
#else
// get
retval = getTransceiverEnableMask();
LOG(logDEBUG1, ("Transceiver Enable Mask retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }

View File

@ -1647,6 +1647,13 @@ class Detector {
/** [CTB] If any of a consecutive 4 bits are enabled, the " /** [CTB] If any of a consecutive 4 bits are enabled, the "
"complete 4 bits are enabled */ "complete 4 bits are enabled */
void setTenGigaADCEnableMask(uint32_t mask, Positions pos = {}); void setTenGigaADCEnableMask(uint32_t mask, Positions pos = {});
/** [CTB] */
Result<uint32_t> getTransceiverEnableMask(Positions pos = {}) const;
/** [CTB] */
void setTransceiverEnableMask(uint32_t mask, Positions pos = {});
///@} ///@}
/** @name CTB Specific */ /** @name CTB Specific */
@ -1663,10 +1670,17 @@ class Detector {
/** [CTB] */ /** [CTB] */
void setNumberOfDigitalSamples(int value, Positions pos = {}); void setNumberOfDigitalSamples(int value, Positions pos = {});
/** [CTB] */
Result<int> getNumberOfTransceiverSamples(Positions pos = {}) const;
/** [CTB] */
void setNumberOfTransceiverSamples(int value, Positions pos = {});
/** [CTB] */ /** [CTB] */
Result<defs::readoutMode> getReadoutMode(Positions pos = {}) const; Result<defs::readoutMode> getReadoutMode(Positions pos = {}) const;
/** [CTB] Options: ANALOG_ONLY (default), DIGITAL_ONLY, ANALOG_AND_DIGITAL /** [CTB] Options: ANALOG_ONLY (default), DIGITAL_ONLY, ANALOG_AND_DIGITAL,
* TRANSCEIVER_ONLY, DIGITAL_AND_TRANSCEIVER
*/ */
void setReadoutMode(defs::readoutMode value, Positions pos = {}); void setReadoutMode(defs::readoutMode value, Positions pos = {});

View File

@ -2576,8 +2576,8 @@ std::string CmdProxy::Samples(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[n_samples]\n\t[CTB] Number of samples (both analog and " os << "[n_samples]\n\t[CTB] Number of samples (analog, digitial and "
"digitial) expected.\n" "transceiver) expected.\n"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (!args.empty()) { if (!args.empty()) {
@ -2587,11 +2587,15 @@ std::string CmdProxy::Samples(int action) {
// get also digital samples for ctb and compare with analog // get also digital samples for ctb and compare with analog
if (det->getDetectorType().squash() == defs::CHIPTESTBOARD) { if (det->getDetectorType().squash() == defs::CHIPTESTBOARD) {
auto d = det->getNumberOfDigitalSamples(std::vector<int>{det_id}); auto d = det->getNumberOfDigitalSamples(std::vector<int>{det_id});
auto t =
det->getNumberOfTransceiverSamples(std::vector<int>{det_id});
int as = a.squash(-1); int as = a.squash(-1);
int ds = d.squash(-1); int ds = d.squash(-1);
if (as == -1 || ds == -1 || as != ds) { // check if a == d? int ts = t.squash(-1);
if (as == -1 || ds == -1 || ts == -1 || as != ds ||
as != ts) { // check if a == d?
throw RuntimeError( throw RuntimeError(
"Different samples. Use asamples or dsamples."); "Different samples. Use asamples, dsamples or tsamples.");
} }
} }
os << OutString(a) << '\n'; os << OutString(a) << '\n';
@ -2605,6 +2609,8 @@ std::string CmdProxy::Samples(int action) {
if (det->getDetectorType().squash() == defs::CHIPTESTBOARD) { if (det->getDetectorType().squash() == defs::CHIPTESTBOARD) {
det->setNumberOfDigitalSamples(StringTo<int>(args[0]), det->setNumberOfDigitalSamples(StringTo<int>(args[0]),
std::vector<int>{det_id}); std::vector<int>{det_id});
det->setNumberOfTransceiverSamples(StringTo<int>(args[0]),
std::vector<int>{det_id});
} }
os << args.front() << '\n'; os << args.front() << '\n';
} else { } else {

View File

@ -1225,7 +1225,7 @@ class CmdProxy {
{"apulse", &CmdProxy::apulse}, {"apulse", &CmdProxy::apulse},
{"dpulse", &CmdProxy::dpulse}, {"dpulse", &CmdProxy::dpulse},
/* CTB/ Moench Specific */ /* CTB Specific */
{"samples", &CmdProxy::Samples}, {"samples", &CmdProxy::Samples},
{"asamples", &CmdProxy::asamples}, {"asamples", &CmdProxy::asamples},
{"adcclk", &CmdProxy::adcclk}, {"adcclk", &CmdProxy::adcclk},
@ -1235,9 +1235,9 @@ class CmdProxy {
{"v_limit", &CmdProxy::v_limit}, {"v_limit", &CmdProxy::v_limit},
{"adcenable", &CmdProxy::adcenable}, {"adcenable", &CmdProxy::adcenable},
{"adcenable10g", &CmdProxy::adcenable10g}, {"adcenable10g", &CmdProxy::adcenable10g},
{"transceiverenable", &CmdProxy::transceiverenable},
/* CTB Specific */
{"dsamples", &CmdProxy::dsamples}, {"dsamples", &CmdProxy::dsamples},
{"tsamples", &CmdProxy::tsamples},
{"romode", &CmdProxy::romode}, {"romode", &CmdProxy::romode},
{"dbitclk", &CmdProxy::dbitclk}, {"dbitclk", &CmdProxy::dbitclk},
{"adcvpp", &CmdProxy::AdcVpp}, {"adcvpp", &CmdProxy::AdcVpp},
@ -2435,18 +2435,26 @@ class CmdProxy {
"ADC channel. However, if any of a consecutive 4 bits are enabled, " "ADC channel. However, if any of a consecutive 4 bits are enabled, "
"the complete 4 bits are enabled."); "the complete 4 bits are enabled.");
/* CTB Specific */ INTEGER_COMMAND_HEX(transceiverenable, getTransceiverEnableMask,
setTransceiverEnableMask, StringTo<uint32_t>,
"[bitmask]\n\t[Ctb] Transceiver Enable Mask. Enable "
"for each 4 Transceiver channel.");
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
dsamples, getNumberOfDigitalSamples, setNumberOfDigitalSamples, dsamples, getNumberOfDigitalSamples, setNumberOfDigitalSamples,
StringTo<int>, StringTo<int>,
"[n_value]\n\t[CTB] Number of digital samples expected."); "[n_value]\n\t[CTB] Number of digital samples expected.");
INTEGER_COMMAND_VEC_ID(
tsamples, getNumberOfTransceiverSamples, setNumberOfTransceiverSamples,
StringTo<int>,
"[n_value]\n\t[CTB] Number of transceiver samples expected.");
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
romode, getReadoutMode, setReadoutMode, romode, getReadoutMode, setReadoutMode,
StringTo<slsDetectorDefs::readoutMode>, StringTo<slsDetectorDefs::readoutMode>,
"[analog|digital|analog_digital]\n\t[CTB] Readout mode. " "[analog|digital|analog_digital|transceiver|digital_transceiver]\n\t["
"Default is analog."); "CTB] Readout mode. Default is analog.");
INTEGER_COMMAND_VEC_ID(dbitclk, getDBITClock, setDBITClock, StringTo<int>, INTEGER_COMMAND_VEC_ID(dbitclk, getDBITClock, setDBITClock, StringTo<int>,
"[n_clk in MHz]\n\t[Ctb] Clock for latching the " "[n_clk in MHz]\n\t[Ctb] Clock for latching the "

View File

@ -2114,6 +2114,13 @@ void Detector::setTenGigaADCEnableMask(uint32_t mask, Positions pos) {
pimpl->Parallel(&Module::setTenGigaADCEnableMask, pos, mask); pimpl->Parallel(&Module::setTenGigaADCEnableMask, pos, mask);
} }
Result<uint32_t> Detector::getTransceiverEnableMask(Positions pos) const {
return pimpl->Parallel(&Module::getTransceiverEnableMask, pos);
}
void Detector::setTransceiverEnableMask(uint32_t mask, Positions pos) {
pimpl->Parallel(&Module::setTransceiverEnableMask, pos, mask);
}
// CTB Specific // CTB Specific
Result<int> Detector::getNumberOfDigitalSamples(Positions pos) const { Result<int> Detector::getNumberOfDigitalSamples(Positions pos) const {
@ -2124,12 +2131,18 @@ void Detector::setNumberOfDigitalSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfDigitalSamples, pos, value); pimpl->Parallel(&Module::setNumberOfDigitalSamples, pos, value);
} }
Result<int> Detector::getNumberOfTransceiverSamples(Positions pos) const {
return pimpl->Parallel(&Module::getNumberOfTransceiverSamples, pos);
}
void Detector::setNumberOfTransceiverSamples(int value, Positions pos) {
pimpl->Parallel(&Module::setNumberOfTransceiverSamples, pos, value);
}
Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const { Result<defs::readoutMode> Detector::getReadoutMode(Positions pos) const {
return pimpl->Parallel(&Module::getReadoutMode, pos); return pimpl->Parallel(&Module::getReadoutMode, pos);
} }
/** Options: ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL \n
* Default: ANALOG_ONLY */
void Detector::setReadoutMode(defs::readoutMode value, Positions pos) { void Detector::setReadoutMode(defs::readoutMode value, Positions pos) {
pimpl->Parallel(&Module::setReadoutMode, pos, value); pimpl->Parallel(&Module::setReadoutMode, pos, value);
} }

View File

@ -2387,6 +2387,19 @@ void Module::setTenGigaADCEnableMask(uint32_t mask) {
} }
} }
uint32_t Module::getTransceiverEnableMask() const {
return sendToDetector<uint32_t>(F_GET_TRANSCEIVER_ENABLE_MASK);
}
void Module::setTransceiverEnableMask(uint32_t mask) {
sendToDetector(F_SET_TRANSCEIVER_ENABLE_MASK, mask, nullptr);
// update #nchan, as it depends on #samples, adcmask,
updateNumberOfChannels();
if (shm()->useReceiverFlag) {
sendToReceiver<int>(F_RECEIVER_SET_TRANSCEIVER_MASK, mask);
}
}
// CTB Specific // CTB Specific
int Module::getNumberOfDigitalSamples() const { int Module::getNumberOfDigitalSamples() const {
@ -2401,6 +2414,18 @@ void Module::setNumberOfDigitalSamples(int value) {
} }
} }
int Module::getNumberOfTransceiverSamples() const {
return sendToDetector<int>(F_GET_NUM_TRANSCEIVER_SAMPLES);
}
void Module::setNumberOfTransceiverSamples(int value) {
sendToDetector(F_SET_NUM_TRANSCEIVER_SAMPLES, value, nullptr);
updateNumberOfChannels(); // depends on samples and adcmask
if (shm()->useReceiverFlag) {
sendToReceiver(F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES, value, nullptr);
}
}
slsDetectorDefs::readoutMode Module::getReadoutMode() const { slsDetectorDefs::readoutMode Module::getReadoutMode() const {
return sendToDetector<readoutMode>(F_GET_READOUT_MODE); return sendToDetector<readoutMode>(F_GET_READOUT_MODE);
} }
@ -2408,6 +2433,7 @@ slsDetectorDefs::readoutMode Module::getReadoutMode() const {
void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) { void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
auto arg = static_cast<uint32_t>(mode); // TODO! unit? auto arg = static_cast<uint32_t>(mode); // TODO! unit?
sendToDetector(F_SET_READOUT_MODE, arg, nullptr); sendToDetector(F_SET_READOUT_MODE, arg, nullptr);
sendToDetectorStop(F_SET_READOUT_MODE, arg, nullptr);
// update #nchan, as it depends on #samples, adcmask, // update #nchan, as it depends on #samples, adcmask,
if (shm()->detType == CHIPTESTBOARD) { if (shm()->detType == CHIPTESTBOARD) {
updateNumberOfChannels(); updateNumberOfChannels();

View File

@ -504,8 +504,12 @@ class Module : public virtual slsDetectorDefs {
void setADCEnableMask(uint32_t mask); void setADCEnableMask(uint32_t mask);
uint32_t getTenGigaADCEnableMask() const; uint32_t getTenGigaADCEnableMask() const;
void setTenGigaADCEnableMask(uint32_t mask); void setTenGigaADCEnableMask(uint32_t mask);
uint32_t getTransceiverEnableMask() const;
void setTransceiverEnableMask(uint32_t mask);
int getNumberOfDigitalSamples() const; int getNumberOfDigitalSamples() const;
void setNumberOfDigitalSamples(int value); void setNumberOfDigitalSamples(int value);
int getNumberOfTransceiverSamples() const;
void setNumberOfTransceiverSamples(int value);
readoutMode getReadoutMode() const; readoutMode getReadoutMode() const;
void setReadoutMode(const readoutMode mode); void setReadoutMode(const readoutMode mode);
int getExternalSamplingSource(); int getExternalSamplingSource();

View File

@ -860,6 +860,36 @@ TEST_CASE("adcenable10g", "[.cmd]") {
} }
} }
TEST_CASE("transceiverenable", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) {
auto prev_val = det.getTransceiverEnableMask();
{
std::ostringstream oss;
proxy.Call("transceiverenable", {"0x3"}, -1, PUT, oss);
REQUIRE(oss.str() == "transceiverenable 0x3\n");
}
{
std::ostringstream oss;
proxy.Call("transceiverenable", {"0xf"}, -1, PUT, oss);
REQUIRE(oss.str() == "transceiverenable 0xf\n");
}
{
std::ostringstream oss;
proxy.Call("transceiverenable", {}, -1, GET, oss);
REQUIRE(oss.str() == "transceiverenable 0xf\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setTransceiverEnableMask(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("transceiverenable", {}, -1, GET));
}
}
/* CTB Specific */ /* CTB Specific */
TEST_CASE("dsamples", "[.cmd]") { TEST_CASE("dsamples", "[.cmd]") {
@ -892,6 +922,36 @@ TEST_CASE("dsamples", "[.cmd]") {
} }
} }
TEST_CASE("tsamples", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) {
auto prev_val = det.getNumberOfTransceiverSamples();
{
std::ostringstream oss;
proxy.Call("tsamples", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "tsamples 1\n");
}
{
std::ostringstream oss;
proxy.Call("tsamples", {"450"}, -1, PUT, oss);
REQUIRE(oss.str() == "tsamples 450\n");
}
{
std::ostringstream oss;
proxy.Call("tsamples", {}, -1, GET, oss);
REQUIRE(oss.str() == "tsamples 450\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setNumberOfTransceiverSamples(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("tsamples", {}, -1, GET));
}
}
TEST_CASE("romode", "[.cmd]") { TEST_CASE("romode", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
@ -900,8 +960,10 @@ TEST_CASE("romode", "[.cmd]") {
auto prev_romode = det.getReadoutMode(); auto prev_romode = det.getReadoutMode();
auto prev_asamples = det.getNumberOfAnalogSamples(); auto prev_asamples = det.getNumberOfAnalogSamples();
auto prev_dsamples = det.getNumberOfDigitalSamples(); auto prev_dsamples = det.getNumberOfDigitalSamples();
auto prev_tsamples = det.getNumberOfTransceiverSamples();
det.setNumberOfAnalogSamples(5000); det.setNumberOfAnalogSamples(5000);
det.setNumberOfDigitalSamples(5000); det.setNumberOfDigitalSamples(5000);
det.setNumberOfTransceiverSamples(5000);
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("romode", {"digital"}, -1, PUT, oss); proxy.Call("romode", {"digital"}, -1, PUT, oss);
@ -922,10 +984,21 @@ TEST_CASE("romode", "[.cmd]") {
proxy.Call("romode", {}, -1, GET, oss); proxy.Call("romode", {}, -1, GET, oss);
REQUIRE(oss.str() == "romode analog\n"); REQUIRE(oss.str() == "romode analog\n");
} }
{
std::ostringstream oss;
proxy.Call("romode", {"transceiver"}, -1, PUT, oss);
REQUIRE(oss.str() == "romode transceiver\n");
}
{
std::ostringstream oss;
proxy.Call("romode", {"digital_transceiver"}, -1, PUT, oss);
REQUIRE(oss.str() == "romode digital_transceiver\n");
}
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setReadoutMode(prev_romode[i], {i}); det.setReadoutMode(prev_romode[i], {i});
det.setNumberOfAnalogSamples(prev_asamples[i], {i}); det.setNumberOfAnalogSamples(prev_asamples[i], {i});
det.setNumberOfDigitalSamples(prev_dsamples[i], {i}); det.setNumberOfDigitalSamples(prev_dsamples[i], {i});
det.setNumberOfTransceiverSamples(prev_tsamples[i], {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("romode", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("romode", {}, -1, GET));

View File

@ -220,6 +220,8 @@ int ClientInterface::functionTable(){
flist[F_RECEIVER_GET_RECEIVER_ROI] = &ClientInterface::get_receiver_roi; flist[F_RECEIVER_GET_RECEIVER_ROI] = &ClientInterface::get_receiver_roi;
flist[F_RECEIVER_SET_RECEIVER_ROI] = &ClientInterface::set_receiver_roi; flist[F_RECEIVER_SET_RECEIVER_ROI] = &ClientInterface::set_receiver_roi;
flist[F_RECEIVER_SET_RECEIVER_ROI_METADATA] = &ClientInterface::set_receiver_roi_metadata; flist[F_RECEIVER_SET_RECEIVER_ROI_METADATA] = &ClientInterface::set_receiver_roi_metadata;
flist[F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES] = &ClientInterface::set_num_transceiver_samples;
flist[F_RECEIVER_SET_TRANSCEIVER_MASK] = &ClientInterface::set_transceiver_mask;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" << LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -370,9 +372,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (detType == CHIPTESTBOARD) { if (detType == CHIPTESTBOARD) {
impl()->setNumberofAnalogSamples(arg.analogSamples); impl()->setNumberofAnalogSamples(arg.analogSamples);
}
if (detType == CHIPTESTBOARD) {
impl()->setNumberofDigitalSamples(arg.digitalSamples); impl()->setNumberofDigitalSamples(arg.digitalSamples);
impl()->setNumberofTransceiverSamples(arg.transceiverSamples);
} }
if (detType != MYTHEN3) { if (detType != MYTHEN3) {
impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs)); impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs));
@ -410,6 +411,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setReadoutMode(arg.roMode); impl()->setReadoutMode(arg.roMode);
impl()->setADCEnableMask(arg.adcMask); impl()->setADCEnableMask(arg.adcMask);
impl()->setTenGigaADCEnableMask(arg.adc10gMask); impl()->setTenGigaADCEnableMask(arg.adc10gMask);
impl()->setTransceiverEnableMask(arg.transceiverMask);
} }
if (detType == GOTTHARD) { if (detType == GOTTHARD) {
impl()->setDetectorROI(arg.roi); impl()->setDetectorROI(arg.roi);
@ -1758,4 +1760,43 @@ int ClientInterface::set_receiver_roi_metadata(Interface &socket) {
return socket.Send(OK); return socket.Send(OK);
} }
int ClientInterface::set_num_transceiver_samples(Interface &socket) {
auto value = socket.Receive<int>();
LOG(logDEBUG1) << "Setting num transceiver samples to " << value;
if (detType != CHIPTESTBOARD) {
functionNotImplemented();
}
try {
impl()->setNumberofTransceiverSamples(value);
} catch (const std::exception &e) {
throw RuntimeError("Could not set number of transceiver samples to " +
std::to_string(value) + " [" +
std::string(e.what()) + ']');
}
return socket.Send(OK);
}
int ClientInterface::set_transceiver_mask(Interface &socket) {
auto arg = socket.Receive<uint32_t>();
verifyIdle(socket);
LOG(logDEBUG1) << "Setting Transceiver enable mask: " << arg;
try {
impl()->setTransceiverEnableMask(arg);
} catch (const std::exception &e) {
throw RuntimeError("Could not set transceiver enable mask [" +
std::string(e.what()) + ']');
}
auto retval = impl()->getTransceiverEnableMask();
if (retval != arg) {
std::ostringstream os;
os << "Could not set Transceiver enable mask. Set 0x" << std::hex << arg
<< " but read 0x" << std::hex << retval;
throw RuntimeError(os.str());
}
LOG(logDEBUG1) << "Transceiver enable mask retval: " << retval;
return socket.sendResult(retval);
}
} // namespace sls } // namespace sls

View File

@ -170,6 +170,8 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_receiver_roi(ServerInterface &socket); int get_receiver_roi(ServerInterface &socket);
int set_receiver_roi(ServerInterface &socket); int set_receiver_roi(ServerInterface &socket);
int set_receiver_roi_metadata(ServerInterface &socket); int set_receiver_roi_metadata(ServerInterface &socket);
int set_num_transceiver_samples(ServerInterface &socket);
int set_transceiver_mask(ServerInterface &socket);
Implementation *impl() { Implementation *impl() {
if (receiver != nullptr) { if (receiver != nullptr) {

View File

@ -496,8 +496,10 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) {
/** ctb specific */ /** ctb specific */
void DataProcessor::RearrangeDbitData(size_t &size, char *data) { void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
int nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); int nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes();
int nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes();
int nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes();
// TODO! (Erik) Refactor and add tests // TODO! (Erik) Refactor and add tests
int ctbDigitalDataBytes = size - nAnalogDataBytes - ctbDbitOffset; int ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset;
// no digital data // no digital data
if (ctbDigitalDataBytes == 0) { if (ctbDigitalDataBytes == 0) {
@ -506,11 +508,15 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
return; return;
} }
const int numSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t));
// ceil as numResult8Bits could be decimal // const int numResult8Bits = ceil((numDigitalSamples * ctbDbitList.size())
const int numResult8Bits = ceil((numSamples * ctbDbitList.size()) / 8.00); // / 8.00);
std::vector<uint8_t> result(numResult8Bits); int numBitsPerDbit = numDigitalSamples;
if ((numBitsPerDbit % 8) != 0)
numBitsPerDbit += (8 - (numDigitalSamples % 8));
const int totalNumBytes = (numBitsPerDbit / 8) * ctbDbitList.size();
std::vector<uint8_t> result(totalNumBytes);
uint8_t *dest = &result[0]; uint8_t *dest = &result[0];
auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset);
@ -518,14 +524,14 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
// loop through digital bit enable vector // loop through digital bit enable vector
int bitoffset = 0; int bitoffset = 0;
for (auto bi : ctbDbitList) { for (auto bi : ctbDbitList) {
// where numbits * numsamples is not a multiple of 8 // where numbits * numDigitalSamples is not a multiple of 8
if (bitoffset != 0) { if (bitoffset != 0) {
bitoffset = 0; bitoffset = 0;
++dest; ++dest;
} }
// loop through the frame digital data // loop through the frame digital data
for (auto *ptr = source; ptr < (source + numSamples);) { for (auto *ptr = source; ptr < (source + numDigitalSamples);) {
// get selected bit from each 8 bit // get selected bit from each 8 bit
uint8_t bit = (*ptr++ >> bi) & 1; uint8_t bit = (*ptr++ >> bi) & 1;
*dest |= bit << bitoffset; *dest |= bit << bitoffset;
@ -540,8 +546,14 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
// copy back to memory and update size // copy back to memory and update size
memcpy(data + nAnalogDataBytes, result.data(), memcpy(data + nAnalogDataBytes, result.data(),
numResult8Bits * sizeof(uint8_t)); totalNumBytes * sizeof(uint8_t));
size = numResult8Bits * sizeof(uint8_t) + nAnalogDataBytes + ctbDbitOffset; size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + ctbDbitOffset +
nTransceiverDataBytes;
LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes
<< " nAnalogDataBytes:" << nAnalogDataBytes
<< " ctbDbitOffset:" << ctbDbitOffset
<< " nTransceiverDataBytes:" << nTransceiverDataBytes
<< " size:" << size;
} }
void DataProcessor::CropImage(size_t &size, char *data) { void DataProcessor::CropImage(size_t &size, char *data) {

View File

@ -58,11 +58,13 @@ class GeneralData {
bool tengigaEnable{false}; bool tengigaEnable{false};
uint32_t nAnalogSamples{0}; uint32_t nAnalogSamples{0};
uint32_t nDigitalSamples{0}; uint32_t nDigitalSamples{0};
uint32_t nTransceiverSamples{0};
slsDetectorDefs::readoutMode readoutType{slsDetectorDefs::ANALOG_ONLY}; slsDetectorDefs::readoutMode readoutType{slsDetectorDefs::ANALOG_ONLY};
uint32_t adcEnableMaskOneGiga{BIT32_MASK}; uint32_t adcEnableMaskOneGiga{BIT32_MASK};
uint32_t adcEnableMaskTenGiga{BIT32_MASK}; uint32_t adcEnableMaskTenGiga{BIT32_MASK};
slsDetectorDefs::ROI detectorRoi{}; slsDetectorDefs::ROI detectorRoi{};
uint32_t counterMask{0}; uint32_t counterMask{0};
uint32_t transceiverMask{0};
GeneralData(){}; GeneralData(){};
virtual ~GeneralData(){}; virtual ~GeneralData(){};
@ -132,6 +134,16 @@ class GeneralData {
return 0; return 0;
}; };
virtual int GetNumberOfDigitalDatabytes() {
ThrowGenericError("GetNumberOfDigitalDatabytes");
return 0;
};
virtual int GetNumberOfTransceiverDatabytes() {
ThrowGenericError("GetNumberOfTransceiverDatabytes");
return 0;
};
virtual void SetNumberOfAnalogSamples(int n) { virtual void SetNumberOfAnalogSamples(int n) {
ThrowGenericError("SetNumberOfAnalogSamples"); ThrowGenericError("SetNumberOfAnalogSamples");
}; };
@ -140,6 +152,10 @@ class GeneralData {
ThrowGenericError("SetNumberOfDigitalSamples"); ThrowGenericError("SetNumberOfDigitalSamples");
}; };
virtual void SetNumberOfTransceiverSamples(int n) {
ThrowGenericError("SetNumberOfTransceiverSamples");
};
virtual void SetOneGigaAdcEnableMask(int n) { virtual void SetOneGigaAdcEnableMask(int n) {
ThrowGenericError("SetOneGigaAdcEnableMask"); ThrowGenericError("SetOneGigaAdcEnableMask");
}; };
@ -151,6 +167,10 @@ class GeneralData {
virtual void SetReadoutMode(slsDetectorDefs::readoutMode r) { virtual void SetReadoutMode(slsDetectorDefs::readoutMode r) {
ThrowGenericError("SetReadoutMode"); ThrowGenericError("SetReadoutMode");
}; };
virtual void SetTransceiverEnableMask(int n) {
ThrowGenericError("SetTransceiverEnableMask");
};
}; };
class GotthardData : public GeneralData { class GotthardData : public GeneralData {
@ -507,7 +527,10 @@ class ChipTestBoardData : public GeneralData {
private: private:
const int NCHAN_DIGITAL = 64; const int NCHAN_DIGITAL = 64;
const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; const int NUM_BYTES_PER_ANALOG_CHANNEL = 2;
const int NUM_BYTES_PER_TRANSCEIVER_CHANNEL = 8;
int nAnalogBytes = 0; int nAnalogBytes = 0;
int nDigitalBytes = 0;
int nTransceiverBytes = 0;
public: public:
/** Constructor */ /** Constructor */
@ -527,6 +550,10 @@ class ChipTestBoardData : public GeneralData {
public: public:
int GetNumberOfAnalogDatabytes() { return nAnalogBytes; }; int GetNumberOfAnalogDatabytes() { return nAnalogBytes; };
int GetNumberOfDigitalDatabytes() { return nDigitalBytes; };
int GetNumberOfTransceiverDatabytes() { return nTransceiverBytes; };
void SetNumberOfAnalogSamples(int n) { void SetNumberOfAnalogSamples(int n) {
nAnalogSamples = n; nAnalogSamples = n;
UpdateImageSize(); UpdateImageSize();
@ -537,6 +564,11 @@ class ChipTestBoardData : public GeneralData {
UpdateImageSize(); UpdateImageSize();
}; };
void SetNumberOfTransceiverSamples(int n) {
nTransceiverSamples = n;
UpdateImageSize();
};
void SetOneGigaAdcEnableMask(int n) { void SetOneGigaAdcEnableMask(int n) {
adcEnableMaskOneGiga = n; adcEnableMaskOneGiga = n;
UpdateImageSize(); UpdateImageSize();
@ -547,6 +579,11 @@ class ChipTestBoardData : public GeneralData {
UpdateImageSize(); UpdateImageSize();
}; };
void SetTransceiverEnableMask(int n) {
transceiverMask = n;
UpdateImageSize();
};
void SetReadoutMode(slsDetectorDefs::readoutMode r) { void SetReadoutMode(slsDetectorDefs::readoutMode r) {
readoutType = r; readoutType = r;
UpdateImageSize(); UpdateImageSize();
@ -560,8 +597,9 @@ class ChipTestBoardData : public GeneralData {
private: private:
void UpdateImageSize() { void UpdateImageSize() {
nAnalogBytes = 0; nAnalogBytes = 0;
int nDigitalBytes = 0; nDigitalBytes = 0;
int nAnalogChans = 0, nDigitalChans = 0; nTransceiverBytes = 0;
int nAnalogChans = 0, nDigitalChans = 0, nTransceiverChans = 0;
// analog channels (normal, analog/digital readout) // analog channels (normal, analog/digital readout)
if (readoutType == slsDetectorDefs::ANALOG_ONLY || if (readoutType == slsDetectorDefs::ANALOG_ONLY ||
@ -577,17 +615,29 @@ class ChipTestBoardData : public GeneralData {
} }
// digital channels // digital channels
if (readoutType == slsDetectorDefs::DIGITAL_ONLY || if (readoutType == slsDetectorDefs::DIGITAL_ONLY ||
readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL) { readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nDigitalChans = NCHAN_DIGITAL; nDigitalChans = NCHAN_DIGITAL;
nDigitalBytes = (sizeof(uint64_t) * nDigitalSamples); nDigitalBytes = (sizeof(uint64_t) * nDigitalSamples);
LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans
<< " Databytes: " << nDigitalBytes; << " Databytes: " << nDigitalBytes;
} }
// transceiver channels
nPixelsX = nAnalogChans + nDigitalChans; if (readoutType == slsDetectorDefs::TRANSCEIVER_ONLY ||
readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) {
nTransceiverChans = __builtin_popcount(transceiverMask);
;
nTransceiverBytes = nTransceiverChans *
NUM_BYTES_PER_TRANSCEIVER_CHANNEL *
nTransceiverSamples;
LOG(logDEBUG1) << "Number of Transceiver Channels:"
<< nTransceiverChans
<< " Databytes: " << nTransceiverBytes;
}
nPixelsX = nAnalogChans + nDigitalChans + nTransceiverChans;
dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES; dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES;
packetSize = headerSizeinPacket + dataSize; packetSize = headerSizeinPacket + dataSize;
imageSize = nAnalogBytes + nDigitalBytes; imageSize = nAnalogBytes + nDigitalBytes + nTransceiverBytes;
packetsPerFrame = ceil((double)imageSize / (double)dataSize); packetsPerFrame = ceil((double)imageSize / (double)dataSize);
LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX

View File

@ -946,7 +946,8 @@ void Implementation::StartMasterWriter() {
masterAttributes.analogSamples = generalData->nAnalogSamples; masterAttributes.analogSamples = generalData->nAnalogSamples;
masterAttributes.digital = masterAttributes.digital =
(generalData->readoutType == DIGITAL_ONLY || (generalData->readoutType == DIGITAL_ONLY ||
generalData->readoutType == ANALOG_AND_DIGITAL) generalData->readoutType == ANALOG_AND_DIGITAL ||
generalData->readoutType == DIGITAL_AND_TRANSCEIVER)
? 1 ? 1
: 0; : 0;
masterAttributes.digitalSamples = generalData->nDigitalSamples; masterAttributes.digitalSamples = generalData->nDigitalSamples;
@ -955,6 +956,14 @@ void Implementation::StartMasterWriter() {
for (auto &i : ctbDbitList) { for (auto &i : ctbDbitList) {
masterAttributes.dbitlist |= (1 << i); masterAttributes.dbitlist |= (1 << i);
} }
masterAttributes.transceiverSamples =
generalData->nTransceiverSamples;
masterAttributes.transceiverMask = generalData->transceiverMask;
masterAttributes.transceiver =
(generalData->readoutType == TRANSCEIVER_ONLY ||
generalData->readoutType == DIGITAL_AND_TRANSCEIVER)
? 1
: 0;
masterAttributes.detectorRoi = generalData->detectorRoi; masterAttributes.detectorRoi = generalData->detectorRoi;
masterAttributes.counterMask = generalData->counterMask; masterAttributes.counterMask = generalData->counterMask;
masterAttributes.exptimeArray[0] = acquisitionTime1; masterAttributes.exptimeArray[0] = acquisitionTime1;
@ -1509,6 +1518,20 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame); LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
} }
uint32_t Implementation::getNumberofTransceiverSamples() const {
return generalData->nTransceiverSamples;
}
void Implementation::setNumberofTransceiverSamples(const uint32_t i) {
if (generalData->nTransceiverSamples != i) {
generalData->SetNumberOfTransceiverSamples(i);
SetupFifoStructure();
}
LOG(logINFO) << "Number of Transceiver Samples: "
<< generalData->nTransceiverSamples;
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
}
uint32_t Implementation::getCounterMask() const { uint32_t Implementation::getCounterMask() const {
return generalData->counterMask; return generalData->counterMask;
} }
@ -1718,6 +1741,20 @@ void Implementation::setDbitOffset(const int s) {
LOG(logINFO) << "Dbit offset: " << ctbDbitOffset; LOG(logINFO) << "Dbit offset: " << ctbDbitOffset;
} }
uint32_t Implementation::getTransceiverEnableMask() const {
return generalData->transceiverMask;
}
void Implementation::setTransceiverEnableMask(uint32_t mask) {
if (generalData->transceiverMask != mask) {
generalData->SetTransceiverEnableMask(mask);
SetupFifoStructure();
}
LOG(logINFO) << "Transceiver Enable Mask: 0x" << std::hex
<< generalData->transceiverMask << std::dec;
LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
}
/************************************************** /**************************************************
* * * *
* Callbacks * * Callbacks *

View File

@ -108,17 +108,17 @@ class Implementation : private virtual slsDetectorDefs {
* * * *
* ************************************************/ * ************************************************/
int getNumberofUDPInterfaces() const; int getNumberofUDPInterfaces() const;
/* [Jungfrau] */ /* [Jungfrau][Moench] */
void setNumberofUDPInterfaces(const int n); void setNumberofUDPInterfaces(const int n);
std::string getEthernetInterface() const; std::string getEthernetInterface() const;
void setEthernetInterface(const std::string &c); void setEthernetInterface(const std::string &c);
std::string getEthernetInterface2() const; std::string getEthernetInterface2() const;
/* [Jungfrau] */ /* [Jungfrau][Moench] */
void setEthernetInterface2(const std::string &c); void setEthernetInterface2(const std::string &c);
uint32_t getUDPPortNumber() const; uint32_t getUDPPortNumber() const;
void setUDPPortNumber(const uint32_t i); void setUDPPortNumber(const uint32_t i);
uint32_t getUDPPortNumber2() const; uint32_t getUDPPortNumber2() const;
/* [Eiger][Jungfrau] */ /* [Eiger][Jungfrau][Moench] */
void setUDPPortNumber2(const uint32_t i); void setUDPPortNumber2(const uint32_t i);
int getUDPSocketBufferSize() const; int getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int s); void setUDPSocketBufferSize(const int s);
@ -198,11 +198,14 @@ class Implementation : private virtual slsDetectorDefs {
/* [Eiger] */ /* [Eiger] */
void setSubPeriod(const ns i); void setSubPeriod(const ns i);
uint32_t getNumberofAnalogSamples() const; uint32_t getNumberofAnalogSamples() const;
/**[Ctb][Moench] */ /**[Ctb] */
void setNumberofAnalogSamples(const uint32_t i); void setNumberofAnalogSamples(const uint32_t i);
uint32_t getNumberofDigitalSamples() const; uint32_t getNumberofDigitalSamples() const;
/**[Ctb] */ /**[Ctb] */
void setNumberofDigitalSamples(const uint32_t i); void setNumberofDigitalSamples(const uint32_t i);
uint32_t getNumberofTransceiverSamples() const;
/**[Ctb] */
void setNumberofTransceiverSamples(const uint32_t i);
uint32_t getCounterMask() const; uint32_t getCounterMask() const;
/** [Mythen3] */ /** [Mythen3] */
void setCounterMask(const uint32_t i); void setCounterMask(const uint32_t i);
@ -230,7 +233,7 @@ class Implementation : private virtual slsDetectorDefs {
* detector) */ * detector) */
void setDetectorDataStream(const portPosition port, const bool enable); void setDetectorDataStream(const portPosition port, const bool enable);
int getReadNRows() const; int getReadNRows() const;
/* [Eiger][Jungfrau] */ /* [Eiger][Jungfrau][Moench] */
void setReadNRows(const int value); void setReadNRows(const int value);
/** [Eiger] */ /** [Eiger] */
void setThresholdEnergy(const int value); void setThresholdEnergy(const int value);
@ -241,10 +244,10 @@ class Implementation : private virtual slsDetectorDefs {
/* [Ctb] */ /* [Ctb] */
void setReadoutMode(const readoutMode f); void setReadoutMode(const readoutMode f);
uint32_t getADCEnableMask() const; uint32_t getADCEnableMask() const;
/* [Ctb][Moench] */ /* [Ctb] */
void setADCEnableMask(const uint32_t mask); void setADCEnableMask(const uint32_t mask);
uint32_t getTenGigaADCEnableMask() const; uint32_t getTenGigaADCEnableMask() const;
/* [Ctb][Moench] */ /* [Ctb] */
void setTenGigaADCEnableMask(const uint32_t mask); void setTenGigaADCEnableMask(const uint32_t mask);
std::vector<int> getDbitList() const; std::vector<int> getDbitList() const;
/* [Ctb] */ /* [Ctb] */
@ -252,6 +255,9 @@ class Implementation : private virtual slsDetectorDefs {
int getDbitOffset() const; int getDbitOffset() const;
/* [Ctb] */ /* [Ctb] */
void setDbitOffset(const int s); void setDbitOffset(const int s);
uint32_t getTransceiverEnableMask() const;
/* [Ctb] */
void setTransceiverEnableMask(const uint32_t mask);
/************************************************** /**************************************************
* * * *

View File

@ -574,6 +574,30 @@ void MasterAttributes::WriteHDF5DbitList(H5::H5File *fd, H5::Group *group) {
"Dbit Bitset List", H5::PredType::STD_U64LE, dataspace); "Dbit Bitset List", H5::PredType::STD_U64LE, dataspace);
dataset.write(&dbitlist, H5::PredType::STD_U64LE); dataset.write(&dbitlist, H5::PredType::STD_U64LE);
} }
void MasterAttributes::WriteHDF5TransceiverMask(H5::H5File *fd,
H5::Group *group) {
H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR);
H5::DataSet dataset = group->createDataSet(
"Transceiver Mask", H5::PredType::NATIVE_INT, dataspace);
dataset.write(&transceiverMask, H5::PredType::NATIVE_INT);
}
void MasterAttributes::WriteHDF5TransceiverFlag(H5::H5File *fd,
H5::Group *group) {
H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR);
H5::DataSet dataset = group->createDataSet(
"Transceiver Flag", H5::PredType::NATIVE_INT, dataspace);
dataset.write(&transceiver, H5::PredType::NATIVE_INT);
}
void MasterAttributes::WriteHDF5TransceiverSamples(H5::H5File *fd,
H5::Group *group) {
H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR);
H5::DataSet dataset = group->createDataSet(
"Transceiver Samples", H5::PredType::NATIVE_INT, dataspace);
dataset.write(&transceiverSamples, H5::PredType::NATIVE_INT);
}
#endif #endif
void MasterAttributes::GetGotthardBinaryAttributes( void MasterAttributes::GetGotthardBinaryAttributes(
@ -763,6 +787,12 @@ void MasterAttributes::GetCtbBinaryAttributes(
w->Uint(dbitoffset); w->Uint(dbitoffset);
w->Key("Dbit Bitset"); w->Key("Dbit Bitset");
w->Uint64(dbitlist); w->Uint64(dbitlist);
w->Key("Transceiver Mask");
w->String(ToStringHex(transceiverMask).c_str());
w->Key("Transceiver Flag");
w->Uint(transceiver);
w->Key("Transceiver Samples");
w->Uint(transceiverSamples);
} }
#ifdef HDF5C #ifdef HDF5C
@ -778,6 +808,9 @@ void MasterAttributes::WriteCtbHDF5Attributes(H5::H5File *fd,
MasterAttributes::WriteHDF5DigitalSamples(fd, group); MasterAttributes::WriteHDF5DigitalSamples(fd, group);
MasterAttributes::WriteHDF5DbitOffset(fd, group); MasterAttributes::WriteHDF5DbitOffset(fd, group);
MasterAttributes::WriteHDF5DbitList(fd, group); MasterAttributes::WriteHDF5DbitList(fd, group);
MasterAttributes::WriteHDF5TransceiverMask(fd, group);
MasterAttributes::WriteHDF5TransceiverFlag(fd, group);
MasterAttributes::WriteHDF5TransceiverSamples(fd, group);
} }
#endif #endif

View File

@ -53,6 +53,9 @@ class MasterAttributes {
uint32_t digitalSamples{0}; uint32_t digitalSamples{0};
uint32_t dbitoffset{0}; uint32_t dbitoffset{0};
uint64_t dbitlist{0}; uint64_t dbitlist{0};
uint32_t transceiverMask{0};
uint32_t transceiver{0};
uint32_t transceiverSamples{0};
slsDetectorDefs::ROI detectorRoi{}; slsDetectorDefs::ROI detectorRoi{};
slsDetectorDefs::ROI receiverRoi{}; slsDetectorDefs::ROI receiverRoi{};
uint32_t counterMask{0}; uint32_t counterMask{0};
@ -103,6 +106,9 @@ class MasterAttributes {
void WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group); void WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group);
void WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group); void WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group);
void WriteHDF5DbitList(H5::H5File *fd, H5::Group *group); void WriteHDF5DbitList(H5::H5File *fd, H5::Group *group);
void WriteHDF5TransceiverMask(H5::H5File *fd, H5::Group *group);
void WriteHDF5TransceiverFlag(H5::H5File *fd, H5::Group *group);
void WriteHDF5TransceiverSamples(H5::H5File *fd, H5::Group *group);
#endif #endif
void GetGotthardBinaryAttributes( void GetGotthardBinaryAttributes(

View File

@ -406,7 +406,13 @@ typedef struct {
/** /**
* read out mode (ctb) * read out mode (ctb)
*/ */
enum readoutMode { ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL }; enum readoutMode {
ANALOG_ONLY,
DIGITAL_ONLY,
ANALOG_AND_DIGITAL,
TRANSCEIVER_ONLY,
DIGITAL_AND_TRANSCEIVER
};
/** chip speed */ /** chip speed */
enum speedLevel { enum speedLevel {
@ -588,6 +594,8 @@ enum streamingInterface {
int64_t gateDelay3Ns{0}; int64_t gateDelay3Ns{0};
int gates{0}; int gates{0};
scanParameters scanParams{}; scanParameters scanParams{};
int transceiverSamples{0};
uint32_t transceiverMask{0};
} __attribute__((packed)); } __attribute__((packed));
#endif #endif

View File

@ -282,6 +282,10 @@ enum detFuncs {
F_CLEAR_BIT, F_CLEAR_BIT,
F_GET_PATTERN_IO_CONTROL, F_GET_PATTERN_IO_CONTROL,
F_GET_PATTERN_FILE_NAME, F_GET_PATTERN_FILE_NAME,
F_GET_NUM_TRANSCEIVER_SAMPLES,
F_SET_NUM_TRANSCEIVER_SAMPLES,
F_GET_TRANSCEIVER_ENABLE_MASK,
F_SET_TRANSCEIVER_ENABLE_MASK,
NUM_DET_FUNCTIONS, NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 512, /**< detector function should not exceed this RECEIVER_ENUM_START = 512, /**< detector function should not exceed this
@ -389,6 +393,8 @@ enum detFuncs {
F_RECEIVER_GET_RECEIVER_ROI, F_RECEIVER_GET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI, F_RECEIVER_SET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI_METADATA, F_RECEIVER_SET_RECEIVER_ROI_METADATA,
F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES,
F_RECEIVER_SET_TRANSCEIVER_MASK,
NUM_REC_FUNCTIONS NUM_REC_FUNCTIONS
}; };
@ -667,7 +673,10 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_CLEAR_BIT: return "F_CLEAR_BIT"; case F_CLEAR_BIT: return "F_CLEAR_BIT";
case F_GET_PATTERN_IO_CONTROL: return "F_GET_PATTERN_IO_CONTROL"; case F_GET_PATTERN_IO_CONTROL: return "F_GET_PATTERN_IO_CONTROL";
case F_GET_PATTERN_FILE_NAME: return "F_GET_PATTERN_FILE_NAME"; case F_GET_PATTERN_FILE_NAME: return "F_GET_PATTERN_FILE_NAME";
case F_GET_NUM_TRANSCEIVER_SAMPLES: return "F_GET_NUM_TRANSCEIVER_SAMPLES";
case F_SET_NUM_TRANSCEIVER_SAMPLES: return "F_SET_NUM_TRANSCEIVER_SAMPLES";
case F_GET_TRANSCEIVER_ENABLE_MASK: return "F_GET_TRANSCEIVER_ENABLE_MASK";
case F_SET_TRANSCEIVER_ENABLE_MASK: return "F_SET_TRANSCEIVER_ENABLE_MASK";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
@ -775,6 +784,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_RECEIVER_GET_RECEIVER_ROI: return "F_RECEIVER_GET_RECEIVER_ROI"; case F_RECEIVER_GET_RECEIVER_ROI: return "F_RECEIVER_GET_RECEIVER_ROI";
case F_RECEIVER_SET_RECEIVER_ROI: return "F_RECEIVER_SET_RECEIVER_ROI"; case F_RECEIVER_SET_RECEIVER_ROI: return "F_RECEIVER_SET_RECEIVER_ROI";
case F_RECEIVER_SET_RECEIVER_ROI_METADATA: return "F_RECEIVER_SET_RECEIVER_ROI_METADATA"; case F_RECEIVER_SET_RECEIVER_ROI_METADATA: return "F_RECEIVER_SET_RECEIVER_ROI_METADATA";
case F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES: return "F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES";
case F_RECEIVER_SET_TRANSCEIVER_MASK: return "F_RECEIVER_SET_TRANSCEIVER_MASK";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function"; default: return "Unknown Function";

View File

@ -8,6 +8,6 @@
#define APIGOTTHARD "developer 0x230615" #define APIGOTTHARD "developer 0x230615"
#define APIGOTTHARD2 "developer 0x230615" #define APIGOTTHARD2 "developer 0x230615"
#define APIJUNGFRAU "developer 0x230615" #define APIJUNGFRAU "developer 0x230615"
#define APICTB "developer 0x230621" #define APICTB "developer 0x230629"
#define APIMYTHEN3 "developer 0x230621" #define APIMYTHEN3 "developer 0x230621"
#define APIMOENCH "developer 0x230707" #define APIMOENCH "developer 0x230707"

View File

@ -87,6 +87,8 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
<< std::endl << std::endl
<< "gates:" << r.gates << std::endl << "gates:" << r.gates << std::endl
<< "scanParams:" << ToString(r.scanParams) << std::endl << "scanParams:" << ToString(r.scanParams) << std::endl
<< "transceiverSamples:" << r.transceiverSamples << std::endl
<< "transceiverMask:" << r.transceiverMask << std::endl
<< ']'; << ']';
return oss.str(); return oss.str();
} }
@ -325,6 +327,10 @@ std::string ToString(const defs::readoutMode s) {
return std::string("digital"); return std::string("digital");
case defs::ANALOG_AND_DIGITAL: case defs::ANALOG_AND_DIGITAL:
return std::string("analog_digital"); return std::string("analog_digital");
case defs::TRANSCEIVER_ONLY:
return std::string("transceiver");
case defs::DIGITAL_AND_TRANSCEIVER:
return std::string("digital_transceiver");
default: default:
return std::string("Unknown"); return std::string("Unknown");
} }
@ -789,6 +795,10 @@ template <> defs::readoutMode StringTo(const std::string &s) {
return defs::DIGITAL_ONLY; return defs::DIGITAL_ONLY;
if (s == "analog_digital") if (s == "analog_digital")
return defs::ANALOG_AND_DIGITAL; return defs::ANALOG_AND_DIGITAL;
if (s == "transceiver")
return defs::TRANSCEIVER_ONLY;
if (s == "digital_transceiver")
return defs::DIGITAL_AND_TRANSCEIVER;
throw RuntimeError("Unknown readout mode " + s); throw RuntimeError("Unknown readout mode " + s);
} }