#include "clogger.h" #include "common.h" #include "mythen3.h" #include "sls/ansi.h" #include "sls/sls_detector_defs.h" #include "slsDetectorServer_defs.h" #include /* // Common C/C++ structure to handle pattern data typedef struct __attribute__((packed)) { uint64_t word[MAX_PATTERN_LENGTH]; uint64_t ioctrl; uint32_t limits[2]; // loop0 start, loop0 stop .. loop2 start, loop2 stop uint32_t loop[6]; uint32_t nloop[3]; uint32_t wait[3]; uint64_t waittime[3]; } patternParameters; */ int chipStatusRegister=0; int setBit(int ibit, int patword) { return patword |= (1 << ibit); } int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); } extern enum TLogLevel trimmingPrint ; int getChipStatusRegister(){ return chipStatusRegister; } int gainCapsToCsr(int caps){ //Translates bit representation int csr = 0; if (!(caps & M3_C10pre)) csr |= 1 << _CSR_C10pre; if (caps & M3_C15sh) csr |= 1 << CSR_C15sh; if (caps & M3_C30sh) csr |= 1 << CSR_C30sh; if (caps & M3_C50sh) csr |= 1 << CSR_C50sh; if (caps & M3_C225ACsh) csr |= 1 << CSR_C225ACsh; if (!(caps & M3_C15pre)) csr |= 1 << _CSR_C15pre; return csr; } int csrToGainCaps(int csr){ //Translates bit representation int caps = 0; if (!(csr & (1 << _CSR_C10pre))) caps |= M3_C10pre; if (csr & (1 << CSR_C15sh)) caps |= M3_C15sh; if (csr & (1 << CSR_C30sh)) caps |= M3_C30sh; if (csr & (1 << CSR_C50sh)) caps |= M3_C50sh; if (csr & (1 << CSR_C225ACsh)) caps |= M3_C225ACsh; if (!(csr & (1 << _CSR_C15pre))) caps |= M3_C15pre; return caps; } patternParameters *setChipStatusRegisterPattern(int csr) { int iaddr=0; int nbits=18; int error=0; //int start=0, stop=MAX_PATTERN_LENGTH, loop=0; int patword=0; patternParameters *pat = malloc(sizeof(patternParameters)); memset(pat, 0, sizeof(patternParameters)); patword=setBit(SIGNAL_STATLOAD,patword); for (int i=0; i<2; i++) pat->word[iaddr++]=patword; patword=setBit(SIGNAL_resStorage,patword); patword=setBit(SIGNAL_resCounter,patword); for (int i=0; i<8; i++) pat->word[iaddr++]=patword; patword=clearBit(SIGNAL_resStorage,patword); patword=clearBit(SIGNAL_resCounter,patword); for (int i=0; i<8; i++) pat->word[iaddr++]=patword; //#This version of the serializer pushes in the MSB first (compatible with the CSR bit numbering) for (int ib=nbits-1; ib>=0; ib--) { if (csr&(1<word[iaddr++]=patword; patword=setBit(SIGNAL_CHSclk,patword); pat->word[iaddr++]=patword; patword=clearBit(SIGNAL_CHSclk,patword); pat->word[iaddr++]=patword; } patword=clearBit(SIGNAL_serialIN,patword); for (int i=0; i<2; i++) pat->word[iaddr++]=patword; patword=setBit(SIGNAL_STO,patword); for (int i=0; i<5; i++) pat->word[iaddr++]=patword; patword=clearBit(SIGNAL_STO,patword); for (int i=0; i<5; i++) pat->word[iaddr++]=patword; patword=clearBit(SIGNAL_STATLOAD,patword); for (int i=0; i<5; i++) pat->word[iaddr++]=patword; if (iaddr >= MAX_PATTERN_LENGTH) { LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n", iaddr, MAX_PATTERN_LENGTH)); error = 1; } // set pattern wait address for (int i = 0; i <= 2; i++) pat->wait[i]=MAX_PATTERN_LENGTH - 1; // pattern loop for (int i = 0; i <= 2; i++) { //int stop = MAX_PATTERN_LENGTH - 1, nloop = 0; pat->loop[i * 2 + 0]=MAX_PATTERN_LENGTH - 1; pat->loop[i * 2 + 1]=MAX_PATTERN_LENGTH - 1; pat->nloop[i]=0; } // pattern limits { pat->limits[0]=0; pat->limits[1]=iaddr; } if (error != 0) { free(pat); return NULL; } chipStatusRegister=csr; return pat; } patternParameters *setInterpolation(int mask) { int csr; if (mask) csr=chipStatusRegister|(1<< CSR_interp); else csr=chipStatusRegister & ~(1<< CSR_interp); return setChipStatusRegisterPattern(csr); } patternParameters *setPumpProbe(int mask) { int csr; if (mask) csr=chipStatusRegister|(1<< CSR_pumprobe); else csr=chipStatusRegister & ~(1<< CSR_pumprobe); return setChipStatusRegisterPattern(csr); } patternParameters *setDigitalPulsing(int mask) { int csr; if (mask) csr=chipStatusRegister|(1<< CSR_dpulse); else csr=chipStatusRegister & ~(1<< CSR_dpulse); return setChipStatusRegisterPattern(csr); } patternParameters *setAnalogPulsing(int mask){ int csr; if (mask) csr=chipStatusRegister|(1<< CSR_apulse); else csr=chipStatusRegister & ~(1<< CSR_apulse); return setChipStatusRegisterPattern(csr); } patternParameters *setNegativePolarity(int mask){ int csr; if (mask) csr=chipStatusRegister|(1<< CSR_invpol); else csr=chipStatusRegister & ~(1<< CSR_invpol); return setChipStatusRegisterPattern(csr); } patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits) { patternParameters *pat = malloc(sizeof(patternParameters)); memset(pat, 0, sizeof(patternParameters)); // validate for (int ichan = ichip * NCHAN_1_COUNTER * NCOUNTERS; ichan < ichip * NCHAN_1_COUNTER * NCOUNTERS+NCHAN_1_COUNTER*NCOUNTERS; ichan++) { if (trimbits[ichan]<0) { LOG(logERROR, ("Trimbit value (%d) for channel %d is invalid - setting it to 0\n", trimbits[ichan], ichan)); trimbits[ichan]=0; } if (trimbits[ichan] > 63) { LOG(logERROR, ("Trimbit value (%d) for channel %d is invalid - settings it to 63\n", trimbits[ichan], ichan)); trimbits[ichan]=63; } } LOG(logINFO, ("Trimbits validated\n")); trimmingPrint = logDEBUG5; // trimming int error = 0; uint64_t patword = 0; int iaddr = 0; LOG(logDEBUG1, (" Chip %d\n", ichip)); iaddr = 0; patword = 0; pat->word[iaddr++]=patword; // chip select patword = setBit(SIGNAL_TBLoad_1 + ichip, patword); pat->word[iaddr++]=patword; // reset trimbits patword = setBit(SIGNAL_resStorage, patword); patword = setBit(SIGNAL_resCounter, patword); pat->word[iaddr++]=patword; pat->word[iaddr++]=patword; patword = clearBit(SIGNAL_resStorage, patword); patword = clearBit(SIGNAL_resCounter, patword); pat->word[iaddr++]=patword; pat->word[iaddr++]=patword; // select first channel patword = setBit(SIGNAL_CHSserialIN, patword); pat->word[iaddr++]=patword; // 1 clk pulse patword = setBit(SIGNAL_CHSclk, patword); pat->word[iaddr++]=patword; patword = clearBit(SIGNAL_CHSclk, patword); // clear 1st channel pat->word[iaddr++]=patword; patword = clearBit(SIGNAL_CHSserialIN, patword); // 2 clk pulses for (int i = 0; i < 2; i++) { patword = setBit(SIGNAL_CHSclk, patword); pat->word[iaddr++]=patword; patword = clearBit(SIGNAL_CHSclk, patword); pat->word[iaddr++]=patword; } // for each channel (all chips) for (int ich = 0; ich < NCHAN_1_COUNTER; ich++) { LOG(logDEBUG1, (" Chip %d, Channel %d\n", ichip, ich)); int val = trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS + NCOUNTERS * ich] + trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS + NCOUNTERS * ich + 1] * 64 + trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS + NCOUNTERS * ich + 2] * 64 * 64; // push 6 0 bits for (int i = 0; i < 3; i++) { patword = clearBit(SIGNAL_serialIN, patword); patword = clearBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; patword = setBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; } for (int i = 0; i < 3; i++) { if (mask[i]) patword = setBit(SIGNAL_serialIN, patword); else patword = clearBit(SIGNAL_serialIN, patword); patword = clearBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; patword = setBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; } // deserialize for (int i = 0; i < 18; i++) { if (val & (1 << i)) { patword = setBit(SIGNAL_serialIN, patword); } else { patword = clearBit(SIGNAL_serialIN, patword); } patword = clearBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; patword = setBit(SIGNAL_clk, patword); pat->word[iaddr++]=patword; } pat->word[iaddr++]=patword; pat->word[iaddr++]=patword; // move to next channel for (int i = 0; i < 3; i++) { patword = setBit(SIGNAL_CHSclk, patword); pat->word[iaddr++]=patword; patword = clearBit(SIGNAL_CHSclk, patword); pat->word[iaddr++]=patword; } } // chip unselect patword = clearBit(SIGNAL_TBLoad_1 + ichip, patword); pat->word[iaddr++]=patword; // last iaddr check if (iaddr >= MAX_PATTERN_LENGTH) { LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n", iaddr, MAX_PATTERN_LENGTH)); error = 1; } if (iaddr >= MAX_PATTERN_LENGTH) { LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n", iaddr, MAX_PATTERN_LENGTH)); error = 1; } // set pattern wait address for (int i = 0; i <= 2; i++) pat->wait[i]=MAX_PATTERN_LENGTH - 1; // pattern loop for (int i = 0; i <= 2; i++) { //int stop = MAX_PATTERN_LENGTH - 1, nloop = 0; pat->loop[i * 2 + 0]=MAX_PATTERN_LENGTH - 1; pat->loop[i * 2 + 1]=MAX_PATTERN_LENGTH - 1; pat->nloop[i]=0; } // pattern limits { pat->limits[0]=0; pat->limits[1]=iaddr; } trimmingPrint = logINFO; if (error == 0) { LOG(logINFO, ("All trimbits have been loaded\n")); } else { free(pat); return NULL; } return pat; }