ctb:separated analog and digital samples in server and send analog and digital data packed separately per frame to reciever

This commit is contained in:
2019-04-30 18:55:32 +02:00
parent b0cffcd570
commit 2f3b0e0b06
17 changed files with 489 additions and 300 deletions

View File

@ -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)

View File

@ -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++;

View File

@ -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)

View File

@ -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) */

View File

@ -15,22 +15,20 @@
#include <errno.h>
#include <netdb.h>
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);
}

View File

@ -61,7 +61,6 @@ void setupDetector();
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
int allocateRAM();
void updateDataBytes();
int getChannels();
#endif
#if defined(GOTTHARDD) || defined(JUNGFRAUD)

View File

@ -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();