#include "mythen3.h" #include "clogger.h" #include "common.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); } 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 << ib)) patword = setBit(SIGNAL_serialIN, patword); else patword = clearBit(SIGNAL_serialIN, patword); for (int i = 0; i < 4; i++) pat->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")); // 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; } if (error == 0) { LOG(logINFO, ("All trimbits have been loaded\n")); } else { free(pat); return NULL; } return pat; }