diff --git a/slsReceiverSoftware/include/UDPStandardImplementation.h b/slsReceiverSoftware/include/UDPStandardImplementation.h index 7ec6672aa..0921ad934 100644 --- a/slsReceiverSoftware/include/UDPStandardImplementation.h +++ b/slsReceiverSoftware/include/UDPStandardImplementation.h @@ -461,29 +461,6 @@ private: *************************************************************************/ //**detector parameters*** - /** - * structure of an eiger packet header - * subframenum subframe number for 32 bit mode (already written by firmware) - * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) - * portnum 0 for the first port and 1 for the second port (written by software to file) - * dynamicrange dynamic range or bits per pixel (written by software to file) - */ - typedef struct { - unsigned char subFameNumber[4]; - unsigned char missingPacket[2]; - unsigned char portIndex[1]; - unsigned char dynamicRange[1]; - } eiger_packet_header_t; - /** - * structure of an eiger packet footer - * framenum 48 bit frame number (already written by firmware) - * packetnum packet number (already written by firmware) - */ - typedef struct { - unsigned char frameNumber[6]; - unsigned char packetNumber[2]; - } eiger_packet_footer_t; - /** Size of 1 Frame including headers */ int frameSize; diff --git a/slsReceiverSoftware/include/genericSocket.h b/slsReceiverSoftware/include/genericSocket.h index 97cd3223e..3facb0a2b 100644 --- a/slsReceiverSoftware/include/genericSocket.h +++ b/slsReceiverSoftware/include/genericSocket.h @@ -75,7 +75,8 @@ class sockaddr_in; using namespace std; #define DEFAULT_PACKET_SIZE 1286 -#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB +/*#define SOCKET_BUFFER_SIZE (100*1024*1024) //100MB*/ +#define SOCKET_BUFFER_SIZE (2000*1024*1024) //100MB #define DEFAULT_PORTNO 1952 #define DEFAULT_BACKLOG 5 #define DEFAULT_UDP_PORTNO 50001 @@ -578,7 +579,6 @@ enum communicationProtocol{ int ReceiveDataOnly(void* buf,int length=0){ - if (buf==NULL) return -1; diff --git a/slsReceiverSoftware/include/receiver_defs.h b/slsReceiverSoftware/include/receiver_defs.h index c11fe876d..3cc5e8091 100755 --- a/slsReceiverSoftware/include/receiver_defs.h +++ b/slsReceiverSoftware/include/receiver_defs.h @@ -5,6 +5,43 @@ #include + +/** + * structure of an eiger packet header + * subframenum subframe number for 32 bit mode (already written by firmware) + * missingpacket explicitly put to 0xFF to recognize it in file read (written by software) + * portnum 0 for the first port and 1 for the second port (written by software to file) + * dynamicrange dynamic range or bits per pixel (written by software to file) + */ +typedef struct { + unsigned char subFrameNumber[4]; + unsigned char missingPacket[2]; + unsigned char portIndex[1]; + unsigned char dynamicRange[1]; +} eiger_packet_header_t; +/** + * structure of an eiger packet footer + * framenum 48 bit frame number (already written by firmware) + * packetnum packet number (already written by firmware) + */ +typedef struct { + unsigned char frameNumber[6]; + unsigned char packetNumber[2]; +} eiger_packet_footer_t; + +/** + * structure of an jungfrau packet header + * empty header + * framenumber + * packetnumber + */ +typedef struct { + unsigned char emptyHeader[6]; + unsigned char frameNumber[8]; + unsigned char packetNumber[8]; +} jfrau_packet_header_t; + + #define GOODBYE -200 #define DO_NOTHING 0 @@ -90,6 +127,26 @@ + +#define JFRAU_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 +#define JFRAU_PACKETS_PER_FRAME 128 +#define JFRAU_HEADER_LENGTH 22 +#define JFRAU_ONE_DATA_SIZE 8192 +#define JFRAU_ONE_PACKET_SIZE (JFRAU_HEADER_LENGTH+JFRAU_ONE_DATA_SIZE) //8214 +#define JFRAU_DATA_BYTES (JFRAU_ONE_DATA_SIZE*JFRAU_PACKETS_PER_FRAME) //8192*128 +#define JFRAU_BUFFER_SIZE (JFRAU_ONE_PACKET_SIZE*JFRAU_PACKETS_PER_FRAME) //8214*128 + + +#define JFRAU_FRAME_INDEX_MASK 0x0 //Not Applicable, use struct +#define JFRAU_FRAME_INDEX_OFFSET 0x0 //Not Applicable, use struct +#define JFRAU_PACKET_INDEX_MASK 0x0//Not Applicable, use struct + +#define JFRAU_PIXELS_IN_ONE_ROW (256*4) +#define JFRAU_PIXELS_IN_ONE_COL (256*2) +#define JFRAU_BYTES_IN_ONE_ROW (JFRAU_PIXELS_IN_ONE_ROW*2) + + + #define JCTB_FIFO_SIZE 2500 //cannot be less than max jobs per thread = 1000 /*#define MOENCH_ALIGNED_FRAME_SIZE 65536*/ #define JCTB_PACKETS_PER_FRAME 50 diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index b71b705f6..237f240e6 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -176,6 +176,9 @@ private: /** eiger specific read frame */ int eiger_read_frame(); + /** jungfrau specific read frame */ + int jungfrau_read_frame(); + /** Sets the receiver to send every nth frame to gui, or only upon gui request */ int set_read_frequency(); diff --git a/slsReceiverSoftware/include/sls_receiver_defs.h b/slsReceiverSoftware/include/sls_receiver_defs.h index 07566ab84..c11f6f8c0 100755 --- a/slsReceiverSoftware/include/sls_receiver_defs.h +++ b/slsReceiverSoftware/include/sls_receiver_defs.h @@ -24,6 +24,7 @@ typedef int int32_t; #define SHORT_MAX_FRAMES_PER_FILE 100000 #define MOENCH_MAX_FRAMES_PER_FILE 1000 #define EIGER_MAX_FRAMES_PER_FILE 2000 +#define JFRAU_MAX_FRAMES_PER_FILE 2000 #define JFCTB_MAX_FRAMES_PER_FILE 100000 diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index ec0f964cb..fe86efd51 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -251,7 +251,7 @@ int UDPStandardImplementation::setupFifoStructure(){ int64_t i; int oldNumberofJobsPerBuffer = numberofJobsPerBuffer; //eiger always listens to 1 packet at a time - if(myDetectorType == EIGER){ + if((myDetectorType == EIGER) || (myDetectorType = JUNGFRAU)){ numberofJobsPerBuffer = 1; FILE_LOG(logDEBUG) << "Info: 1 packet per buffer"; } @@ -288,6 +288,7 @@ int UDPStandardImplementation::setupFifoStructure(){ case GOTTHARD: fifoSize = GOTTHARD_FIFO_SIZE; break; case MOENCH: fifoSize = MOENCH_FIFO_SIZE; break; case PROPIX: fifoSize = PROPIX_FIFO_SIZE; break; + case JUNGFRAU: fifoSize = JFRAU_FIFO_SIZE; break; case EIGER: fifoSize = EIGER_FIFO_SIZE * packetsPerFrame; break;//listens to 1 packet at a time and size depends on packetsperframe default: break; } @@ -717,7 +718,6 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ footerOffset = EIGER_PACKET_HEADER_SIZE + oneDataSize; break; case JUNGFRAUCTB: - case JUNGFRAU: packetsPerFrame = JCTB_PACKETS_PER_FRAME; onePacketSize = JCTB_ONE_PACKET_SIZE; //oneDataSize = Not applicable; @@ -730,6 +730,19 @@ int UDPStandardImplementation::setDetectorType(const detectorType d){ fifoSize = JCTB_FIFO_SIZE; //footerOffset = Not applicable; break; + case JUNGFRAU: + packetsPerFrame = JFRAU_PACKETS_PER_FRAME; + onePacketSize = JFRAU_ONE_PACKET_SIZE; + oneDataSize = JFRAU_DATA_BYTES; + frameSize = JFRAU_BUFFER_SIZE; + bufferSize = JFRAU_BUFFER_SIZE; + frameIndexMask = JFRAU_FRAME_INDEX_MASK; + frameIndexOffset = JFRAU_FRAME_INDEX_OFFSET; + packetIndexMask = JFRAU_PACKET_INDEX_MASK; + maxPacketsPerFile = JFRAU_MAX_FRAMES_PER_FILE * JFRAU_PACKETS_PER_FRAME; + fifoSize = JFRAU_FIFO_SIZE; + //footerOffset = Not applicable; + break; default: FILE_LOG(logERROR) << "This is an unknown receiver type " << (int)d; return FAIL; @@ -1297,9 +1310,9 @@ int UDPStandardImplementation::setupWriter(){ if (rawDataReadyCallBack){ FILE_LOG(logINFO) << "Data Write has been defined externally"; } - }else if(!fileWriteEnable) + }else if(!fileWriteEnable){ FILE_LOG(logINFO) << "Data will not be saved"; - + } //creating first file @@ -1571,6 +1584,7 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in int receivedSize = udpSocket[ithread]->ReceiveDataOnly(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS + cSize, lSize + cSize); + //throw away packets that is not one packet size, need to check status if socket is shut down while(status != TRANSMITTING && myDetectorType == EIGER && receivedSize != onePacketSize) { if(receivedSize != EIGER_HEADER_LENGTH) @@ -1584,13 +1598,19 @@ int UDPStandardImplementation::prepareAndListenBuffer(int ithread, int lSize, in totalListeningFrameCount[ithread] += (receivedSize/onePacketSize); #ifdef MANUALDEBUG - eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); - eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); - cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", - ithread, - (*( (unsigned int*) header->subFameNumber)), - (*( (uint8_t*) header->dynamicRange)), - (*( (uint16_t*) footer->packetNumber))); + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(RED,"framenumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->frameNumber))); + cprintf(RED,"packetnumber:%llu\n",(long long unsigned int)(*( (uint64_t*) header->packetNumber))); + }else if(myDetectorType == EIGER){ + eiger_packet_header_t* header = (eiger_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + eiger_packet_footer_t* footer = (eiger_packet_footer_t*)(buffer[ithread] + footerOffset + HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(GREEN,"thread:%d subframenum:%d oldpacketnum:%d new pnum:%d\n", + ithread, + (*( (unsigned int*) header->subFrameNumber)), + (*( (uint8_t*) header->dynamicRange)), + (*( (uint16_t*) footer->packetNumber))); + } #endif @@ -1609,10 +1629,15 @@ void UDPStandardImplementation::startFrameIndices(int ithread){ FILE_LOG(logDEBUG) << __AT__ << " called"; //determine startFrameIndex + jfrau_packet_header_t* header=0; switch(myDetectorType){ case EIGER: startFrameIndex = 0; //frame number always resets break; + case JUNGFRAU: + header = (jfrau_packet_header_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS); + startFrameIndex = (*( (uint64_t*) header->frameNumber)); + break; default: if(shortFrameEnable < 0){ startFrameIndex = (((((uint32_t)(*((uint32_t*)(buffer[ithread] + HEADER_SIZE_NUM_TOT_PACKETS))))+1) @@ -1741,8 +1766,10 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz int lastPacketOffset; //the offset of the last packet uint32_t lastFrameHeader; //frame number of last packet in buffer + uint64_t lastFrameHeader64; //frame number of last packet in buffer uint32_t packetCount = (packetsPerFrame/numberofListeningThreads) * numberofJobsPerBuffer; //packets received cSize = 0; //reset size + jfrau_packet_header_t* header; switch(myDetectorType){ case GOTTHARD: @@ -1802,6 +1829,44 @@ uint32_t UDPStandardImplementation::processListeningBuffer(int ithread, int cSiz } break; + + case JUNGFRAU: + lastPacketOffset = (((numberofJobsPerBuffer * packetsPerFrame - 1) * onePacketSize) + HEADER_SIZE_NUM_TOT_PACKETS); +#ifdef DEBUG4 + header = (jfrau_packet_header_t*) (buffer[ithread]+HEADER_SIZE_NUM_TOT_PACKETS); + cprintf(BLUE, "Listening_Thread: First Header:%llu\t First Packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); +#ifdef DEBUG4 + cprintf(BLUE, "Listening_Thread: Last Header:%llu\t Last Packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + //jungfrau last packet value is 0, so find the last packet and store the others in a temp storage + if(*( (uint64_t*) header->packetNumber)){ + cprintf(RED,"entering missing packet zone\n"); + lastFrameHeader64 = (*( (uint64_t*) header->frameNumber)); + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + --packetCount; + while (lastFrameHeader64 == (*( (uint64_t*) header->frameNumber))){ + cSize += onePacketSize; + lastPacketOffset -= onePacketSize; + header = (jfrau_packet_header_t*) (buffer[ithread]+lastPacketOffset); +#ifdef DEBUG4 + cprintf(RED,"new header:%llu new packet:%llu\n", + (long long unsigned int)(*( (uint64_t*) header->frameNumber)), + (long long unsigned int)(*( (uint64_t*) header->packetNumber))); +#endif + --packetCount; + } + memcpy(temp, buffer[ithread]+(lastPacketOffset+onePacketSize), cSize); + } + + break; + default: cprintf(RED,"Listening_Thread %d: Error: This detector %s is not implemented in the receiver\n", ithread, getDetectorType(myDetectorType).c_str()); @@ -2406,19 +2471,26 @@ void UDPStandardImplementation::handleWithoutDataCompression(int ithread, char* //get frame number (eiger already gets it when it does packet to packet processing) - if (myDetectorType != EIGER){ - uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); - //for gotthard and normal frame, increment frame number to separate fnum and pnum - if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) - tempframenumber++; - //get frame number - currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + if(myDetectorType != EIGER){ + if(myDetectorType == JUNGFRAU){ + jfrau_packet_header_t* header = (jfrau_packet_header_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS); + currentFrameNumber = (*( (uint64_t*) header->frameNumber)); + }else{ + uint64_t tempframenumber = ((uint32_t)(*((uint32_t*)(wbuffer[0] + HEADER_SIZE_NUM_TOT_PACKETS)))); + //for gotthard and normal frame, increment frame number to separate fnum and pnum + if (myDetectorType == PROPIX ||(myDetectorType == GOTTHARD && shortFrameEnable == -1)) + tempframenumber++; + //get frame number + currentFrameNumber = (tempframenumber & frameIndexMask) >> frameIndexOffset; + } //set indices acquisitionIndex = currentFrameNumber - startAcquisitionIndex; frameIndex = currentFrameNumber - startFrameIndex; } + + //callback to write data if (cbAction < DO_EVERYTHING){ switch(myDetectorType){ diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 4af5e0424..3cb511b87 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -817,7 +817,7 @@ int slsReceiverTCPIPInterface::start_receiver(){ // send answer socket->SendDataOnly(&ret,sizeof(ret)); if(ret==FAIL){ - cprintf(RED, "%s\n", mess); + cprintf(RED, "Error:%s\n", mess); socket->SendDataOnly(mess,sizeof(mess)); } //return ok/fail @@ -1084,6 +1084,8 @@ int slsReceiverTCPIPInterface::read_frame(){ return eiger_read_frame(); case PROPIX: return propix_read_frame(); + case JUNGFRAU: + return jungfrau_read_frame(); default: return gotthard_read_frame(); } @@ -1608,22 +1610,6 @@ int slsReceiverTCPIPInterface::propix_read_frame(){ int slsReceiverTCPIPInterface::eiger_read_frame(){ ret=OK; - /** structure of an eiger packet*/ - typedef struct - { - unsigned char subframenum[4]; - unsigned char missingpacket[2]; - unsigned char portnum[1]; - unsigned char dynamicrange[1]; - } eiger_packet_header_t; - - typedef struct - { - unsigned char framenum[6]; - unsigned char packetnum[2]; - } eiger_packet_footer_t; - - char fName[MAX_STR_LENGTH]=""; int acquisitionIndex = -1; int frameIndex= -1; @@ -1686,7 +1672,7 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ if(dynamicrange == 32){ eiger_packet_header_t* wbuf_header; wbuf_header = (eiger_packet_header_t*) raw; - subframenumber = *( (uint32_t*) wbuf_header->subframenum); + subframenumber = *( (uint32_t*) wbuf_header->subFrameNumber); } #ifdef VERYVERBOSE @@ -1866,6 +1852,167 @@ int slsReceiverTCPIPInterface::eiger_read_frame(){ +int slsReceiverTCPIPInterface::jungfrau_read_frame(){ + ret=OK; + + char fName[MAX_STR_LENGTH]=""; + int acquisitionIndex = -1; + int frameIndex= -1; + uint64_t currentIndex=0; + uint64_t startAcquisitionIndex=0; + uint64_t startFrameIndex=0; + strcpy(mess,"Could not read frame\n"); + + + int frameSize = JFRAU_ONE_PACKET_SIZE * packetsPerFrame; + int dataSize = JFRAU_ONE_DATA_SIZE * packetsPerFrame; + int oneDataSize = JFRAU_ONE_DATA_SIZE; + + char* raw; + char* origVal = new char[frameSize]; + char* retval = new char[dataSize]; + char* blackpacket = new char[oneDataSize]; + + for(int i=0;igetFramesCaught()){ + startAcquisitionIndex=-1; +#ifdef VERYVERBOSE + cout<<"haven't caught any frame yet"<readFrame(fName,&raw,startAcquisitionIndex,startFrameIndex); + //send garbage with -1 index to try again + if (raw == NULL){ + startAcquisitionIndex = -1; +#ifdef VERYVERBOSE + cout<<"data not ready for gui yet"<frameNumber)); +#ifdef VERYVERBOSE + cout << "currentIndex:" << dec << currentIndex << endl; +#endif + + int64_t currentPacket = packetsPerFrame-1; + int offsetsrc = 0; + int offsetdest = 0; + uint64_t ifnum=-1; + uint64_t ipnum=-1; + + while(currentPacket >= 0){ + header = (jfrau_packet_header_t*) (origVal + offsetsrc); + ifnum = (*( (uint64_t*) header->frameNumber)); + ipnum = (*( (uint64_t*) header->packetNumber)); + if(ifnum != currentIndex) { + cout << "current packet " << currentPacket << " Wrong Frame number " << ifnum << ", copying blank packet" << endl; + memcpy(retval+offsetdest,blackpacket,oneDataSize); + offsetdest += oneDataSize; + //no need to increase offsetsrc as all packets will be wrong + currentPacket--; + continue; + } + if(ipnum!= currentPacket){ + cout << "current packet " << currentPacket << " Wrong packet number " << ipnum << ", copying blank packet" << endl; + memcpy(retval+offsetdest,blackpacket,oneDataSize); + offsetdest += oneDataSize; + //no need to increase offsetsrc until we get the right packet + currentPacket--; + continue; + } + offsetsrc+=JFRAU_HEADER_LENGTH; + memcpy(retval+offsetdest,origVal+offsetsrc,oneDataSize); + offsetdest += oneDataSize; + offsetsrc += oneDataSize; + currentPacket--; + } + + + acquisitionIndex = (int)(currentIndex-startAcquisitionIndex); + if(acquisitionIndex == -1) + startFrameIndex = -1; + else + frameIndex = (int)(currentIndex-startFrameIndex); +#ifdef VERY_VERY_DEBUG + cout << "acquisitionIndex calculated is:" << acquisitionIndex << endl; + cout << "frameIndex calculated is:" << frameIndex << endl; + cout << "currentIndex:" << currentIndex << endl; + cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; + cout << "startFrameIndex:" << startFrameIndex << endl; +#endif + } + } + +#ifdef VERYVERBOSE + if(frameIndex!=-1){ + cout << "fName:" << fName << endl; + cout << "acquisitionIndex:" << acquisitionIndex << endl; + cout << "frameIndex:" << frameIndex << endl; + cout << "startAcquisitionIndex:" << startAcquisitionIndex << endl; + cout << "startFrameIndex:" << startFrameIndex << endl; + } +#endif + + + +#endif + + if(ret==OK && socket->differentClients){ + FILE_LOG(logDEBUG) << "Force update"; + ret=FORCE_UPDATE; + } + + // send answer + socket->SendDataOnly(&ret,sizeof(ret)); + if(ret==FAIL){ + cprintf(RED,"%s\n",mess); + socket->SendDataOnly(mess,sizeof(mess)); + } + else{ + socket->SendDataOnly(fName,MAX_STR_LENGTH); + socket->SendDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + socket->SendDataOnly(&frameIndex,sizeof(frameIndex)); + socket->SendDataOnly(retval,dataSize); + } + + delete [] retval; + delete [] origVal; + delete [] raw; + + return ret; +} + + + + + + int slsReceiverTCPIPInterface::set_read_frequency(){ ret=OK; int retval=-1; @@ -2323,7 +2470,8 @@ int slsReceiverTCPIPInterface::set_dynamic_range() { packetsPerFrame = EIGER_ONE_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; else packetsPerFrame = EIGER_TEN_GIGA_CONSTANT * dynamicrange * EIGER_MAX_PORTS; - } + }else if (myDetectorType == JUNGFRAU) + packetsPerFrame = JFRAU_PACKETS_PER_FRAME; } } }