From 2f3b0e0b06df914c994e665bf3460ac5564ded8f Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 30 Apr 2019 18:55:32 +0200 Subject: [PATCH] ctb:separated analog and digital samples in server and send analog and digital data packed separately per frame to reciever --- .../ctbDetectorServer/RegisterDefs.h | 5 + .../slsDetectorFunctionList.c | 178 ++++++++++------ .../slsDetectorServer_defs.h | 2 +- .../slsDetectorFunctionList.c | 17 +- .../UDPPacketHeaderGenerator.h | 75 ++++--- .../slsDetectorFunctionList.h | 1 - .../slsDetectorServer_funcs.c | 23 +- slsDetectorSoftware/src/multiSlsDetector.cpp | 7 +- slsDetectorSoftware/src/slsDetector.cpp | 88 ++++---- .../src/slsDetectorCommand.cpp | 66 +++++- slsReceiverSoftware/include/GeneralData.h | 199 ++++++++---------- .../include/slsReceiverImplementation.h | 31 ++- .../src/slsReceiverImplementation.cpp | 54 +++-- .../src/slsReceiverTCPIPInterface.cpp | 26 ++- slsReceiverSoftware/tests/CMakeLists.txt | 2 +- slsSupportLib/include/sls_detector_defs.h | 13 +- slsSupportLib/include/versionAPI.h | 2 +- 17 files changed, 489 insertions(+), 300 deletions(-) diff --git a/slsDetectorServers/ctbDetectorServer/RegisterDefs.h b/slsDetectorServers/ctbDetectorServer/RegisterDefs.h index f14f02e6d..bf3dae964 100755 --- a/slsDetectorServers/ctbDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/ctbDetectorServer/RegisterDefs.h @@ -429,6 +429,11 @@ /* Samples RW register */ #define SAMPLES_REG (0x5D << MEM_MAP_SHIFT) +#define SAMPLES_DIGITAL_OFST (0) +#define SAMPLES_DIGITAL_MSK (0x0000FFFF << SAMPLES_DIGITAL_OFST) +#define SAMPLES_ANALOG_OFST (16) +#define SAMPLES_ANALOG_MSK (0x0000FFFF << SAMPLES_ANALOG_OFST) + /** Power RW register */ #define POWER_REG (0x5E << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 48f9ee7b0..a71a11d96 100755 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -39,7 +39,13 @@ int virtual_stop = 0; #endif int dataBytes = 0; -char* ramValues = 0; +int analogDataBytes = 0; +int digitalDataBytes = 0; +char* analogData = 0; +char* digitalData = 0; +char volatile *analogDataPtr = 0; +char volatile *digitalDataPtr = 0; + char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)]; int32_t clkPhase[NUM_CLOCKS] = {0, 0, 0, 0}; @@ -53,8 +59,9 @@ int highvoltage = 0; uint32_t adcEnableMask = 0; int analogEnable = 1; int digitalEnable = 0; -int nSamples = 1; -char volatile *now_ptr = 0; +int naSamples = 1; +int ndSamples = 1; + int isFirmwareCheckDone() { return firmware_check_done; @@ -454,10 +461,18 @@ void setupDetector() { // default variables dataBytes = 0; - if (ramValues) { - free(ramValues); - ramValues = 0; + analogDataBytes = 0; + digitalDataBytes = 0; + if (analogData) { + free(analogData); + analogData = 0; } + if (digitalData) { + free(digitalData); + digitalData = 0; + } + analogDataPtr = 0; + digitalDataPtr = 0; { int i = 0; for (i = 0; i < NUM_CLOCKS; ++i) { @@ -475,8 +490,8 @@ void setupDetector() { adcEnableMask = BIT_32_MSK; analogEnable = 1; digitalEnable = 0; - nSamples = 1; - now_ptr = 0; + naSamples = 1; + ndSamples = 1; ALTERA_PLL_ResetPLLAndReconfiguration(); @@ -538,7 +553,8 @@ void setupDetector() { enableTenGigabitEthernet(0); //Initialization of acquistion parameters - setTimer(SAMPLES, DEFAULT_NUM_SAMPLES); // update databytes and allocate ram + setTimer(ANALOG_SAMPLES, DEFAULT_NUM_SAMPLES); + setTimer(DIGITAL_SAMPLES, DEFAULT_NUM_SAMPLES); // update databytes and allocate ram setTimer(FRAME_NUMBER, DEFAULT_NUM_FRAMES); setTimer(ACQUISITION_TIME, DEFAULT_EXPTIME); setTimer(CYCLES_NUMBER, DEFAULT_NUM_CYCLES); @@ -552,7 +568,8 @@ void setupDetector() { } int allocateRAM() { - int oldDataBytes = dataBytes; + int oldAnalogDataBytes = analogDataBytes; + int oldDigitalDataBytes = digitalDataBytes; updateDataBytes(); // only allcoate RAM for 1 giga udp (if 10G, return) @@ -561,59 +578,82 @@ int allocateRAM() { // update only if change in databytes - if (dataBytes == oldDataBytes) { - FILE_LOG(logDEBUG1, ("RAM of size %d already allocated. Nothing to be done.\n", dataBytes)); + if (analogDataBytes == oldAnalogDataBytes && digitalDataBytes == oldDigitalDataBytes) { + FILE_LOG(logDEBUG1, ("RAM size (Analog:%d, Digital:%d) already allocated. Nothing to be done.\n", + analogDataBytes, digitalDataBytes)); return OK; } // Zero databytes - if (dataBytes <= 0) { - FILE_LOG(logERROR, ("Can not allocate RAM for 0 bytes (databytes: 0).\n")); + if (analogDataBytes == 0 && digitalDataBytes == 0) { + FILE_LOG(logERROR, ("Can not allocate RAM for 0 bytes.\n")); return FAIL; } // clear RAM - if (ramValues) { - free(ramValues); - ramValues = 0; - } + if (analogData) { + free(analogData); + analogData = 0; + } + if (digitalData) { + free(digitalData); + digitalData = 0; + } // allocate RAM - ramValues = malloc(dataBytes); - // cannot malloc - if (ramValues == NULL) { - FILE_LOG(logERROR, ("Can not allocate RAM for even 1 frame. " - "Probably cause: Memory Leak.\n")); - return FAIL; - } + if (analogDataBytes) { + analogData = malloc(analogDataBytes); + // cannot malloc + if (analogData == NULL) { + FILE_LOG(logERROR, ("Can not allocate analog data RAM for even 1 frame. " + "Probable cause: Memory Leak.\n")); + return FAIL; + } + FILE_LOG(logINFO, ("\tAnalog RAM allocated to %d bytes\n", analogDataBytes)); + } + if (digitalDataBytes) { + digitalData = malloc(digitalDataBytes); + // cannot malloc + if (digitalData == NULL) { + FILE_LOG(logERROR, ("Can not allocate digital data RAM for even 1 frame. " + "Probable cause: Memory Leak.\n")); + return FAIL; + } + } - FILE_LOG(logINFO, ("\tRAM allocated to %d bytes\n", dataBytes)); + + FILE_LOG(logINFO, ("\tDigital RAM allocated to %d bytes\n", digitalDataBytes)); return OK; } void updateDataBytes() { - int oldDataBytes = dataBytes; - dataBytes = NCHIP * getChannels() * NUM_BYTES_PER_PIXEL * nSamples; - if (dataBytes != oldDataBytes) { - FILE_LOG(logINFO, ("\tUpdating Databytes: %d\n", dataBytes)); - } -} - -int getChannels() { - int nchans = 0; + int nachans = 0, ndchans = 0; + analogDataBytes = 0; + digitalDataBytes = 0; + // analog if (analogEnable) { if (adcEnableMask == BIT_32_MSK) - nchans = 32; + nachans = 32; else { int ichan = 0; for (ichan = 0; ichan < NCHAN_ANALOG; ++ichan) { if (adcEnableMask & (1 << ichan)) - ++nchans; + ++nachans; } } + analogDataBytes = nachans * (DYNAMIC_RANGE / 8) * naSamples; + FILE_LOG(logINFO, ("\t#Analog Channels:%d, Databytes:%d\n", nachans, analogDataBytes)); } - if (digitalEnable) - nchans += NCHAN_DIGITAL; - FILE_LOG(logINFO, ("\tNumber of Channels calculated: %d\n", nchans)) - return nchans; + // digital + if (digitalEnable) { + ndchans = NCHAN_DIGITAL; + digitalDataBytes = (sizeof(uint64_t) * ndSamples); + FILE_LOG(logINFO, ("\t#Digital Channels:%d, Databytes:%d\n", ndchans, digitalDataBytes)); + } + + // total + int nchans = nachans + ndchans; + dataBytes = analogDataBytes + digitalDataBytes; + + FILE_LOG(logINFO, ("\t#Total Channels:%d, Total Databytes:%d\n", nchans, dataBytes)); } @@ -845,17 +885,33 @@ int64_t setTimer(enum timerIndex ind, int64_t val) { FILE_LOG(logINFO, ("\tGetting #cycles: %lld\n", (long long int)retval)); break; - case SAMPLES: + case ANALOG_SAMPLES: if(val >= 0) { - FILE_LOG(logINFO, ("Setting #samples: %lld\n", (long long int)val)); - nSamples = val; - bus_w(SAMPLES_REG, val); + FILE_LOG(logINFO, ("Setting #analog samples: %lld\n", (long long int)val)); + naSamples = val; + bus_w(SAMPLES_REG, bus_r(SAMPLES_REG) &~ SAMPLES_ANALOG_MSK); + bus_w(SAMPLES_REG, bus_r(SAMPLES_REG) | ((val << SAMPLES_ANALOG_OFST) & SAMPLES_ANALOG_MSK)); if (allocateRAM() == FAIL) { return -1; } } - retval = nSamples; - FILE_LOG(logINFO, ("\tGetting #samples: %lld\n", (long long int)retval)); + retval = naSamples; + FILE_LOG(logINFO, ("\tGetting #analog samples: %lld\n", (long long int)retval)); + break; + + case DIGITAL_SAMPLES: + if(val >= 0) { + FILE_LOG(logINFO, ("Setting #digital samples: %lld\n", (long long int)val)); + ndSamples = val; + bus_w(SAMPLES_REG, bus_r(SAMPLES_REG) &~ SAMPLES_DIGITAL_MSK); + bus_w(SAMPLES_REG, bus_r(SAMPLES_REG) | ((val << SAMPLES_DIGITAL_OFST) & SAMPLES_DIGITAL_MSK)); + + if (allocateRAM() == FAIL) { + return -1; + } + } + retval = ndSamples; + FILE_LOG(logINFO, ("\tGetting #digital samples: %lld\n", (long long int)retval)); break; default: @@ -2242,7 +2298,7 @@ void readSample(int ns) { uint32_t addr = DUMMY_REG; // read adcs - if (analogEnable) { + if (analogEnable && ns < naSamples) { uint32_t fifoAddr = FIFO_DATA_REG; @@ -2259,7 +2315,7 @@ void readSample(int ns) { if (!(ns%1000)) { FILE_LOG(logDEBUG1, ("Reading sample ns:%d of %d AEmtpy:0x%x AFull:0x%x Status:0x%x\n", - ns, nSamples, bus_r(FIFO_EMPTY_REG), bus_r(FIFO_FULL_REG), bus_r(STATUS_REG))); + ns, naSamples, bus_r(FIFO_EMPTY_REG), bus_r(FIFO_FULL_REG), bus_r(STATUS_REG))); } // loop through all channels @@ -2276,22 +2332,22 @@ void readSample(int ns) { bus_w(addr, bus_r(addr) | ((ich << DUMMY_FIFO_CHNNL_SLCT_OFST) & DUMMY_FIFO_CHNNL_SLCT_MSK)); // read fifo and write it to current position of data pointer - *((uint16_t*)now_ptr) = bus_r16(fifoAddr); + *((uint16_t*)analogDataPtr) = bus_r16(fifoAddr); // keep reading till the value is the same - /* while (*((uint16_t*)now_ptr) != bus_r16(fifoAddr)) { + /* while (*((uint16_t*)analogDataPtr) != bus_r16(fifoAddr)) { FILE_LOG(logDEBUG1, ("%d ", ich)); - *((uint16_t*)now_ptr) = bus_r16(fifoAddr); + *((uint16_t*)analogDataPtr) = bus_r16(fifoAddr); }*/ // increment pointer to data out destination - now_ptr += 2; + analogDataPtr += 2; } } } // read digital output - if (digitalEnable) { + 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)); @@ -2306,15 +2362,15 @@ void readSample(int ns) { // wait as it is connected directly to fifo running on a different clock if (!(ns%1000)) { FILE_LOG(logDEBUG1, ("Reading sample ns:%d of %d DEmtpy:%d DFull:%d Status:0x%x\n", - ns, nSamples, + ns, ndSamples, ((bus_r(FIFO_DIN_STATUS_REG) & FIFO_DIN_STATUS_FIFO_EMPTY_MSK) >> FIFO_DIN_STATUS_FIFO_EMPTY_OFST), ((bus_r(FIFO_DIN_STATUS_REG) & FIFO_DIN_STATUS_FIFO_FULL_MSK) >> FIFO_DIN_STATUS_FIFO_FULL_OFST), bus_r(STATUS_REG))); } // read fifo and write it to current position of data pointer - *((uint64_t*)now_ptr) = get64BitReg(FIFO_DIN_LSB_REG, FIFO_DIN_MSB_REG); - now_ptr += 8; + *((uint64_t*)digitalDataPtr) = get64BitReg(FIFO_DIN_LSB_REG, FIFO_DIN_MSB_REG); + digitalDataPtr += 8; } } @@ -2334,7 +2390,7 @@ uint32_t checkDataInFifo() { return dataPresent; } -// only called for first sample +// only called for starting of a new frame int checkFifoForEndOfAcquisition() { uint32_t dataPresent = checkDataInFifo(); FILE_LOG(logDEBUG2, ("status:0x%x\n", bus_r(STATUS_REG))); @@ -2367,7 +2423,8 @@ int checkFifoForEndOfAcquisition() { int readFrameFromFifo() { int ns = 0; // point the data pointer to the starting position of data - now_ptr = ramValues; + analogDataPtr = analogData; + digitalDataPtr = digitalData; // no data for this frame if (checkFifoForEndOfAcquisition() == FAIL) { @@ -2375,7 +2432,8 @@ int readFrameFromFifo() { } // read Sample - while(ns < nSamples) { + int maxSamples = (naSamples > ndSamples) ? naSamples : ndSamples; + while(ns < maxSamples) { // chceck if no data in fifo, return ns?//FIXME: ask Anna readSample(ns); ns++; diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h index 71428a242..758dfb2c1 100755 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h @@ -32,7 +32,7 @@ enum DACINDEX {D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, /* Hardware Definitions */ #define NCHAN (36) #define NCHAN_ANALOG (32) -#define NCHAN_DIGITAL (4) +#define NCHAN_DIGITAL (64) #define NCHIP (1) #define NDAC (24) #define NPWR (6) diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 0a87846d6..b55a77983 100755 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -574,27 +574,12 @@ int allocateRAM() { void updateDataBytes() { int oldDataBytes = dataBytes; - dataBytes = NCHIP * getChannels() * NUM_BYTES_PER_PIXEL * nSamples; + dataBytes = NCHIP * NUM_BYTES_PER_PIXEL * nSamples; if (dataBytes != oldDataBytes) { FILE_LOG(logINFO, ("\tUpdating Databytes: %d\n", dataBytes)); } } -int getChannels() { - int nchans = 0; - - nchans += NCHAN; - // remove the channels disabled - int ichan = 0; - for (ichan = 0; ichan < NCHAN; ++ichan) { - if (adcDisableMask & (1 << ichan)) - --nchans; - } - - FILE_LOG(logINFO, ("\tNumber of Channels calculated: %d\n", nchans)) - return nchans; -} - /* firmware functions (resets) */ diff --git a/slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h b/slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h index 9b6b0123f..9350d4bd6 100755 --- a/slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h +++ b/slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h @@ -15,22 +15,20 @@ #include #include -extern const enum detectorType myDetectorType; -extern int nSamples; -extern int dataBytes; -extern int nframes; -extern char* ramValues; - #define UDP_PACKET_HEADER_VERSION (0x1) +extern const enum detectorType myDetectorType; +extern int analogDataBytes; +extern int digitalDataBytes; +extern char* analogData; +extern char* digitalData; + +int analogOffset = 0; +int digitalOffset = 0; uint32_t udpPacketNumber = 0; uint64_t udpFrameNumber = 0; -int numSamplesPerPacket = 0; -int dataBytesPerSample = 0; -int dataBytesPerPacket = 0; -int udpHeaderOffset = 0; uint32_t getUDPPacketNumber() { return udpPacketNumber; @@ -56,25 +54,28 @@ void createUDPPacketHeader(char* buffer, uint16_t id) { header->version = UDP_PACKET_HEADER_VERSION; // reset offset - udpHeaderOffset = 0; + analogOffset = 0; + digitalOffset = 0; // reset frame number udpFrameNumber = 0; } int fillUDPPacket(char* buffer) { - FILE_LOG(logDEBUG2, ("Databytes:%d offset:%d\n", dataBytes, udpHeaderOffset)); + FILE_LOG(logDEBUG2, ("Analog (databytes:%d, offset:%d)\n Digital (databytes:%d offset:%d)\n", + analogDataBytes, analogOffset, digitalDataBytes, digitalOffset)); // reached end of data for one frame - if (udpHeaderOffset >= dataBytes) { + if (analogOffset >= analogDataBytes && digitalOffset >= digitalDataBytes) { // reset offset - udpHeaderOffset = 0; + analogOffset = 0; + digitalOffset = 0; return 0; } sls_detector_header* header = (sls_detector_header*)(buffer); // update frame number, starts at 1 (reset packet number) - if (udpHeaderOffset == 0) { + if (analogOffset == 0 && digitalOffset == 0) { ++udpFrameNumber; header->frameNumber = udpFrameNumber; udpPacketNumber = -1; @@ -85,21 +86,41 @@ int fillUDPPacket(char* buffer) { header->packetNumber = udpPacketNumber; FILE_LOG(logDEBUG2, ("Creating packet number %d (fnum:%lld)\n", udpPacketNumber, (long long int) udpFrameNumber)); - // calculate number of bytes to copy - int numBytesToCopy = ((udpHeaderOffset + UDP_PACKET_DATA_BYTES) <= dataBytes) ? - UDP_PACKET_DATA_BYTES : (dataBytes - udpHeaderOffset); + int freeBytes = UDP_PACKET_DATA_BYTES; - // copy data - memcpy(buffer + sizeof(sls_detector_header), ramValues + udpHeaderOffset, numBytesToCopy); - // pad last packet if extra space - if (numBytesToCopy < UDP_PACKET_DATA_BYTES) { - int bytes = UDP_PACKET_DATA_BYTES - numBytesToCopy; - FILE_LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", bytes, (long long int)udpFrameNumber, udpPacketNumber)); - memset(buffer + sizeof(sls_detector_header) + numBytesToCopy, 0, bytes); + // analog data + int analogBytes = 0; + if (analogOffset < analogDataBytes) { + // bytes to copy + analogBytes = ((analogOffset + freeBytes) <= analogDataBytes) ? + freeBytes : (analogDataBytes - analogOffset); + // copy + memcpy(buffer + sizeof(sls_detector_header), analogData + analogOffset, analogBytes); + // increment offset + analogOffset += analogBytes; + // decrement free bytes + freeBytes -= analogBytes; } - // increment offset - udpHeaderOffset += numBytesToCopy; + // digital data + int digitalBytes = 0; + if (freeBytes && digitalOffset < digitalDataBytes) { + // bytes to copy + digitalBytes = ((digitalOffset + freeBytes) <= digitalDataBytes) ? + freeBytes : (digitalDataBytes - digitalOffset); + // copy + memcpy(buffer + sizeof(sls_detector_header) + analogBytes, digitalData + digitalOffset, digitalBytes); + // increment offset + digitalOffset += digitalBytes; + // decrement free bytes + freeBytes -= digitalBytes; + } + + // pad data + if (freeBytes) { + memset(buffer + sizeof(sls_detector_header) + analogBytes + digitalBytes, 0, freeBytes); + FILE_LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", freeBytes, (long long int)udpFrameNumber, udpPacketNumber)); + } return UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header); } diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h index 1cbf5d67e..ba4ae9da8 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h @@ -61,7 +61,6 @@ void setupDetector(); #if defined(CHIPTESTBOARDD) || defined(MOENCHD) int allocateRAM(); void updateDataBytes(); -int getChannels(); #endif #if defined(GOTTHARDD) || defined(JUNGFRAUD) diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c index 8fea08fa6..3bdcd7f77 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c @@ -124,7 +124,8 @@ const char* getTimerName(enum timerIndex ind) { case MEASUREMENTS_NUMBER: return "measurements_number"; case FRAMES_FROM_START: return "frames_from_start"; case FRAMES_FROM_START_PG: return "frames_from_start_pg"; - case SAMPLES: return "samples"; + case ANALOG_SAMPLES: return "analog_samples"; + case DIGITAL_SAMPLES: return "digital_samples"; case SUBFRAME_ACQUISITION_TIME: return "subframe_acquisition_time"; case SUBFRAME_DEADTIME: return "subframe_deadtime"; case STORAGE_CELL_NUMBER: return "storage_cell_number"; @@ -1581,7 +1582,8 @@ int set_timer(int file_des) { case FRAME_PERIOD: case CYCLES_NUMBER: #if defined(CHIPTESTBOARDD) || defined(MOENCHD) - case SAMPLES: + case ANALOG_SAMPLES: + case DIGITAL_SAMPLES: #endif #ifndef EIGERD case DELAY_AFTER_TRIGGER: @@ -1652,12 +1654,13 @@ int set_timer(int file_des) { case STORAGE_CELL_NUMBER: validate64(tns, retval, vtimerName, DEC); // no conversion, so all good break; - case SAMPLES: + case ANALOG_SAMPLES: + case DIGITAL_SAMPLES: if (retval == -1) { ret = FAIL; retval = setTimer(ind, -1); - sprintf(mess, "Could not set samples to %lld. Could not allocate RAM\n", - (long long unsigned int)tns); + sprintf(mess, "Could not %s to %lld. Could not allocate RAM\n", + vtimerName, (long long unsigned int)tns); FILE_LOG(logERROR,(mess)); } else validate64(tns, retval, vtimerName, DEC); // no conversion, so all good @@ -2258,12 +2261,18 @@ int send_update(int file_des) { } #endif - // #samples, adcmask #if defined(CHIPTESTBOARDD) || defined(MOENCHD) - i64 = setTimer(SAMPLES,GET_FLAG); + // #analog samples + i64 = setTimer(ANALOG_SAMPLES,GET_FLAG); n = sendData(file_des,&i64,sizeof(i64),INT64); if (n < 0) return printSocketReadError(); + // #digital samples + i64 = setTimer(DIGITAL_SAMPLES,GET_FLAG); + n = sendData(file_des,&i64,sizeof(i64),INT64); + if (n < 0) return printSocketReadError(); + + // adcmask i32 = getADCEnableMask(); n = sendData(file_des,&i32,sizeof(i32),INT32); if (n < 0) return printSocketReadError(); diff --git a/slsDetectorSoftware/src/multiSlsDetector.cpp b/slsDetectorSoftware/src/multiSlsDetector.cpp index c1d5696e1..9598deb72 100755 --- a/slsDetectorSoftware/src/multiSlsDetector.cpp +++ b/slsDetectorSoftware/src/multiSlsDetector.cpp @@ -284,7 +284,8 @@ void multiSlsDetector::initSharedMemory(bool verify) { << ") version mismatch " "(expected 0x" << std::hex << MULTI_SHMVERSION << " but got 0x" - << multi_shm()->shmversion << std::dec; + << multi_shm()->shmversion << std::dec + << ". Clear Shared memory to continue."; throw SharedMemoryError("Shared memory version mismatch!"); } } @@ -1080,10 +1081,6 @@ int64_t multiSlsDetector::setTimer(timerIndex index, int64_t t, int detPos) { auto r = parallelCall(&slsDetector::setTimer, index, t); int64_t ret = sls::minusOneIfDifferent(r); - if (index == SAMPLES) { - setDynamicRange(); - } - // set progress if (t != -1) { switch (index) { diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index 1a72084b6..a1cbb2060 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -281,7 +281,7 @@ void slsDetector::initSharedMemory(detectorType type, int multi_id, ss << "Single shared memory (" << multi_id << "-" << detId << ":) version mismatch (expected 0x" << std::hex << SLS_SHMVERSION << " but got 0x" << shm()->shmversion << ")" - << std::dec; + << std::dec << ". Clear Shared memory to continue."; throw SharedMemoryError(ss.str()); } } @@ -322,7 +322,8 @@ void slsDetector::initializeDetectorStructure(detectorType type) { shm()->timerValue[MEASUREMENTS_NUMBER] = 1; shm()->timerValue[FRAMES_FROM_START] = 0; shm()->timerValue[FRAMES_FROM_START_PG] = 0; - shm()->timerValue[SAMPLES] = 1; + shm()->timerValue[ANALOG_SAMPLES] = 1; + shm()->timerValue[DIGITAL_SAMPLES] = 1; shm()->timerValue[SUBFRAME_ACQUISITION_TIME] = 0; shm()->timerValue[STORAGE_CELL_NUMBER] = 0; shm()->timerValue[SUBFRAME_DEADTIME] = 0; @@ -418,10 +419,7 @@ void slsDetector::initializeDetectorStructure(detectorType type) { // update #nchans and databytes, as it depends on #samples, adcmask, // readoutflags (ctb only) - if (shm()->myDetectorType == CHIPTESTBOARD || - shm()->myDetectorType == MOENCH) { - updateTotalNumberOfChannels(); - } + updateTotalNumberOfChannels(); } int slsDetector::sendModule(sls_detector_module *myMod, @@ -519,7 +517,8 @@ slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multi_id, std::ostringstream ss; ss << "Single shared memory (" << multi_id << "-" << detId << ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION - << " but got 0x" << shm()->shmversion << ")" << std::dec; + << " but got 0x" << shm()->shmversion << ")" << std::dec + << ". Clear Shared memory to continue."; shm.UnmapSharedMemory(); throw SharedMemoryError(ss.str()); } @@ -584,34 +583,38 @@ void slsDetector::updateTotalNumberOfChannels() { if (shm()->myDetectorType == CHIPTESTBOARD || shm()->myDetectorType == MOENCH) { - int nchans = 0; - // calculate analog channels - uint32_t mask = shm()->adcEnableMask; - if (mask == BIT32_MASK) { - nchans = 32; - } else { - nchans = 0; - for (int ich = 0; ich < 32; ++ich) { - if (mask & (1 << ich)) - ++nchans; + int nachans = 0, ndchans = 0; + int adatabytes = 0, ddatabytes = 0; + // analog channels (normal, analog/digital readout) + if (shm()->roFlags == slsDetectorDefs::NORMAL_READOUT || + shm()->roFlags & slsDetectorDefs::ANALOG_AND_DIGITAL) { + uint32_t mask = shm()->adcEnableMask; + if (mask == BIT32_MASK) { + nachans = 32; + } else { + for (int ich = 0; ich < 32; ++ich) { + if (mask & (1 << ich)) + ++nachans; + } } + adatabytes = nachans * (shm()->dynamicRange / 8) * + shm()->timerValue[ANALOG_SAMPLES]; + FILE_LOG(logDEBUG1) + << "#Analog Channels:" << nachans << " Databytes: " << adatabytes; } - // calculate digital channels + // digital channels (ctb only, digital, analog/digital readout) if (shm()->myDetectorType == CHIPTESTBOARD && - (((shm()->roFlags & DIGITAL_ONLY) != 0) || - ((shm()->roFlags & ANALOG_AND_DIGITAL) != 0))) { - nchans += 4; + ((shm()->roFlags & DIGITAL_ONLY) || (shm()->roFlags & ANALOG_AND_DIGITAL))) { + ndchans = 64; + ddatabytes = (sizeof(uint64_t) * shm()->timerValue[DIGITAL_SAMPLES]); + FILE_LOG(logDEBUG1) << "#Digital Channels:" << ndchans + << " Databytes: " << ddatabytes; } - shm()->nChan[X] = nchans; - - // recalculate derived parameters chans and databytes - shm()->nChans = nchans; - shm()->dataBytes = shm()->nChans * shm()->nChips * - (shm()->dynamicRange / 8) * - shm()->timerValue[SAMPLES]; - FILE_LOG(logDEBUG1) << "Number of Channels:" << shm()->nChans - << " Databytes: " << shm()->dataBytes; + shm()->nChans = nachans + ndchans; + shm()->dataBytes = adatabytes + ddatabytes; + FILE_LOG(logDEBUG1) << "# Total #Channels:" << shm()->nChans + << " Databytes: " << shm()->dataBytes; } } @@ -882,10 +885,16 @@ int slsDetector::updateDetectorNoWait(sls::ClientSocket &client) { if (shm()->myDetectorType == CHIPTESTBOARD || shm()->myDetectorType == MOENCH) { - // samples + // analog samples n += client.receiveData(&i64, sizeof(i64)); if (i64 >= 0) { - shm()->timerValue[SAMPLES] = i64; + shm()->timerValue[ANALOG_SAMPLES] = i64; + } + + // digital samples + n += client.receiveData(&i64, sizeof(i64)); + if (i64 >= 0) { + shm()->timerValue[DIGITAL_SAMPLES] = i64; } // adcmask @@ -1518,8 +1527,7 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t) { shm()->timerValue[index] = retval; // update #nchans and databytes, as it depends on #samples, adcmask, // readoutflags - if (index == SAMPLES && (shm()->myDetectorType == CHIPTESTBOARD || - shm()->myDetectorType == MOENCH)) { + if (index == ANALOG_SAMPLES || index == DIGITAL_SAMPLES) { updateTotalNumberOfChannels(); } } @@ -1548,7 +1556,8 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t) { ACQUISITION_TIME, SUBFRAME_ACQUISITION_TIME, SUBFRAME_DEADTIME, - SAMPLES, + ANALOG_SAMPLES, + DIGITAL_SAMPLES, STORAGE_CELL_NUMBER}; if (std::any_of(std::begin(rt), std::end(rt), @@ -1884,7 +1893,8 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) { << "\nsub exp time:" << (shm()->timerValue[SUBFRAME_ACQUISITION_TIME]) << "\nsub dead time:" << (shm()->timerValue[SUBFRAME_DEADTIME]) - << "\nsamples:" << (shm()->timerValue[SAMPLES]) + << "\nasamples:" << (shm()->timerValue[ANALOG_SAMPLES]) + << "\ndsamples:" << (shm()->timerValue[DIGITAL_SAMPLES]) << "\ndynamic range:" << shm()->dynamicRange << "\nflippeddatax:" << (shm()->flippedData[X]) << "\nactivated: " << shm()->activated @@ -1939,14 +1949,16 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) { break; case CHIPTESTBOARD: - setTimer(SAMPLES, shm()->timerValue[SAMPLES]); + setTimer(ANALOG_SAMPLES, shm()->timerValue[ANALOG_SAMPLES]); + setTimer(DIGITAL_SAMPLES, shm()->timerValue[DIGITAL_SAMPLES]); enableTenGigabitEthernet(shm()->tenGigaEnable); setReadOutFlags(GET_READOUT_FLAGS); setADCEnableMask(shm()->adcEnableMask); break; case MOENCH: - setTimer(SAMPLES, shm()->timerValue[SAMPLES]); + setTimer(ANALOG_SAMPLES, shm()->timerValue[ANALOG_SAMPLES]); + setTimer(DIGITAL_SAMPLES, shm()->timerValue[DIGITAL_SAMPLES]); enableTenGigabitEthernet(shm()->tenGigaEnable); setADCEnableMask(shm()->adcEnableMask); break; diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index 8b0016b6d..326b75f62 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -609,12 +609,26 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { ++i; /*! \page timing - - samples [i] sets/gets number of samples expected from the jctb. Used in CHIP TEST BOARD only. \c Returns \c (long long int) + - samples [i] sets/gets number of samples (both analog and digital) expected from the ctb. Used in CHIP TEST BOARD and MOENCH only. \c Returns \c (long long int) */ descrToFuncMap[i].m_pFuncName = "samples"; descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer; ++i; + /*! \page timing + - asamples [i] sets/gets number of analog samples expected from the ctb. Used in CHIP TEST BOARD and MOENCH only. \c Returns \c (long long int) + */ + descrToFuncMap[i].m_pFuncName = "asamples"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer; + ++i; + + /*! \page timing + - bsamples [i] sets/gets number of digital samples expected from the ctb. Used in CHIP TEST BOARD and MOENCH only. \c Returns \c (long long int) + */ + descrToFuncMap[i].m_pFuncName = "bsamples"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdTimer; + ++i; + /*! \page timing - storagecells [i] sets/gets number of additional storage cells per acquisition. For very advanced users only! For JUNGFRAU only. Range: 0-15. The #images = #frames * #cycles * (#storagecells +1). \c Returns \c (long long int) */ @@ -1934,6 +1948,11 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdPattern; ++i; + /** not documenting this, but keeping this for backwards compatibility */ + descrToFuncMap[i].m_pFuncName = "adcdisable"; + descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdPattern; + ++i; + /*! \page prototype - pattern fn loads binary pattern file fn */ @@ -4426,8 +4445,13 @@ std::string slsDetectorCommand::cmdTimer(int narg, char *args[], int action, int index = CYCLES_NUMBER; else if (cmd == "measurements") index = MEASUREMENTS_NUMBER; - else if (cmd == "samples") - index = SAMPLES; + // also does digital sample + else if (cmd == "samples") + index = ANALOG_SAMPLES; + else if (cmd == "asamples") + index = ANALOG_SAMPLES; + else if (cmd == "bsamples") + index = DIGITAL_SAMPLES; else if (cmd == "storagecells") index = STORAGE_CELL_NUMBER; else if (cmd == "storagecell_delay") @@ -4466,6 +4490,14 @@ std::string slsDetectorCommand::cmdTimer(int narg, char *args[], int action, int ret = myDet->setTimer(index, t, detPos); + // samples command does both asamples and dsamples + if (cmd == "samples" ) { + int64_t dret = myDet->setTimer(DIGITAL_SAMPLES, t, detPos); + if (dret != ret) { + throw sls::RuntimeError("Analog and digital number of samples are different. Check with asamples and dsamples command"); + } + } + if ((ret != -1) && (index == ACQUISITION_TIME || index == SUBFRAME_ACQUISITION_TIME || index == FRAME_PERIOD || index == DELAY_AFTER_TRIGGER || index == SUBFRAME_DEADTIME || index == STORAGE_CELL_DELAY)) { @@ -4487,7 +4519,9 @@ std::string slsDetectorCommand::helpTimer(int action) { os << "delay t \t sets the delay after trigger in s" << std::endl; os << "frames t \t sets the number of frames per cycle (e.g. after each trigger)" << std::endl; os << "cycles t \t sets the number of cycles (e.g. number of triggers)" << std::endl; - os << "samples t \t sets the number of samples expected from the jctb" << std::endl; + os << "samples t \t sets the number of samples (both analog and digital) expected from the ctb" << std::endl; + os << "asamples t \t sets the number of analog samples expected from the ctb" << std::endl; + os << "dsamples t \t sets the number of digital samples expected from the ctb" << std::endl; os << "storagecells t \t sets number of storage cells per acquisition. For very advanced users only! For JUNGFRAU only. Range: 0-15. The #images = #frames * #cycles * (#storagecells+1)." << std::endl; os << "storagecell_start t \t sets the storage cell that stores the first acquisition of the series. Default is 15(0xf). For very advanced users only! For JUNGFRAU only. Range: 0-15." << std::endl; os << "storagecell_delay t \t sets additional time to t between 2 storage cells. For very advanced users only! For JUNGFRAU only. Range: 0-1638375 ns (resolution of 25ns).. " << std::endl; @@ -4502,7 +4536,9 @@ std::string slsDetectorCommand::helpTimer(int action) { os << "delay \t gets the delay after trigger in s" << std::endl; os << "frames \t gets the number of frames per cycle (e.g. after each trigger)" << std::endl; os << "cycles \t gets the number of cycles (e.g. number of triggers)" << std::endl; - os << "samples \t gets the number of samples expected from the jctb" << std::endl; + os << "samples \t gets the number of samples (both analog and digital) expected from the ctb" << std::endl; + os << "asamples \t gets the number of analog samples expected from the ctb" << std::endl; + os << "dsamples \t gets the number of digital samples expected from the ctb" << std::endl; os << "storagecells \t gets number of storage cells per acquisition.For JUNGFRAU only." << std::endl; os << "storagecell_start \t gets the storage cell that stores the first acquisition of the series." << std::endl; os << "storagecell_delay \tgets additional time between 2 storage cells. " << std::endl; @@ -5591,6 +5627,26 @@ std::string slsDetectorCommand::cmdPattern(int narg, char *args[], int action, i } os << std::hex << myDet->getADCEnableMask(detPos) << std::dec; + } + // kept only for backwards compatibility, use adcenable + else if (cmd == "adcdisable") { + + if (action == PUT_ACTION) { + uint32_t adcEnableMask = 0; + if (sscanf(args[1], "%x", &adcEnableMask)) + ; + else + return std::string("Could not scan adcdisable reg ") + std::string(args[1]); + + // get enable mask from enable mask + adcEnableMask ^= BIT32_MASK; + myDet->setADCEnableMask(adcEnableMask, detPos); + } + + uint32_t retval = myDet->getADCEnableMask(detPos); + // get disable mask + retval ^= BIT32_MASK; + os << std::hex << retval << std::dec; } else diff --git a/slsReceiverSoftware/include/GeneralData.h b/slsReceiverSoftware/include/GeneralData.h index 0fa1d0e95..3fb306663 100755 --- a/slsReceiverSoftware/include/GeneralData.h +++ b/slsReceiverSoftware/include/GeneralData.h @@ -179,14 +179,6 @@ public: FILE_LOG(logERROR) << "SetTenGigaEnable is a generic function that should be overloaded by a derived class"; }; - /** - * Setting packets per frame changes member variables - * @param ns number of samples - */ - virtual void setNumberofSamples(const uint64_t ns) { - FILE_LOG(logERROR) << "setNumberofSamples is a generic function that should be overloaded by a derived class"; - }; - /** * Enable Gap Pixels changes member variables * @param enable true if gap pixels enable, else false @@ -209,11 +201,12 @@ public: /** * Set databytes (ctb, moench) * @param a adc enable mask - * @param s number of samples + * @param as analog number of samples + * @param ds digital number of samples * @param t tengiga enable * @param f readout flags */ - virtual void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { + virtual void setImageSize(uint32_t a, uint64_t as, uint64_t ds, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { cprintf(RED,"setImageSize is a generic function that should be overloaded by a derived class\n"); }; @@ -557,7 +550,9 @@ private: /** Number of analog channels */ const int NCHAN_ANALOG = 32; /** Number of digital channels */ - const int NCHAN_DIGITAL = 4; + const int NCHAN_DIGITAL = 64; + /** Number of bytes per analog channel */ + const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; public: @@ -581,46 +576,60 @@ public: /** * Set databytes (ctb, moench) * @param a adc enable mask - * @param s number of samples + * @param as analog number of samples + * @param ds digital number of samples * @param t tengiga enable * @param f readout flags */ - void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { - int nchans = 0; - if (f != slsDetectorDefs::GET_READOUT_FLAGS) { - // analog channels - if (f == slsDetectorDefs::NORMAL_READOUT || f & slsDetectorDefs::ANALOG_AND_DIGITAL) { - if (a == BIT32_MASK) { - nchans = 32; - } else { - for (int ich = 0; ich < 32; ++ich) { - if (a & (1 << ich)) - ++nchans; - } - } - } - // digital channels - if (f & slsDetectorDefs::DIGITAL_ONLY || f & slsDetectorDefs::ANALOG_AND_DIGITAL) { - nchans += NCHAN_DIGITAL; - } - } - nPixelsX = nchans; - nPixelsY = s; - // 10G - if (t) { - headerSizeinPacket = 22; - dataSize = 8192; - packetSize = headerSizeinPacket + dataSize; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = ceil((double)imageSize / (double)packetSize); - standardheader = false; } + void setImageSize(uint32_t a, uint64_t as, uint64_t ds, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { + int nachans = 0, ndchans = 0; + int adatabytes = 0, ddatabytes = 0; + + if (f != slsDetectorDefs::GET_READOUT_FLAGS) { + // analog channels (normal, analog/digital readout) + if (f == slsDetectorDefs::NORMAL_READOUT || + f & slsDetectorDefs::ANALOG_AND_DIGITAL) { + if (a == BIT32_MASK) { + nachans = 32; + } else { + for (int ich = 0; ich < 32; ++ich) { + if (a & (1 << ich)) + ++nachans; + } + } + adatabytes = nachans * NUM_BYTES_PER_ANALOG_CHANNEL * as; + FILE_LOG(logDEBUG1) << " Number of Analog Channels:" << nachans + << " Databytes: " << adatabytes; + } + // digital channels + if (f & slsDetectorDefs::DIGITAL_ONLY || + f & slsDetectorDefs::ANALOG_AND_DIGITAL) { + ndchans = NCHAN_DIGITAL; + ddatabytes = (sizeof(uint64_t) * ds); + FILE_LOG(logDEBUG1) << "Number of Digital Channels:" << ndchans + << " Databytes: " << ddatabytes; + } + FILE_LOG(logDEBUG1) << "Total Number of Channels:" << nachans + ndchans + << " Databytes: " << adatabytes + ddatabytes; + } + nPixelsX = nachans + ndchans; + nPixelsY = 1; + // 10G + if (t) { + headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); + dataSize = UDP_PACKET_DATA_BYTES; + packetSize = headerSizeinPacket + dataSize; + imageSize = adatabytes + ddatabytes; + packetsPerFrame = ceil((double)imageSize / (double)dataSize); + standardheader = true; + } // 1g udp (via fifo readout) else { headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); dataSize = UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); + imageSize = adatabytes + ddatabytes; + packetsPerFrame = ceil((double)imageSize / (double)dataSize); standardheader = true; } } @@ -632,95 +641,73 @@ class MoenchData : public GeneralData { private: - /** Structure of an jungfrau ctb packet header (10G Udp) */ - struct jfrauctb_packet_header { - unsigned char emptyHeader[6]; - unsigned char reserved[4]; - uint32_t packetFrameNumber; - uint64_t bunchid; - } __attribute__((packed)); + /** Number of bytes per analog channel */ + const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; public: /** Constructor */ MoenchData() { - myDetectorType = slsDetectorDefs::MOENCH; - nPixelsX = 32; // total number of channels - nPixelsY = 1; // number of samples - headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - dataSize = UDP_PACKET_DATA_BYTES; - packetSize = headerSizeinPacket + dataSize; - // packetsPerFrame = 1; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); - frameIndexMask = 0xFFFFFF; - maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize = - FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); - defaultFifoDepth = 2500; - standardheader = true; + myDetectorType = slsDetectorDefs::MOENCH; + nPixelsX = 32; // total number of channels + nPixelsY = 1; // number of samples + headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); + dataSize = UDP_PACKET_DATA_BYTES; + packetSize = headerSizeinPacket + dataSize; + // packetsPerFrame = 1; + imageSize = nPixelsX * nPixelsY * 2; + packetsPerFrame = ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); + frameIndexMask = 0xFFFFFF; + maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE; + fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); + defaultFifoDepth = 2500; + standardheader = true; }; - /** - * Get Header Infomation (frame number, packet number) - * @param index thread index for debugging purposes - * @param packetData pointer to data - * @param dynamicRange dynamic range to assign subframenumber if 32 bit mode - * @param oddStartingPacket odd starting packet (gotthard) - * @param frameNumber frame number * @param packetNumber packet number - * @param subFrameNumber sub frame number if applicable - * @param bunchId bunch id - */ - void GetHeaderInfo(int index, char* packetData, uint32_t dynamicRange, bool oddStartingPacket, - uint64_t& frameNumber, uint32_t& packetNumber, uint32_t& subFrameNumber, uint64_t& bunchId) const { - subFrameNumber = -1; - auto header = reinterpret_cast(packetData); - frameNumber = (header->packetFrameNumber >> 8) & frameIndexMask; - packetNumber = header->packetFrameNumber & 0xFF; - bunchId = header->bunchid; - } - - /** * Set databytes (ctb, moench) * @param a adc enable mask - * @param s number of samples + * @param as analog number of samples + * @param ds digital number of samples * @param t tengiga enable * @param f readout flags */ - void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { - int nchans = 32; + void setImageSize(uint32_t a, uint64_t as, uint64_t ds, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) { + int nachans = 0; + int adatabytes = 0; + + // analog channels (normal, analog/digital readout) if (a == BIT32_MASK) { - nchans = 32; + nachans = 32; } else { for (int ich = 0; ich < 32; ++ich) { if (a & (1 << ich)) - ++nchans; + ++nachans; } } + adatabytes = nachans * NUM_BYTES_PER_ANALOG_CHANNEL * as; + FILE_LOG(logDEBUG1) << "Total Number of Channels:" << nachans + << " Databytes: " << adatabytes; - nPixelsX = nchans; - nPixelsY = s; - // 10G - if (t) { - headerSizeinPacket = 22; - dataSize = 8192; + nPixelsX = nachans; + nPixelsY = 1; + // 10G + if (t) { + headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); + dataSize = UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = (imageSize + packetSize - 1) / packetSize; - standardheader = false; + imageSize = adatabytes; + packetsPerFrame = ceil((double)imageSize / (double)dataSize); } - // 1g udp (via fifo readout) - else { + // 1g udp (via fifo readout) + else { headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); dataSize = UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = (imageSize + UDP_PACKET_DATA_BYTES - 1) / UDP_PACKET_DATA_BYTES; - standardheader = true; - } + imageSize = adatabytes; + packetsPerFrame = ceil((double)imageSize / (double)dataSize); + } } }; -; \ No newline at end of file diff --git a/slsReceiverSoftware/include/slsReceiverImplementation.h b/slsReceiverSoftware/include/slsReceiverImplementation.h index 2e821fc69..dc86a6b8d 100755 --- a/slsReceiverSoftware/include/slsReceiverImplementation.h +++ b/slsReceiverSoftware/include/slsReceiverImplementation.h @@ -257,10 +257,16 @@ class slsReceiverImplementation: private virtual slsDetectorDefs { uint64_t getNumberOfFrames() const; /* - * Get Number of Samples expected by receiver from detector (for chip test board only) - * @return number of samples expected + * Get Number of Analog Samples expected by receiver from detector (for chip test board and moench only) + * @return number of Analog samples expected */ - uint64_t getNumberofSamples() const; + uint64_t getNumberofAnalogSamples() const; + + /* + * Get Number of Digital Samples expected by receiver from detector (for chip test board and moench only) + * @return number of Digital samples expected + */ + uint64_t getNumberofDigitalSamples() const; /** * Get Dynamic Range or Number of Bits Per Pixel @@ -571,11 +577,18 @@ class slsReceiverImplementation: private virtual slsDetectorDefs { int setNumberOfFrames(const uint64_t i); /** - * Set Number of Samples expected by receiver from detector - * @param i number of Samples expected + * Set Number of Analog Samples expected by receiver from detector + * @param i number of Analog Samples expected * @return OK or FAIL */ - int setNumberofSamples(const uint64_t i); + int setNumberofAnalogSamples(const uint64_t i); + + /** + * Set Number of Digital Samples expected by receiver from detector + * @param i number of Digital Samples expected + * @return OK or FAIL + */ + int setNumberofDigitalSamples(const uint64_t i); /** * Set Dynamic Range or Number of Bits Per Pixel @@ -816,8 +829,10 @@ private: uint64_t subPeriod; /** Frame Number */ uint64_t numberOfFrames; - /** Samples Number */ - uint64_t numberOfSamples; + /** Analog Samples Number */ + uint64_t numberOfAnalogSamples; + /** Digital Samples Number */ + uint64_t numberOfDigitalSamples; /** Dynamic Range */ uint32_t dynamicRange; /** Ten Giga Enable*/ diff --git a/slsReceiverSoftware/src/slsReceiverImplementation.cpp b/slsReceiverSoftware/src/slsReceiverImplementation.cpp index e18057995..3375d6fc2 100755 --- a/slsReceiverSoftware/src/slsReceiverImplementation.cpp +++ b/slsReceiverSoftware/src/slsReceiverImplementation.cpp @@ -62,7 +62,8 @@ void slsReceiverImplementation::InitializeMembers() { subExpTime = 0; subPeriod = 0; numberOfFrames = 0; - numberOfSamples = 0; + numberOfAnalogSamples = 0; + numberOfDigitalSamples = 0; dynamicRange = 16; tengigaEnable = false; fifoDepth = 0; @@ -341,9 +342,14 @@ uint64_t slsReceiverImplementation::getNumberOfFrames() const{ return numberOfFrames; } -uint64_t slsReceiverImplementation::getNumberofSamples() const{ +uint64_t slsReceiverImplementation::getNumberofAnalogSamples() const{ FILE_LOG(logDEBUG3) << __SHORT_AT__ << " called"; - return numberOfSamples; + return numberOfAnalogSamples; +} + +uint64_t slsReceiverImplementation::getNumberofDigitalSamples() const{ + FILE_LOG(logDEBUG3) << __SHORT_AT__ << " called"; + return numberOfDigitalSamples; } uint32_t slsReceiverImplementation::getDynamicRange() const{ @@ -475,7 +481,7 @@ int slsReceiverImplementation::setReadOutFlags(const readOutFlags f) { // side effects if (myDetectorType == CHIPTESTBOARD) { - generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags); + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, readoutFlags); for (const auto& it : dataProcessor) it->SetPixelDimension(); if (SetupFifoStructure() == FAIL) @@ -823,10 +829,10 @@ int slsReceiverImplementation::setADCEnableMask(uint32_t mask) { switch (myDetectorType) { case MOENCH: - generalData->setImageSize(mask, numberOfSamples, tengigaEnable); + generalData->setImageSize(mask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable); break; case CHIPTESTBOARD: - generalData->setImageSize(mask, numberOfSamples, tengigaEnable, readoutFlags); + generalData->setImageSize(mask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, readoutFlags); break; default: break; @@ -953,21 +959,41 @@ int slsReceiverImplementation::setNumberOfFrames(const uint64_t i) { } -int slsReceiverImplementation::setNumberofSamples(const uint64_t i) { - if (numberOfSamples != i) { - numberOfSamples = i; +int slsReceiverImplementation::setNumberofAnalogSamples(const uint64_t i) { + if (numberOfAnalogSamples != i) { + numberOfAnalogSamples = i; if(myDetectorType == MOENCH) { - generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable); + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable); } else if(myDetectorType == CHIPTESTBOARD) { - generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags); + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, readoutFlags); } for (const auto& it : dataProcessor) it->SetPixelDimension(); if (SetupFifoStructure() == FAIL) return FAIL; } - FILE_LOG (logINFO) << "Number of Samples: " << numberOfSamples; + FILE_LOG (logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples; + FILE_LOG (logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame); + return OK; +} + + +int slsReceiverImplementation::setNumberofDigitalSamples(const uint64_t i) { + if (numberOfDigitalSamples != i) { + numberOfDigitalSamples = i; + + if(myDetectorType == MOENCH) { + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable); + } else if(myDetectorType == CHIPTESTBOARD) { + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, readoutFlags); + } + for (const auto& it : dataProcessor) + it->SetPixelDimension(); + if (SetupFifoStructure() == FAIL) + return FAIL; + } + FILE_LOG (logINFO) << "Number of Digital Samples: " << numberOfDigitalSamples; FILE_LOG (logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame); return OK; } @@ -999,10 +1025,10 @@ int slsReceiverImplementation::setTenGigaEnable(const bool b) { generalData->SetTenGigaEnable(b,dynamicRange); break; case MOENCH: - generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable); + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable); break; case CHIPTESTBOARD: - generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags); + generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, readoutFlags); break; default: break; diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index b27d638d5..8575ffb9a 100755 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -877,12 +877,19 @@ int slsReceiverTCPIPInterface::set_timer() { case SUBFRAME_DEADTIME: receiver->setSubPeriod(index[1] + receiver->getSubExpTime()); break; - case SAMPLES: + case ANALOG_SAMPLES: if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) { - modeNotImplemented("(Samples) Timer index", (int)index[0]); + modeNotImplemented("(Analog Samples) Timer index", (int)index[0]); break; } - receiver->setNumberofSamples(index[1]); + receiver->setNumberofAnalogSamples(index[1]); + break; + case DIGITAL_SAMPLES: + if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) { + modeNotImplemented("(Digital Samples) Timer index", (int)index[0]); + break; + } + receiver->setNumberofDigitalSamples(index[1]); break; default: modeNotImplemented("Timer index", (int)index[0]); @@ -909,14 +916,23 @@ int slsReceiverTCPIPInterface::set_timer() { case SUBFRAME_DEADTIME: retval=(receiver->getSubPeriod() - receiver->getSubExpTime()); break; - case SAMPLES: + case ANALOG_SAMPLES: if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) { ret = FAIL; sprintf(mess,"This timer mode (%lld) does not exist for this receiver type\n", (long long int)index[0]); FILE_LOG(logERROR) << "Warning: " << mess; break; } - retval=receiver->getNumberofSamples(); + retval=receiver->getNumberofAnalogSamples(); + break; + case DIGITAL_SAMPLES: + if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) { + ret = FAIL; + sprintf(mess,"This timer mode (%lld) does not exist for this receiver type\n", (long long int)index[0]); + FILE_LOG(logERROR) << "Warning: " << mess; + break; + } + retval=receiver->getNumberofDigitalSamples(); break; default: modeNotImplemented("Timer index", (int)index[0]); diff --git a/slsReceiverSoftware/tests/CMakeLists.txt b/slsReceiverSoftware/tests/CMakeLists.txt index 03e10f106..d8cc5e694 100755 --- a/slsReceiverSoftware/tests/CMakeLists.txt +++ b/slsReceiverSoftware/tests/CMakeLists.txt @@ -7,7 +7,7 @@ # test-GeneralData.cpp # ) -target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-GeneralData.cpp) +#target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-GeneralData.cpp) # add_executable(testSlsReceiver ${SOURCES}) # target_link_libraries(testSlsReceiver diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 61d64ac66..c903d24a9 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -117,7 +117,8 @@ class slsDetectorDefs { MEASUREMENTS_NUMBER, FRAMES_FROM_START, FRAMES_FROM_START_PG, - SAMPLES, + ANALOG_SAMPLES, + DIGITAL_SAMPLES, SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */ STORAGE_CELL_NUMBER, /**