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):
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
@element
def samples(self):
"""
[CTB] Number of samples (both analog and digitial) expected. \n
[CTB] Number of samples (only analog) expected. \n
"""
return self.getNumberOfAnalogSamples()
@ -3211,7 +3221,7 @@ class Detector(CppDetectorApi):
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
Example
@ -3246,6 +3256,16 @@ class Detector(CppDetectorApi):
def dsamples(self, 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
@element
def dbitphase(self):

View File

@ -1556,6 +1556,14 @@ void init_det(py::module &m) {
(void (Detector::*)(uint32_t, sls::Positions)) &
Detector::setTenGigaADCEnableMask,
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",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfDigitalSamples,
@ -1564,6 +1572,14 @@ void init_det(py::module &m) {
(void (Detector::*)(int, sls::Positions)) &
Detector::setNumberOfDigitalSamples,
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(
"getReadoutMode",
(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("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();
py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel")

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
// clang-format off
/* Definitions for FPGA */
#define MEM_MAP_SHIFT 1
@ -87,7 +88,7 @@
/* PLL Param (Reconfiguratble PLL Parameter) RO register TODO FIXME: Same as
* PLL_PARAM_REG 0x50 */
//#define PLL_PARAM_REG (0x05 << MEM_MAP_SHIFT)
// #define PLL_PARAM_REG (0x05 << MEM_MAP_SHIFT)
/* FIFO Data RO register TODO */
#define FIFO_DATA_REG (0x06 << MEM_MAP_SHIFT)
@ -95,8 +96,9 @@
#define FIFO_DATA_HRDWR_SRL_NMBR_OFST (0)
#define FIFO_DATA_HRDWR_SRL_NMBR_MSK \
(0x0000FFFF << FIFO_DATA_HRDWR_SRL_NMBR_OFST)
//#define FIFO_DATA_WRD_OFST (16)
//#define FIFO_DATA_WRD_MSK (0x0000FFFF << FIFO_DATA_WRD_OFST)
// #define FIFO_DATA_WRD_OFST (16)
// #define FIFO_DATA_WRD_MSK (0x0000FFFF <<
// FIFO_DATA_WRD_OFST)
/* FIFO Status RO register TODO */
#define FIFO_STATUS_REG (0x07 << MEM_MAP_SHIFT)
@ -146,15 +148,15 @@
#define PERIOD_LEFT_MSB_REG (0x19 << MEM_MAP_SHIFT)
/* Exposure Time Left 64 bit RO register */
//#define EXPTIME_LEFT_LSB_REG (0x1A << MEM_MAP_SHIFT) // Not
// used in FW #define EXPTIME_LEFT_MSB_REG (0x1B <<
// MEM_MAP_SHIFT)
// #define EXPTIME_LEFT_LSB_REG (0x1A << MEM_MAP_SHIFT) // Not
// used in FW #define EXPTIME_LEFT_MSB_REG (0x1B <<
// MEM_MAP_SHIFT)
//// Not used in FW
/* Gates Left 64 bit RO register */
//#define GATES_LEFT_LSB_REG (0x1C << MEM_MAP_SHIFT) // Not
// used in FW #define GATES_LEFT_MSB_REG (0x1D <<
// MEM_MAP_SHIFT)
// #define GATES_LEFT_LSB_REG (0x1C << MEM_MAP_SHIFT) // Not
// used in FW #define GATES_LEFT_MSB_REG (0x1D <<
// MEM_MAP_SHIFT)
//// Not used in FW
/* Data In 64 bit RO register TODO */
@ -184,14 +186,28 @@
#define POWER_STATUS_ALRT_OFST (27)
#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 */
#define FIFO_DIN_STATUS_REG (0x3B << MEM_MAP_SHIFT)
#define FIFO_DIN_STATUS_FIFO_FULL_OFST (30)
#define FIFO_DIN_STATUS_FIFO_FULL_MSK \
(0x00000001 << FIFO_DIN_STATUS_FIFO_FULL_OFST)
#define FIFO_DIN_STATUS_REG (0x3B << MEM_MAP_SHIFT)
#define FIFO_DIN_STATUS_FIFO_FULL_OFST (30)
#define FIFO_DIN_STATUS_FIFO_FULL_MSK (0x00000001 << FIFO_DIN_STATUS_FIFO_FULL_OFST)
#define FIFO_DIN_STATUS_FIFO_EMPTY_OFST (31)
#define FIFO_DIN_STATUS_FIFO_EMPTY_MSK \
(0x00000001 << FIFO_DIN_STATUS_FIFO_EMPTY_OFST)
#define FIFO_DIN_STATUS_FIFO_EMPTY_MSK (0x00000001 << FIFO_DIN_STATUS_FIFO_EMPTY_OFST)
/* FIFO Digital In 64 bit RO register */
#define FIFO_DIN_LSB_REG (0x3C << MEM_MAP_SHIFT)
@ -246,14 +262,16 @@
/* Dummy RW register */
#define DUMMY_REG (0x44 << MEM_MAP_SHIFT)
#define DUMMY_FIFO_CHNNL_SLCT_OFST (0)
#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_MSK \
(0x00000001 << DUMMY_ANLG_FIFO_RD_STRBE_OFST)
#define DUMMY_DGTL_FIFO_RD_STRBE_OFST (9)
#define DUMMY_DGTL_FIFO_RD_STRBE_MSK \
(0x00000001 << DUMMY_DGTL_FIFO_RD_STRBE_OFST)
#define DUMMY_FIFO_CHNNL_SLCT_OFST (0)
#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_MSK (0x00000001 << DUMMY_ANLG_FIFO_RD_STRBE_OFST)
#define DUMMY_DGTL_FIFO_RD_STRBE_OFST (9)
#define DUMMY_DGTL_FIFO_RD_STRBE_MSK (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 */
#define RX_IP_REG (0x45 << MEM_MAP_SHIFT)
@ -296,14 +314,17 @@
/* Configuration RW register */
#define CONFIG_REG (0x4D << MEM_MAP_SHIFT)
#define CONFIG_LED_DSBL_OFST (0)
#define CONFIG_LED_DSBL_MSK (0x00000001 << CONFIG_LED_DSBL_OFST)
#define CONFIG_DSBL_ANLG_OTPT_OFST (8)
#define CONFIG_DSBL_ANLG_OTPT_MSK (0x00000001 << CONFIG_DSBL_ANLG_OTPT_OFST)
#define CONFIG_ENBLE_DGTL_OTPT_OFST (9)
#define CONFIG_ENBLE_DGTL_OTPT_MSK (0x00000001 << CONFIG_ENBLE_DGTL_OTPT_OFST)
#define CONFIG_GB10_SND_UDP_OFST (12)
#define CONFIG_GB10_SND_UDP_MSK (0x00000001 << CONFIG_GB10_SND_UDP_OFST)
#define CONFIG_LED_DSBL_OFST (0)
#define CONFIG_LED_DSBL_MSK (0x00000001 << CONFIG_LED_DSBL_OFST)
#define CONFIG_DSBL_ANLG_OTPT_OFST (8)
#define CONFIG_DSBL_ANLG_OTPT_MSK (0x00000001 << CONFIG_DSBL_ANLG_OTPT_OFST)
#define CONFIG_ENBLE_DGTL_OTPT_OFST (9)
#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_MSK (0x00000001 << CONFIG_GB10_SND_UDP_OFST)
/* External Signal RW register */
#define EXT_SIGNAL_REG (0x4E << MEM_MAP_SHIFT)
@ -320,33 +341,34 @@
#define CONTROL_STRT_ACQSTN_MSK (0x00000001 << CONTROL_STRT_ACQSTN_OFST)
#define CONTROL_STP_ACQSTN_OFST (1)
#define CONTROL_STP_ACQSTN_MSK (0x00000001 << CONTROL_STP_ACQSTN_OFST)
//#define CONTROL_STRT_FF_TST_OFST (2)
//#define CONTROL_STRT_FF_TST_MSK (0x00000001 <<
// CONTROL_STRT_FF_TST_OFST) #define CONTROL_STP_FF_TST_OFST (3)
//#define CONTROL_STP_FF_TST_MSK (0x00000001 <<
// CONTROL_STP_FF_TST_OFST) #define CONTROL_STRT_RDT_OFST (4)
//#define CONTROL_STRT_RDT_MSK (0x00000001 <<
// CONTROL_STRT_RDT_OFST) #define CONTROL_STP_RDT_OFST (5)
// #define CONTROL_STP_RDT_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST)
// #define CONTROL_STRT_FF_TST_OFST (2)
// #define CONTROL_STRT_FF_TST_MSK (0x00000001 <<
// CONTROL_STRT_FF_TST_OFST) #define CONTROL_STP_FF_TST_OFST (3)
// #define CONTROL_STP_FF_TST_MSK (0x00000001 <<
// CONTROL_STP_FF_TST_OFST) #define CONTROL_STRT_RDT_OFST (4)
// #define CONTROL_STRT_RDT_MSK (0x00000001 <<
// CONTROL_STRT_RDT_OFST) #define CONTROL_STP_RDT_OFST (5)
// #define CONTROL_STP_RDT_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST)
#define CONTROL_STRT_EXPSR_OFST (6)
#define CONTROL_STRT_EXPSR_MSK (0x00000001 << CONTROL_STRT_EXPSR_OFST)
//#define CONTROL_STP_EXPSR_OFST (7)
//#define CONTROL_STP_EXPSR_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST) #define CONTROL_STRT_TRN_OFST (8) #define
// CONTROL_STRT_TRN_MSK (0x00000001 << CONTROL_STRT_RDT_OFST)
//#define CONTROL_STP_TRN_OFST (9)
//#define CONTROL_STP_TRN_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST)
// #define CONTROL_STP_EXPSR_OFST (7)
// #define CONTROL_STP_EXPSR_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST) #define CONTROL_STRT_TRN_OFST (8)
// #define CONTROL_STRT_TRN_MSK (0x00000001 <<
// CONTROL_STRT_RDT_OFST)
// #define CONTROL_STP_TRN_OFST (9)
// #define CONTROL_STP_TRN_MSK (0x00000001 <<
// CONTROL_STP_RDT_OFST)
#define CONTROL_CRE_RST_OFST (10)
#define CONTROL_CRE_RST_MSK (0x00000001 << CONTROL_CRE_RST_OFST)
#define CONTROL_PRPHRL_RST_OFST (11) // Only GBE10?
#define CONTROL_PRPHRL_RST_MSK (0x00000001 << CONTROL_PRPHRL_RST_OFST)
#define CONTROL_MMRY_RST_OFST (12)
#define CONTROL_MMRY_RST_MSK (0x00000001 << CONTROL_MMRY_RST_OFST)
//#define CONTROL_PLL_RCNFG_WR_OFST (13)
//#define CONTROL_PLL_RCNFG_WR_MSK (0x00000001 <<
// CONTROL_PLL_RCNFG_WR_OFST)
// #define CONTROL_PLL_RCNFG_WR_OFST (13)
// #define CONTROL_PLL_RCNFG_WR_MSK (0x00000001 <<
// CONTROL_PLL_RCNFG_WR_OFST)
#define CONTROL_SND_10GB_PCKT_OFST (14)
#define CONTROL_SND_10GB_PCKT_MSK (0x00000001 << CONTROL_SND_10GB_PCKT_OFST)
#define CONTROL_CLR_ACQSTN_FIFO_OFST (15)
@ -457,8 +479,10 @@
#define POWER_HV_INTERNAL_SLCT_OFST (31)
#define POWER_HV_INTERNAL_SLCT_MSK (0x00000001 << POWER_HV_INTERNAL_SLCT_OFST)
/* Number of Words RW register TODO */
#define NUMBER_OF_WORDS_REG (0x5F << MEM_MAP_SHIFT)
/* Number of samples from transceiver RW register */
#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. */
#define DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT)
@ -477,14 +501,15 @@
#define PERIOD_MSB_REG (0x67 << MEM_MAP_SHIFT)
/* Period 64 bit RW register */
//#define EXPTIME_LSB_REG (0x68 << MEM_MAP_SHIFT) //
// Not used in FW #define EXPTIME_MSB_REG (0x69 <<
// MEM_MAP_SHIFT) // Not used in FW
// #define EXPTIME_LSB_REG (0x68 << MEM_MAP_SHIFT) //
// Not used in FW #define EXPTIME_MSB_REG (0x69 <<
// MEM_MAP_SHIFT) // Not used in FW
/* Gates 64 bit RW register */
//#define GATES_LSB_REG (0x6A << MEM_MAP_SHIFT) // Not used
// in FW #define GATES_MSB_REG (0x6B << MEM_MAP_SHIFT) //
// Not used in FW
// #define GATES_LSB_REG (0x6A << MEM_MAP_SHIFT) // Not
// used
// in FW #define GATES_MSB_REG (0x6B << MEM_MAP_SHIFT) //
// Not used in FW
/* Pattern IO Control 64 bit RW regiser
* Each bit configured as output(1)/ input(0) */
@ -516,10 +541,13 @@
/* Readout enable RW register */
#define READOUT_10G_ENABLE_REG (0x79 << MEM_MAP_SHIFT)
#define READOUT_10G_ENABLE_ANLG_OFST (0)
#define READOUT_10G_ENABLE_ANLG_MSK (0x000000FF << READOUT_10G_ENABLE_ANLG_OFST)
#define READOUT_10G_ENABLE_DGTL_OFST (8)
#define READOUT_10G_ENABLE_DGTL_MSK (0x00000001 << READOUT_10G_ENABLE_DGTL_OFST)
#define READOUT_10G_ENABLE_ANLG_OFST (0)
#define READOUT_10G_ENABLE_ANLG_MSK (0x000000FF << READOUT_10G_ENABLE_ANLG_OFST)
#define READOUT_10G_ENABLE_DGTL_OFST (8)
#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 */
#define DBIT_EXT_TRG_REG (0x7B << MEM_MAP_SHIFT)
@ -725,3 +753,5 @@
/* Round Robin */
#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 analogDataBytes = 0;
int digitalDataBytes = 0;
int transceiverDataBytes = 0;
char *analogData = 0;
char *digitalData = 0;
char *transceiverData = 0;
char volatile *analogDataPtr = 0;
char volatile *digitalDataPtr = 0;
char volatile *transceiverDataPtr = 0;
char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)];
uint32_t adcEnableMask_1g = BIT32_MSK;
// 10g readout
uint8_t adcEnableMask_10g = 0xFF;
uint32_t transceiverMask = DEFAULT_TRANSCEIVER_MASK;
int32_t clkPhase[NUM_CLOCKS] = {};
uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200};
@ -68,8 +71,10 @@ int vLimit = 0;
int highvoltage = 0;
int analogEnable = 1;
int digitalEnable = 0;
int transceiverEnable = 0;
int naSamples = 1;
int ndSamples = 1;
int ntSamples = 1;
int detPos[2] = {0, 0};
int isInitCheckDone() { return initCheckDone; }
@ -468,6 +473,7 @@ void setupDetector() {
dataBytes = 0;
analogDataBytes = 0;
digitalDataBytes = 0;
transceiverDataBytes = 0;
if (analogData) {
free(analogData);
analogData = 0;
@ -476,8 +482,13 @@ void setupDetector() {
free(digitalData);
digitalData = 0;
}
if (transceiverData) {
free(transceiverData);
transceiverData = 0;
}
analogDataPtr = 0;
digitalDataPtr = 0;
transceiverData = 0;
{
for (int i = 0; i < NUM_CLOCKS; ++i) {
clkPhase[i] = 0;
@ -493,10 +504,13 @@ void setupDetector() {
highvoltage = 0;
adcEnableMask_1g = BIT32_MSK;
adcEnableMask_10g = 0xFF;
transceiverMask = DEFAULT_TRANSCEIVER_MASK;
analogEnable = 1;
digitalEnable = 0;
transceiverEnable = 0;
naSamples = 1;
ndSamples = 1;
ntSamples = 1;
#ifdef VIRTUAL
sharedMemory_setStatus(IDLE);
initializePatternWord();
@ -575,6 +589,7 @@ void setupDetector() {
setNumAnalogSamples(DEFAULT_NUM_SAMPLES);
setNumDigitalSamples(
DEFAULT_NUM_SAMPLES); // update databytes and allocate ram
setNumTransceiverSamples(DEFAULT_NUM_SAMPLES);
setNumFrames(DEFAULT_NUM_FRAMES);
setExpTime(DEFAULT_EXPTIME);
setNumTriggers(DEFAULT_NUM_CYCLES);
@ -583,6 +598,8 @@ void setupDetector() {
setTiming(DEFAULT_TIMING_MODE);
setADCEnableMask(BIT32_MSK);
setADCEnableMask_10G(BIT32_MSK);
setTransceiverEnableMask(DEFAULT_TRANSCEIVER_MASK);
if (setReadoutMode(ANALOG_ONLY) == FAIL) {
strcpy(initErrorMessage,
"Could not set readout mode to analog only.\n");
@ -596,18 +613,22 @@ int updateDatabytesandAllocateRAM() {
int oldAnalogDataBytes = analogDataBytes;
int oldDigitalDataBytes = digitalDataBytes;
int oldTranceiverDataBytes = transceiverDataBytes;
updateDataBytes();
// update only if change in databytes
if (analogDataBytes == oldAnalogDataBytes &&
digitalDataBytes == oldDigitalDataBytes) {
LOG(logDEBUG1, ("RAM size (Analog:%d, Digital:%d) already allocated. "
"Nothing to be done.\n",
analogDataBytes, digitalDataBytes));
digitalDataBytes == oldDigitalDataBytes &&
transceiverDataBytes == oldTranceiverDataBytes) {
LOG(logDEBUG1,
("RAM size (Analog:%d, Digital:%d, Transceiver:%d) already "
"allocated. Nothing to be done.\n",
analogDataBytes, digitalDataBytes, transceiverDataBytes));
return OK;
}
// Zero databytes
if (analogDataBytes == 0 && digitalDataBytes == 0) {
if (analogDataBytes == 0 && digitalDataBytes == 0 &&
transceiverDataBytes == 0) {
LOG(logERROR, ("Can not allocate RAM for 0 bytes.\n"));
return FAIL;
}
@ -620,6 +641,10 @@ int updateDatabytesandAllocateRAM() {
free(digitalData);
digitalData = 0;
}
if (transceiverData) {
free(transceiverData);
transceiverData = 0;
}
// allocate RAM
if (analogDataBytes) {
analogData = malloc(analogDataBytes);
@ -640,16 +665,29 @@ int updateDatabytesandAllocateRAM() {
"Probable cause: Memory Leak.\n"));
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;
}
void updateDataBytes() {
int nachans = 0, ndchans = 0;
int nachans = 0, ndchans = 0, ntchans = 0;
analogDataBytes = 0;
digitalDataBytes = 0;
transceiverDataBytes = 0;
// analog
if (analogEnable) {
@ -672,10 +710,20 @@ void updateDataBytes() {
LOG(logINFO, ("\t#Digital Channels:%d, Databytes:%d\n", ndchans,
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
int nchans = nachans + ndchans;
dataBytes = analogDataBytes + digitalDataBytes;
int nchans = nachans + ndchans + ntchans;
dataBytes = analogDataBytes + digitalDataBytes + transceiverDataBytes;
LOG(logINFO,
("\t#Total Channels:%d, Total Databytes:%d\n", nchans, dataBytes));
@ -723,10 +771,6 @@ int getDynamicRange(int *retval) {
}
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));
adcEnableMask_1g = mask;
// 1Gb enabled
@ -792,6 +836,20 @@ uint32_t getADCEnableMask_10G() {
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) {
LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val));
bus_w(ADC_PORT_INVERT_REG, val);
@ -829,6 +887,7 @@ int setExternalSampling(int val) {
int setReadoutMode(enum readoutMode mode) {
analogEnable = 0;
digitalEnable = 0;
transceiverEnable = 0;
switch (mode) {
case ANALOG_ONLY:
LOG(logINFO, ("Setting Analog Only Readout\n"));
@ -843,6 +902,15 @@ int setReadoutMode(enum readoutMode mode) {
analogEnable = 1;
digitalEnable = 1;
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:
LOG(logERROR, ("Cannot set unknown readout flag. 0x%x\n", mode));
return FAIL;
@ -850,66 +918,90 @@ int setReadoutMode(enum readoutMode mode) {
uint32_t addr = CONFIG_REG;
uint32_t addr_readout_10g = READOUT_10G_ENABLE_REG;
// default: analog only
bus_w(addr, bus_r(addr) & (~CONFIG_DSBL_ANLG_OTPT_MSK) &
(~CONFIG_ENBLE_DGTL_OTPT_MSK));
bus_w(addr, (bus_r(addr) | CONFIG_DSBL_ANLG_OTPT_MSK) &
(~CONFIG_ENBLE_DGTL_OTPT_MSK) &
(~CONFIG_ENBLE_TRNSCVR_OTPT_MSK));
bus_w(addr_readout_10g, bus_r(addr_readout_10g) &
(~READOUT_10G_ENABLE_ANLG_MSK) &
~(READOUT_10G_ENABLE_DGTL_MSK));
bus_w(addr_readout_10g,
bus_r(addr_readout_10g) |
((adcEnableMask_10g << READOUT_10G_ENABLE_ANLG_OFST) &
READOUT_10G_ENABLE_ANLG_MSK));
// disable analog (digital only)
if (!analogEnable) {
bus_w(addr, bus_r(addr) | CONFIG_DSBL_ANLG_OTPT_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_r(addr_readout_10g) & (~READOUT_10G_ENABLE_ANLG_MSK));
bus_r(addr_readout_10g) |
((adcEnableMask_10g << READOUT_10G_ENABLE_ANLG_OFST) &
READOUT_10G_ENABLE_ANLG_MSK));
}
// enable digital (analog and digital)
if (digitalEnable) {
bus_w(addr, bus_r(addr) | CONFIG_ENBLE_DGTL_OTPT_MSK);
bus_w(addr_readout_10g,
bus_r(addr_readout_10g) | READOUT_10G_ENABLE_DGTL_MSK);
}
// 1Gb
if (!enableTenGigabitEthernet(-1)) {
if (updateDatabytesandAllocateRAM() == FAIL) {
return FAIL;
}
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));
}
// 10Gb
else {
// validate adcenablemask for 10g
if (analogEnable &&
adcEnableMask_10g != ((bus_r(READOUT_10G_ENABLE_REG) &
READOUT_10G_ENABLE_ANLG_MSK) >>
READOUT_10G_ENABLE_ANLG_OFST)) {
LOG(logERROR, ("Setting readout mode failed. Could not set 10g adc "
"enable mask to 0x%x\n.",
adcEnableMask_10g));
return FAIL;
if (isControlServer) {
// 1Gb
if (!enableTenGigabitEthernet(-1)) {
if (updateDatabytesandAllocateRAM() == FAIL) {
return FAIL;
}
}
// 10Gb
else {
// validate adcenablemask for 10g
if (analogEnable &&
adcEnableMask_10g != ((bus_r(READOUT_10G_ENABLE_REG) &
READOUT_10G_ENABLE_ANLG_MSK) >>
READOUT_10G_ENABLE_ANLG_OFST)) {
LOG(logERROR,
("Setting readout mode failed. Could not set 10g adc "
"enable mask to 0x%x\n.",
adcEnableMask_10g));
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;
}
int getReadoutMode() {
if (analogEnable && digitalEnable) {
if (analogEnable && digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Analog & Digita\n"));
return ANALOG_AND_DIGITAL;
} else if (analogEnable && !digitalEnable) {
} else if (analogEnable && !digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Analog Only\n"));
return ANALOG_ONLY;
} else if (!analogEnable && digitalEnable) {
} else if (!analogEnable && digitalEnable && !transceiverEnable) {
LOG(logDEBUG1, ("Getting readout: Digital Only\n"));
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 {
LOG(logERROR,
("Read unknown readout (Both digital and analog are disabled)\n"));
LOG(logERROR, ("Read unknown readout (analog enable:%d digital "
"enable:%d transceiver enable:%d)\n",
analogEnable, digitalEnable, transceiverEnable));
return -1;
}
}
@ -994,6 +1086,28 @@ int setNumDigitalSamples(int val) {
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) {
if (val < 0) {
LOG(logERROR, ("Invalid exptime: %lld ns\n", (long long int)val));
@ -2098,6 +2212,7 @@ int startStateMachine() {
LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
return OK;
#endif
int send_to_10g = enableTenGigabitEthernet(-1);
// 1 giga udp
if (send_to_10g == 0) {
@ -2124,6 +2239,38 @@ int startStateMachine() {
~CONTROL_STRT_EXPSR_MSK);
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;
}
@ -2188,6 +2335,7 @@ void *start_timer(void *arg) {
srcOffset += dataSize;
sendUDPPacket(0, 0, packetData, packetSize);
// LOG(logINFOBLUE, ("packetsize:%d\n", packetSize));
}
LOG(logINFO, ("Sent frame: %d [%lld]\n", iframes, frameNr + iframes));
clock_gettime(CLOCK_REALTIME, &end);
@ -2236,6 +2384,7 @@ int stopStateMachine() {
}
enum runStatus getRunStatus() {
LOG(logDEBUG1, ("Getting status\n"));
// scan error or running
if (sharedMemory_getScanStatus() == ERROR) {
@ -2291,6 +2440,7 @@ enum runStatus getRunStatus() {
// 1g might still be transmitting or reading from fifo (not virtual)
if (!enableTenGigabitEthernet(-1) && checkDataInFifo()) {
LOG(logINFOBLUE, ("Status: Transmitting (Data in Fifo)\n"));
return TRANSMITTING;
}
@ -2345,25 +2495,20 @@ void waitForAcquisitionEnd() {
void unsetFifoReadStrobes() {
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;
LOG(logDEBUG1, ("sample :%d\n", ns));
// read adcs
if (analogEnable && ns < naSamples) {
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)) {
LOG(logDEBUG1, ("Reading sample ns:%d of %d AEmtpy:0x%x AFull:0x%x "
"Status:0x%x\n",
@ -2384,6 +2529,11 @@ void readSample(int ns) {
bus_w(addr, bus_r(addr) | ((ich << DUMMY_FIFO_CHNNL_SLCT_OFST) &
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
*((uint16_t *)analogDataPtr) = bus_r16(fifoAddr);
@ -2395,21 +2545,22 @@ void readSample(int ns) {
// increment pointer to data out destination
analogDataPtr += 2;
sampleRead = 1;
}
}
}
// read digital output
if (digitalEnable && ns < ndSamples) {
// 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));
// 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)
;
}
// read digital output
if (digitalEnable && ns < ndSamples) {
// wait as it is connected directly to fifo running on a different clock
if (!(ns % 1000)) {
LOG(logDEBUG1,
("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) =
get64BitReg(FIFO_DIN_LSB_REG, FIFO_DIN_MSB_REG);
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 dataPresent = 0;
if (analogEnable) {
uint32_t analogFifoEmpty = bus_r(FIFO_EMPTY_REG);
uint32_t fifoEmtpy = bus_r(FIFO_EMPTY_REG);
LOG(logDEBUG1,
("Analog Fifo Empty (32 channels): 0x%08x\n", analogFifoEmpty));
dataPresent = (~analogFifoEmpty);
("Analog Fifo Empty (32 channels): 0x%08x\n", fifoEmtpy));
dataPresent = (~fifoEmtpy);
}
if (!dataPresent && digitalEnable) {
int digitalFifoEmpty =
int fifoEmtpy =
((bus_r(FIFO_DIN_STATUS_REG) & FIFO_DIN_STATUS_FIFO_EMPTY_MSK) >>
FIFO_DIN_STATUS_FIFO_EMPTY_OFST);
LOG(logINFO, ("Digital Fifo Empty: %d\n", digitalFifoEmpty));
dataPresent = (digitalFifoEmpty ? 0 : 1);
LOG(logDEBUG1, ("Digital Fifo Empty: %d\n", fifoEmtpy));
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;
}
// only called for starting of a new frame
int checkFifoForEndOfAcquisition() {
LOG(logDEBUG1, ("Check for end of acq\n"));
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
while (!dataPresent) {
// acquisition done
if (!runBusy()) {
LOG(logDEBUG1, ("Not running\n"));
// wait to be sure there is no data in fifo
usleep(WAIT_TME_US_FR_ACQDONE_REG);
@ -2484,18 +2725,35 @@ int readFrameFromFifo() {
int ns = 0;
// point the data pointer to the starting position of data
analogDataPtr = analogData;
memset(analogData, 0, analogDataBytes);
digitalDataPtr = digitalData;
memset(digitalData, 0, digitalDataBytes);
transceiverDataPtr = transceiverData;
memset(transceiverData, 0, transceiverDataBytes);
// no data for this frame
/*if (!checkDataInFifo()) {
return FAIL;
}*/
// for startacquistiion
if (checkFifoForEndOfAcquisition() == FAIL) {
return FAIL;
}
// 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) {
// 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++;
}
@ -2523,8 +2781,7 @@ int getTotalNumberOfChannels() {
}
void getNumberOfChannels(int *nchanx, int *nchany) {
int nachans = 0, ndchans = 0;
// analog channels (normal, analog/digital readout)
int nachans = 0, ndchans = 0, ntchans = 0;
if (analogEnable) {
uint32_t mask =
enableTenGigabitEthernet(-1) ? adcEnableMask_10g : adcEnableMask_1g;
@ -2539,12 +2796,19 @@ void getNumberOfChannels(int *nchanx, int *nchany) {
LOG(logDEBUG1, ("Analog Channels: %d\n", nachans));
}
// digital channels (digital, analog/digital readout)
if (digitalEnable) {
ndchans = 64;
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));
*nchany = 1;
}

View File

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

View File

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

View File

@ -315,3 +315,7 @@ int get_frontend_firmware_version(int);
int get_bit(int);
int set_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 digitalDataBytes;
extern int transceiverDataBytes;
extern char *analogData;
extern char *digitalData;
extern char *transceiverData;
int analogOffset = 0;
int digitalOffset = 0;
int transceiverOffset = 0;
uint32_t udpPacketNumber = 0;
uint64_t udpFrameNumber = 0;
@ -51,27 +54,30 @@ void createUDPPacketHeader(char *buffer, uint16_t id) {
// reset offset
analogOffset = 0;
digitalOffset = 0;
transceiverOffset = 0;
// reset frame number
udpFrameNumber = 0;
}
int fillUDPPacket(char *buffer) {
LOG(logDEBUG2,
("Analog (databytes:%d, offset:%d)\n Digital (databytes:%d "
"offset:%d)\n",
analogDataBytes, analogOffset, digitalDataBytes, digitalOffset));
LOG(logDEBUG2, ("Analog (databytes:%d, offset:%d)\n Digital (databytes:%d "
"offset:%d)\n\n Transceiver (databytes:%d offset:%d)\n",
analogDataBytes, analogOffset, digitalDataBytes,
digitalOffset, transceiverDataBytes, transceiverOffset));
// reached end of data for one frame
if (analogOffset >= analogDataBytes && digitalOffset >= digitalDataBytes) {
if (analogOffset >= analogDataBytes && digitalOffset >= digitalDataBytes &&
transceiverOffset >= transceiverDataBytes) {
// reset offset
analogOffset = 0;
digitalOffset = 0;
transceiverOffset = 0;
return 0;
}
sls_detector_header *header = (sls_detector_header *)(buffer);
// update frame number, starts at 1 (reset packet number)
if (analogOffset == 0 && digitalOffset == 0) {
if (analogOffset == 0 && digitalOffset == 0 && transceiverOffset == 0) {
++udpFrameNumber;
header->frameNumber = udpFrameNumber;
udpPacketNumber = -1;
@ -117,10 +123,28 @@ int fillUDPPacket(char *buffer) {
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
if (freeBytes) {
memset(buffer + sizeof(sls_detector_header) + analogBytes +
digitalBytes,
digitalBytes + transceiverBytes,
0, freeBytes);
LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", freeBytes,
(long long int)udpFrameNumber, udpPacketNumber));

View File

@ -478,7 +478,10 @@ void function_table() {
flist[F_GET_BIT] = &get_bit;
flist[F_SET_BIT] = &set_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
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
LOG(logERROR, ("The last detector function enum has reached its "
@ -1876,7 +1879,8 @@ int acquire(int blocking, int file_des) {
getNumAnalogSamples());
LOG(logERROR, (mess));
} else if ((getReadoutMode() == ANALOG_AND_DIGITAL ||
getReadoutMode() == DIGITAL_ONLY) &&
getReadoutMode() == DIGITAL_ONLY ||
getReadoutMode() == DIGITAL_AND_TRANSCEIVER) &&
(getNumDigitalSamples() <= 0)) {
ret = FAIL;
sprintf(mess,
@ -1884,6 +1888,16 @@ int acquire(int blocking, int file_des) {
"samples: %d.\n",
getNumDigitalSamples());
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
#endif
#ifdef EIGERD
@ -4275,28 +4289,19 @@ int set_adc_enable_mask(int file_des) {
#else
// only set
if (Server_VerifyLock() == OK) {
if (arg == 0u) {
ret = FAIL;
sprintf(mess,
"Not allowed to set adc mask of 0 due to data readout. \n");
ret = setADCEnableMask(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n", arg);
LOG(logERROR, (mess));
} else {
ret = setADCEnableMask(arg);
if (ret == FAIL) {
sprintf(mess, "Could not set 1Gb ADC Enable mask to 0x%x.\n",
arg);
LOG(logERROR, (mess));
} else {
uint32_t retval = getADCEnableMask();
if (arg != retval) {
ret = FAIL;
sprintf(
mess,
uint32_t retval = getADCEnableMask();
if (arg != retval) {
ret = FAIL;
sprintf(mess,
"Could not set 1Gb ADC Enable mask. Set 0x%x, but read "
"0x%x\n",
arg, retval);
LOG(logERROR, (mess));
}
LOG(logERROR, (mess));
}
}
}
@ -5662,6 +5667,8 @@ int set_readout_mode(int file_des) {
case ANALOG_ONLY:
case DIGITAL_ONLY:
case ANALOG_AND_DIGITAL:
case TRANSCEIVER_ONLY:
case DIGITAL_AND_TRANSCEIVER:
break;
default:
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)
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")));
#if !defined(CHIPTESTBOARDD) && !defined(JUNGFRAUD) && !defined(MOENCHD) && \
@ -5972,7 +5979,7 @@ int get_clock_phase(int file_des) {
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
if (ind < NUM_CLOCKS) {
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;
}
#endif
@ -7384,6 +7391,26 @@ int get_receiver_parameters(int file_des) {
if (n < 0)
return printSocketReadError();
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)
return printSocketReadError();
@ -8210,7 +8237,7 @@ int get_bursts_left(int file_des) {
int start_readout(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
#ifndef MYTHEN3D
#if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD)
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
@ -8241,6 +8268,25 @@ int start_readout(int file_des) {
#endif
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
@ -10401,34 +10447,138 @@ int get_bit(int file_des) {
int nBit = (int)args[1];
LOG(logDEBUG1, ("Getting bit %d of reg 0x%x\n", nBit, addr));
// only set
if (Server_VerifyLock() == OK) {
if (nBit < 0 || nBit > 31) {
ret = FAIL;
sprintf(
mess,
if (nBit < 0 || nBit > 31) {
ret = FAIL;
sprintf(mess,
"Could not get bit. Bit nr %d out of range. Must be 0-31\n",
nBit);
LOG(logERROR, (mess));
} else {
LOG(logERROR, (mess));
} else {
#ifdef EIGERD
ret = getBit(addr, nBit, &retval);
LOG(logDEBUG1, ("retval: %d\n", retval));
if (ret == FAIL) {
ret = getBit(addr, nBit, &retval);
LOG(logDEBUG1, ("retval: %d\n", retval));
if (ret == FAIL) {
sprintf(mess, "Could not get bit %d.\n", nBit);
LOG(logERROR, (mess));
}
#else
#ifdef GOTTHARDD
retval = readRegister16And32(addr);
uint32_t regval = readRegister16And32(addr);
#else
retval = readRegister(addr);
uint32_t regval = readRegister(addr);
#endif
LOG(logDEBUG1, ("retval: %d\n", retval));
if (retval & (1 << nBit)) {
ret = FAIL;
retval = (regval & (1 << nBit)) >> nBit;
LOG(logDEBUG1, ("regval: 0x%x bit value:0%d\n", regval, retval));
#endif
sprintf(mess, "Could not get bit %d.\n", nBit);
}
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;
sprintf(mess, "Invalid Transceiver Mask. Max: 0x%x\n",
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));
}
}
}
}
#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));
}

View File

@ -1647,6 +1647,13 @@ class Detector {
/** [CTB] If any of a consecutive 4 bits are enabled, the "
"complete 4 bits are enabled */
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 */
@ -1663,10 +1670,17 @@ class Detector {
/** [CTB] */
void setNumberOfDigitalSamples(int value, Positions pos = {});
/** [CTB] */
Result<int> getNumberOfTransceiverSamples(Positions pos = {}) const;
/** [CTB] */
void setNumberOfTransceiverSamples(int value, Positions pos = {});
/** [CTB] */
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 = {});

View File

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

View File

@ -1225,7 +1225,7 @@ class CmdProxy {
{"apulse", &CmdProxy::apulse},
{"dpulse", &CmdProxy::dpulse},
/* CTB/ Moench Specific */
/* CTB Specific */
{"samples", &CmdProxy::Samples},
{"asamples", &CmdProxy::asamples},
{"adcclk", &CmdProxy::adcclk},
@ -1235,9 +1235,9 @@ class CmdProxy {
{"v_limit", &CmdProxy::v_limit},
{"adcenable", &CmdProxy::adcenable},
{"adcenable10g", &CmdProxy::adcenable10g},
/* CTB Specific */
{"transceiverenable", &CmdProxy::transceiverenable},
{"dsamples", &CmdProxy::dsamples},
{"tsamples", &CmdProxy::tsamples},
{"romode", &CmdProxy::romode},
{"dbitclk", &CmdProxy::dbitclk},
{"adcvpp", &CmdProxy::AdcVpp},
@ -2435,18 +2435,26 @@ class CmdProxy {
"ADC channel. However, if any of a consecutive 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(
dsamples, getNumberOfDigitalSamples, setNumberOfDigitalSamples,
StringTo<int>,
"[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(
romode, getReadoutMode, setReadoutMode,
StringTo<slsDetectorDefs::readoutMode>,
"[analog|digital|analog_digital]\n\t[CTB] Readout mode. "
"Default is analog.");
"[analog|digital|analog_digital|transceiver|digital_transceiver]\n\t["
"CTB] Readout mode. Default is analog.");
INTEGER_COMMAND_VEC_ID(dbitclk, getDBITClock, setDBITClock, StringTo<int>,
"[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);
}
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
Result<int> Detector::getNumberOfDigitalSamples(Positions pos) const {
@ -2124,12 +2131,18 @@ void Detector::setNumberOfDigitalSamples(int value, Positions pos) {
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 {
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) {
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
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 {
return sendToDetector<readoutMode>(F_GET_READOUT_MODE);
}
@ -2408,6 +2433,7 @@ slsDetectorDefs::readoutMode Module::getReadoutMode() const {
void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
auto arg = static_cast<uint32_t>(mode); // TODO! unit?
sendToDetector(F_SET_READOUT_MODE, arg, nullptr);
sendToDetectorStop(F_SET_READOUT_MODE, arg, nullptr);
// update #nchan, as it depends on #samples, adcmask,
if (shm()->detType == CHIPTESTBOARD) {
updateNumberOfChannels();

View File

@ -504,8 +504,12 @@ class Module : public virtual slsDetectorDefs {
void setADCEnableMask(uint32_t mask);
uint32_t getTenGigaADCEnableMask() const;
void setTenGigaADCEnableMask(uint32_t mask);
uint32_t getTransceiverEnableMask() const;
void setTransceiverEnableMask(uint32_t mask);
int getNumberOfDigitalSamples() const;
void setNumberOfDigitalSamples(int value);
int getNumberOfTransceiverSamples() const;
void setNumberOfTransceiverSamples(int value);
readoutMode getReadoutMode() const;
void setReadoutMode(const readoutMode mode);
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 */
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]") {
Detector det;
CmdProxy proxy(&det);
@ -900,8 +960,10 @@ TEST_CASE("romode", "[.cmd]") {
auto prev_romode = det.getReadoutMode();
auto prev_asamples = det.getNumberOfAnalogSamples();
auto prev_dsamples = det.getNumberOfDigitalSamples();
auto prev_tsamples = det.getNumberOfTransceiverSamples();
det.setNumberOfAnalogSamples(5000);
det.setNumberOfDigitalSamples(5000);
det.setNumberOfTransceiverSamples(5000);
{
std::ostringstream oss;
proxy.Call("romode", {"digital"}, -1, PUT, oss);
@ -922,10 +984,21 @@ TEST_CASE("romode", "[.cmd]") {
proxy.Call("romode", {}, -1, GET, oss);
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) {
det.setReadoutMode(prev_romode[i], {i});
det.setNumberOfAnalogSamples(prev_asamples[i], {i});
det.setNumberOfDigitalSamples(prev_dsamples[i], {i});
det.setNumberOfTransceiverSamples(prev_tsamples[i], {i});
}
} else {
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_SET_RECEIVER_ROI] = &ClientInterface::set_receiver_roi;
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++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -370,9 +372,8 @@ int ClientInterface::setup_receiver(Interface &socket) {
if (detType == CHIPTESTBOARD) {
impl()->setNumberofAnalogSamples(arg.analogSamples);
}
if (detType == CHIPTESTBOARD) {
impl()->setNumberofDigitalSamples(arg.digitalSamples);
impl()->setNumberofTransceiverSamples(arg.transceiverSamples);
}
if (detType != MYTHEN3) {
impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs));
@ -410,6 +411,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
impl()->setReadoutMode(arg.roMode);
impl()->setADCEnableMask(arg.adcMask);
impl()->setTenGigaADCEnableMask(arg.adc10gMask);
impl()->setTransceiverEnableMask(arg.transceiverMask);
}
if (detType == GOTTHARD) {
impl()->setDetectorROI(arg.roi);
@ -1758,4 +1760,43 @@ int ClientInterface::set_receiver_roi_metadata(Interface &socket) {
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

View File

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

View File

@ -496,8 +496,10 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) {
/** ctb specific */
void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
int nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes();
int nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes();
int nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes();
// TODO! (Erik) Refactor and add tests
int ctbDigitalDataBytes = size - nAnalogDataBytes - ctbDbitOffset;
int ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset;
// no digital data
if (ctbDigitalDataBytes == 0) {
@ -506,11 +508,15 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
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((numSamples * ctbDbitList.size()) / 8.00);
std::vector<uint8_t> result(numResult8Bits);
// const int numResult8Bits = ceil((numDigitalSamples * ctbDbitList.size())
// / 8.00);
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];
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
int bitoffset = 0;
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) {
bitoffset = 0;
++dest;
}
// 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
uint8_t bit = (*ptr++ >> bi) & 1;
*dest |= bit << bitoffset;
@ -540,8 +546,14 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) {
// copy back to memory and update size
memcpy(data + nAnalogDataBytes, result.data(),
numResult8Bits * sizeof(uint8_t));
size = numResult8Bits * sizeof(uint8_t) + nAnalogDataBytes + ctbDbitOffset;
totalNumBytes * sizeof(uint8_t));
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) {

View File

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

View File

@ -946,7 +946,8 @@ void Implementation::StartMasterWriter() {
masterAttributes.analogSamples = generalData->nAnalogSamples;
masterAttributes.digital =
(generalData->readoutType == DIGITAL_ONLY ||
generalData->readoutType == ANALOG_AND_DIGITAL)
generalData->readoutType == ANALOG_AND_DIGITAL ||
generalData->readoutType == DIGITAL_AND_TRANSCEIVER)
? 1
: 0;
masterAttributes.digitalSamples = generalData->nDigitalSamples;
@ -955,6 +956,14 @@ void Implementation::StartMasterWriter() {
for (auto &i : ctbDbitList) {
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.counterMask = generalData->counterMask;
masterAttributes.exptimeArray[0] = acquisitionTime1;
@ -1509,6 +1518,20 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) {
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 {
return generalData->counterMask;
}
@ -1718,6 +1741,20 @@ void Implementation::setDbitOffset(const int s) {
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 *

View File

@ -108,17 +108,17 @@ class Implementation : private virtual slsDetectorDefs {
* *
* ************************************************/
int getNumberofUDPInterfaces() const;
/* [Jungfrau] */
/* [Jungfrau][Moench] */
void setNumberofUDPInterfaces(const int n);
std::string getEthernetInterface() const;
void setEthernetInterface(const std::string &c);
std::string getEthernetInterface2() const;
/* [Jungfrau] */
/* [Jungfrau][Moench] */
void setEthernetInterface2(const std::string &c);
uint32_t getUDPPortNumber() const;
void setUDPPortNumber(const uint32_t i);
uint32_t getUDPPortNumber2() const;
/* [Eiger][Jungfrau] */
/* [Eiger][Jungfrau][Moench] */
void setUDPPortNumber2(const uint32_t i);
int getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int s);
@ -198,11 +198,14 @@ class Implementation : private virtual slsDetectorDefs {
/* [Eiger] */
void setSubPeriod(const ns i);
uint32_t getNumberofAnalogSamples() const;
/**[Ctb][Moench] */
/**[Ctb] */
void setNumberofAnalogSamples(const uint32_t i);
uint32_t getNumberofDigitalSamples() const;
/**[Ctb] */
void setNumberofDigitalSamples(const uint32_t i);
uint32_t getNumberofTransceiverSamples() const;
/**[Ctb] */
void setNumberofTransceiverSamples(const uint32_t i);
uint32_t getCounterMask() const;
/** [Mythen3] */
void setCounterMask(const uint32_t i);
@ -230,7 +233,7 @@ class Implementation : private virtual slsDetectorDefs {
* detector) */
void setDetectorDataStream(const portPosition port, const bool enable);
int getReadNRows() const;
/* [Eiger][Jungfrau] */
/* [Eiger][Jungfrau][Moench] */
void setReadNRows(const int value);
/** [Eiger] */
void setThresholdEnergy(const int value);
@ -241,10 +244,10 @@ class Implementation : private virtual slsDetectorDefs {
/* [Ctb] */
void setReadoutMode(const readoutMode f);
uint32_t getADCEnableMask() const;
/* [Ctb][Moench] */
/* [Ctb] */
void setADCEnableMask(const uint32_t mask);
uint32_t getTenGigaADCEnableMask() const;
/* [Ctb][Moench] */
/* [Ctb] */
void setTenGigaADCEnableMask(const uint32_t mask);
std::vector<int> getDbitList() const;
/* [Ctb] */
@ -252,6 +255,9 @@ class Implementation : private virtual slsDetectorDefs {
int getDbitOffset() const;
/* [Ctb] */
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);
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
void MasterAttributes::GetGotthardBinaryAttributes(
@ -763,6 +787,12 @@ void MasterAttributes::GetCtbBinaryAttributes(
w->Uint(dbitoffset);
w->Key("Dbit Bitset");
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
@ -778,6 +808,9 @@ void MasterAttributes::WriteCtbHDF5Attributes(H5::H5File *fd,
MasterAttributes::WriteHDF5DigitalSamples(fd, group);
MasterAttributes::WriteHDF5DbitOffset(fd, group);
MasterAttributes::WriteHDF5DbitList(fd, group);
MasterAttributes::WriteHDF5TransceiverMask(fd, group);
MasterAttributes::WriteHDF5TransceiverFlag(fd, group);
MasterAttributes::WriteHDF5TransceiverSamples(fd, group);
}
#endif

View File

@ -53,6 +53,9 @@ class MasterAttributes {
uint32_t digitalSamples{0};
uint32_t dbitoffset{0};
uint64_t dbitlist{0};
uint32_t transceiverMask{0};
uint32_t transceiver{0};
uint32_t transceiverSamples{0};
slsDetectorDefs::ROI detectorRoi{};
slsDetectorDefs::ROI receiverRoi{};
uint32_t counterMask{0};
@ -103,6 +106,9 @@ class MasterAttributes {
void WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group);
void WriteHDF5DbitOffset(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
void GetGotthardBinaryAttributes(

View File

@ -406,7 +406,13 @@ typedef struct {
/**
* 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 */
enum speedLevel {
@ -588,6 +594,8 @@ enum streamingInterface {
int64_t gateDelay3Ns{0};
int gates{0};
scanParameters scanParams{};
int transceiverSamples{0};
uint32_t transceiverMask{0};
} __attribute__((packed));
#endif

View File

@ -282,6 +282,10 @@ enum detFuncs {
F_CLEAR_BIT,
F_GET_PATTERN_IO_CONTROL,
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,
RECEIVER_ENUM_START = 512, /**< detector function should not exceed this
@ -389,6 +393,8 @@ enum detFuncs {
F_RECEIVER_GET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI,
F_RECEIVER_SET_RECEIVER_ROI_METADATA,
F_RECEIVER_SET_NUM_TRANSCEIVER_SAMPLES,
F_RECEIVER_SET_TRANSCEIVER_MASK,
NUM_REC_FUNCTIONS
};
@ -667,7 +673,10 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_CLEAR_BIT: return "F_CLEAR_BIT";
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_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 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_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_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";
default: return "Unknown Function";

View File

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

View File

@ -87,6 +87,8 @@ std::string ToString(const slsDetectorDefs::rxParameters &r) {
<< std::endl
<< "gates:" << r.gates << std::endl
<< "scanParams:" << ToString(r.scanParams) << std::endl
<< "transceiverSamples:" << r.transceiverSamples << std::endl
<< "transceiverMask:" << r.transceiverMask << std::endl
<< ']';
return oss.str();
}
@ -325,6 +327,10 @@ std::string ToString(const defs::readoutMode s) {
return std::string("digital");
case defs::ANALOG_AND_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:
return std::string("Unknown");
}
@ -789,6 +795,10 @@ template <> defs::readoutMode StringTo(const std::string &s) {
return defs::DIGITAL_ONLY;
if (s == "analog_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);
}