diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index ee7182f16..cc4d43934 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -197,6 +197,8 @@ int isChipConfigured(); int powerChip(int on, char *mess); int getPowerChip(); int configureChip(char *mess); +int readConfigFile(char *mess, char *fileName, char *fileType); +int resetChip(char *mess); #endif #if defined(JUNGFRAUD) || defined(MOENCHD) || defined(CHIPTESTBOARDD) || \ defined(MYTHEN3D) || defined(GOTTHARD2D) @@ -742,8 +744,7 @@ int softwareTrigger(); #if defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD) int softwareTrigger(int block); #endif -#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD) || \ - defined(XILINX_CHIPTESTBOARDD) +#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD) int startReadOut(); #endif enum runStatus getRunStatus(); diff --git a/slsDetectorServers/slsDetectorServer/src/loadPattern.c b/slsDetectorServers/slsDetectorServer/src/loadPattern.c index 6065d0076..90ef5b6d4 100644 --- a/slsDetectorServers/slsDetectorServer/src/loadPattern.c +++ b/slsDetectorServers/slsDetectorServer/src/loadPattern.c @@ -853,7 +853,7 @@ int loadPattern(char *message, enum TLogLevel printLevel, } } // iocontrol -#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO +#if !defined(MYTHEN3D) if (ret == OK) { ret = validate_writePatternIOControl(message, pat->ioctrl); } @@ -914,7 +914,7 @@ int getPattern(char *message, patternParameters *pat) { pat->word[i] = retval64; } // iocontrol -#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO +#if !defined(MYTHEN3D) if (ret == OK) { validate_readPatternIOControl(); } @@ -1051,12 +1051,12 @@ int loadPatternFile(char *patFname, char *errMessage) { } // patioctrl -#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO +#if !defined(MYTHEN3D) // TODO if (!strncmp(line, "patioctrl", strlen("patioctrl"))) { uint64_t arg = 0; // cannot scan values -#ifdef VIRTUAL +#if defined(VIRTUAL) || defined(XILINX_CHIPTESTBOARDD) if (sscanf(line, "%s 0x%lx", command, &arg) != 2) { #else if (sscanf(line, "%s 0x%llx", command, &arg) != 2) { diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 9d133f7f4..94657697f 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -8467,8 +8467,7 @@ int get_bursts_left(int file_des) { int start_readout(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); -#if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD) && \ - !defined(XILINX_CHIPTESTBOARDD) +#if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD) functionNotImplemented(); #else if (Server_VerifyLock() == OK) { diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/CMakeLists.txt b/slsDetectorServers/xilinx_ctbDetectorServer/CMakeLists.txt index 78a5fbfb7..db081528a 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/xilinx_ctbDetectorServer/CMakeLists.txt @@ -40,3 +40,9 @@ set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES install(TARGETS xilinx_ctbDetectorServer_virtual RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + +configure_file(chip_config_xilinx.txt ${CMAKE_BINARY_DIR}/bin/chip_config_xilinx.txt COPYONLY) +configure_file(reset_chip_xilinx.txt ${CMAKE_BINARY_DIR}/bin/reset_chip_xilinx.txt COPYONLY) +configure_file(enable_clock_pattern.pyat ${CMAKE_BINARY_DIR}/bin/enable_clock_pattern.pyat COPYONLY) +configure_file(readout_pattern.pyat ${CMAKE_BINARY_DIR}/bin/readout_pattern.pyat COPYONLY) + diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/Makefile b/slsDetectorServers/xilinx_ctbDetectorServer/Makefile index c271efdfe..59cf0fe37 100755 --- a/slsDetectorServers/xilinx_ctbDetectorServer/Makefile +++ b/slsDetectorServers/xilinx_ctbDetectorServer/Makefile @@ -48,6 +48,10 @@ $(PROGS): $(OBJS) mkdir -p $(DESTDIR) $(CC) -o $@ $^ $(CFLAGS) $(LDLIBS) mv $(PROGS) $(DESTDIR) + cp chip_config_xilinx.txt $(DESTDIR) + cp reset_chip_xilinx.txt $(DESTDIR) + cp enable_clock_pattern.pyat $(DESTDIR) + cp readout_pattern.pyat $(DESTDIR) rm $(main_src)*.o $(md5_dir)*.o clean: rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h b/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h index 3563a8b82..6059d1e8f 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h @@ -17,12 +17,24 @@ #define EMPTY4REG (0x4) -#define STATUSREG1 (0x8) +#define STATUS_REG (0x8) -#define TRANSMISSIONBUSY_OFST (0) -#define TRANSMISSIONBUSY_MSK (0x00000001 << TRANSMISSIONBUSY_OFST) +#define PATTERN_RUNNING_OFST (0) +#define PATTERN_RUNNING_MSK (0x00000001 << PATTERN_RUNNING_OFST) +#define RX_BUSY_OFST (1) +#define RX_BUSY_MSK (0x00000001 << RX_BUSY_OFST) +#define PROCESSING_BUSY_OFST (2) +#define PROCESSING_BUSY_MSK (0x00000001 << PROCESSING_BUSY_OFST) +#define UDP_GEN_BUSY_OFST (3) +#define UDP_GEN_BUSY_MSK (0x00000001 << UDP_GEN_BUSY_OFST) +#define NETWORK_BUSY_OFST (4) +#define NETWORK_BUSY_MSK (0x00000001 << NETWORK_BUSY_OFST) +#define WAIT_FOR_TRIGGER_OFST (5) +#define WAIT_FOR_TRIGGER_MSK (0x00000001 << WAIT_FOR_TRIGGER_OFST) +#define RX_NOT_GOOD_OFST (6) +#define RX_NOT_GOOD_MSK (0x00000001 << RX_NOT_GOOD_OFST) -#define STATUSREG2 (0xC) +#define STATUS_REG2 (0xC) #define FPGAVERSIONREG (0x10) @@ -31,7 +43,7 @@ #define FPGADETTYPE_OFST (24) #define FPGADETTYPE_MSK (0x000000ff << FPGADETTYPE_OFST) -#define EMPTY14REG (0x14) +#define FPGA_GIT_HEAD (0x14) #define FIXEDPATTERNREG (0x18) #define FIXEDPATTERNVAL (0xACDC2016) @@ -889,7 +901,10 @@ #define GTTPOWERGOOD_OFST (26) #define GTTPOWERGOOD_MSK (0x0000000f << GTTPOWERGOOD_OFST) -#define EMPTY654REG (0x654) +#define TRANSCEIVERSTATUS2 (0x654) + +#define RXLOCKED_OFST (0) +#define RXLOCKED_MSK (0x0000000f << RXLOCKED_OFST) #define TRANSCEIVERCONTROL (0x658) @@ -905,30 +920,58 @@ #define RESETRXDATAPATHIN_MSK (0x00000001 << RESETRXDATAPATHIN_OFST) #define RXPOLARITY_OFST (5) #define RXPOLARITY_MSK (0x0000000f << RXPOLARITY_OFST) +#define RXERRORCNTRESET_OFST (9) +#define RXERRORCNTRESET_MSK (0x0000000f << RXERRORCNTRESET_OFST) +#define RXMSBLSBINVERT_OFST (13) +#define RXMSBLSBINVERT_MSK (0x0000000f << RXMSBLSBINVERT_OFST) -#define EMPTY65CREG (0x65C) +#define TRANSCEIVERERRCNT_REG0 (0x65C) -#define EMPTY660REG (0x660) +#define TRANSCEIVERERRCNT_REG1 (0x660) -#define EMPTY664REG (0x664) +#define TRANSCEIVERERRCNT_REG2 (0x664) -#define EMPTY668REG (0x668) +#define TRANSCEIVERERRCNT_REG3 (0x668) -#define EMPTY66CREG (0x66C) +#define TRANSCEIVERALIGNCNT_REG0 (0x66C) -#define EMPTY670REG (0x670) +#define RXALIGNCNTCH0_OFST (0) +#define RXALIGNCNTCH0_MSK (0x0000ffff << RXALIGNCNTCH0_OFST) -#define EMPTY674REG (0x674) +#define TRANSCEIVERALIGNCNT_REG1 (0x670) -#define EMPTY678REG (0x678) +#define RXALIGNCNTCH1_OFST (0) +#define RXALIGNCNTCH1_MSK (0x0000ffff << RXALIGNCNTCH1_OFST) -#define EMPTY67CREG (0x67C) +#define TRANSCEIVERALIGNCNT_REG2 (0x674) -#define EMPTY680REG (0x680) +#define RXALIGNCNTCH2_OFST (0) +#define RXALIGNCNTCH2_MSK (0x0000ffff << RXALIGNCNTCH2_OFST) -#define EMPTY684REG (0x684) +#define TRANSCEIVERALIGNCNT_REG3 (0x678) -#define EMPTY688REG (0x688) +#define RXALIGNCNTCH3_OFST (0) +#define RXALIGNCNTCH3_MSK (0x0000ffff << RXALIGNCNTCH3_OFST) + +#define TRANSCEIVERLASTWORD_REG0 (0x67C) + +#define RXDATACH0_OFST (0) +#define RXDATACH0_MSK (0x0000ffff << RXDATACH0_OFST) + +#define TRANSCEIVERLASTWORD_REG1 (0x680) + +#define RXDATACH1_OFST (0) +#define RXDATACH1_MSK (0x0000ffff << RXDATACH1_OFST) + +#define TRANSCEIVERLASTWORD_REG2 (0x684) + +#define RXDATACH2_OFST (0) +#define RXDATACH2_MSK (0x0000ffff << RXDATACH2_OFST) + +#define TRANSCEIVERLASTWORD_REG3 (0x688) + +#define RXDATACH3_OFST (0) +#define RXDATACH3_MSK (0x0000ffff << RXDATACH3_OFST) #define EMPTY68CREG (0x68C) diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer index 15bb18072..2617952ec 100755 Binary files a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer and b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer differ diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/chip_config_xilinx.txt b/slsDetectorServers/xilinx_ctbDetectorServer/chip_config_xilinx.txt new file mode 100644 index 000000000..0aac43aad --- /dev/null +++ b/slsDetectorServers/xilinx_ctbDetectorServer/chip_config_xilinx.txt @@ -0,0 +1,24 @@ +# Prepare MH02 configuration +reg 0x600 0x00000041 +reg 0x604 0x01200004 + +# configure Matterhorn SPI +setbit 0x608 0 + +# wait till config is done +pollbit 0x608 3 0 + +# reset transceiver +reg 0x658 0x0 +reg 0x658 0x1 +reg 0x658 0x0 + +# set MSB LSB inversions and polarity for transceiver +reg 0x658 0x61e0 + +# Enable MH02 PLL clock +patternX enable_clock_pattern.pyat +# start the flow +setbit 0x108 0 +clearbit 0x108 0 +sleep 1 diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/enable_clock_pattern.pyat b/slsDetectorServers/xilinx_ctbDetectorServer/enable_clock_pattern.pyat new file mode 100644 index 000000000..debfbbd27 --- /dev/null +++ b/slsDetectorServers/xilinx_ctbDetectorServer/enable_clock_pattern.pyat @@ -0,0 +1,8 @@ +patword 0x0000 0x0000000000000000 +patword 0x0001 0x0000000000008000 +patword 0x0002 0x0000000000008000 +patword 0x0003 0x0000000000008000 +patword 0x0004 0x0000000000008000 +patword 0x0005 0x0000000000008000 +patioctrl 0x01b3ffff +patlimits 0x0000 0x0005 diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/readout_pattern.pyat b/slsDetectorServers/xilinx_ctbDetectorServer/readout_pattern.pyat new file mode 100644 index 000000000..fb5520142 --- /dev/null +++ b/slsDetectorServers/xilinx_ctbDetectorServer/readout_pattern.pyat @@ -0,0 +1,22 @@ +patword 0x0000 0x0000000000008000 +patword 0x0001 0x0000000000008000 +patword 0x0002 0x0000000000008000 +patword 0x0003 0x0000000000008000 +patword 0x0004 0x0000000000008000 +patword 0x0005 0x0000000000008000 +patword 0x0006 0x0000000000008000 +patword 0x0007 0x0000000000008000 +patword 0x0008 0x0000000000008000 +patword 0x0009 0x0000000000008000 +patword 0x000a 0x0000000000008000 +patword 0x000b 0x0000000000108000 +patword 0x000c 0x0000000000108000 +patword 0x000d 0x0000000000108000 +patword 0x000e 0x0000000000108000 +patword 0x000f 0x0000000000008000 +patword 0x0010 0x0000000000008000 +patword 0x0011 0x0000000000008000 +patword 0x0012 0x0000000000008000 +patword 0x0013 0x0000000000008000 +patioctrl 0x01b3ffff +patlimits 0x0000 0x0013 \ No newline at end of file diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/reset_chip_xilinx.txt b/slsDetectorServers/xilinx_ctbDetectorServer/reset_chip_xilinx.txt new file mode 100644 index 000000000..70892384f --- /dev/null +++ b/slsDetectorServers/xilinx_ctbDetectorServer/reset_chip_xilinx.txt @@ -0,0 +1,40 @@ + +# turn off clock +setbit 0x600 16 +setbit 0x608 0 +sleep 1 + +# reset Matterhorn periphery +setbit 0x608 1 +sleep 1 + +# turn on clock +clearbit 0x600 16 +setbit 0x608 0 +sleep 1 + +# reset rx transceiver datapath +setbit 0x658 4 +sleep 1 + +# reset 8b10b counters +setbit 0x658 9 +setbit 0x658 10 +setbit 0x658 11 +setbit 0x658 12 +sleep 1 +clearbit 0x658 9 +clearbit 0x658 10 + +# reset buffer fifos +reg 0x5C8 0xFFFFFFFF +reg 0x5D0 0xFFFFFFFF +reg 0x5D8 0xFFFFFFFF +reg 0x5C8 0x0 +reg 0x5D0 0x0 +reg 0x5D8 0x0 +setbit 0x500 18 + +# load default pattern +patternX readout_pattern.pyat + diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c index d0b42841a..75f66efd7 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c @@ -492,7 +492,16 @@ void setTransceiverAlignment(int align) { #endif int isTransceiverAligned() { - return (bus_r(TRANSCEIVERSTATUS) & RXBYTEISALIGNED_MSK); + int times = 0; + int retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK; + while (retval) { + retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK; + times++; + usleep(10); + if (times == 5) + return 1; + } + return retval; } int waitTransceiverAligned(char *mess) { @@ -511,7 +520,9 @@ int waitTransceiverAligned(char *mess) { int times = 0; while (transceiverWordAligned == 0) { if (times++ > WAIT_TIME_OUT_0US_TIMES) { - sprintf(mess, "Transceiver alignment timed out\n"); + sprintf(mess, "Transceiver alignment timed out. Check connection, " + "p-n inversions, LSB-MSB inversions, link error " + "counters and channel enable settings\n"); LOG(logERROR, (mess)); return FAIL; } @@ -587,34 +598,197 @@ int getPowerChip() { int configureChip(char *mess) { LOG(logINFOBLUE, ("\tConfiguring chip\n")); - - // enable correct endianness (Only for MH_PR_2) - // uint32_t addr = MATTERHORNSPIREG1; - // bus_w(addr, bus_r(addr) &~MATTERHORNSPI1_MSK); - // bus_w(addr, bus_r(addr) | ((0x40000 << MATTERHORNSPI1_OFST) & - // MATTERHORNSPI1_MSK)); - - // start configuration - uint32_t addr = MATTERHORNSPICTRL; - bus_w(addr, bus_r(addr) | CONFIGSTART_P_MSK); - bus_w(addr, bus_r(addr) & ~CONFIGSTART_P_MSK); - - // wait until configuration is done -#ifndef VIRTUAL - int configDone = (bus_r(MATTERHORNSPICTRL) & BUSY_MSK); - int times = 0; - while (configDone == 0) { - if (times++ > WAIT_TIME_OUT_0US_TIMES) { - sprintf(mess, "Configuration of chip timed out\n"); - LOG(logERROR, (mess)); - return FAIL; - } - usleep(0); - configDone = (bus_r(MATTERHORNSPICTRL) & BUSY_MSK); + chipConfigured = 0; + if (readConfigFile(mess, CONFIG_CHIP_FILE, "chip config") == FAIL) { + return FAIL; } -#endif + if (readConfigFile(mess, RESET_CHIP_FILE, "reset chip") == FAIL) { + return FAIL; + } + LOG(logINFOBLUE, ("Chip configured.\n")); chipConfigured = 1; - LOG(logINFOBLUE, ("\tChip configured\n")); + return OK; +} + +int readConfigFile(char *mess, char *fileName, char *fileType) { + const int fileNameSize = 128; + char fname[fileNameSize]; + if (getAbsPath(fname, fileNameSize, fileName) == FAIL) { + sprintf(mess, "Could not get full path for %s file [%s].\n", fileType, + fname); + LOG(logERROR, (mess)); + return FAIL; + } + if (access(fname, F_OK) != 0) { + sprintf(mess, "Could not find %s file [%s].\n", fileType, fname); + LOG(logERROR, (mess)); + return FAIL; + } + FILE *fd = fopen(fname, "r"); + if (fd == NULL) { + sprintf(mess, "Could not open on-board detector server %s file [%s].\n", + fileType, fname); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFOBLUE, ("Reading %s file %s\n", fileType, fname)); + + const size_t LZ = 256; + char line[LZ]; + memset(line, 0, LZ); + char command[LZ]; + + // keep reading a line + while (fgets(line, LZ, fd)) { + + // ignore comments + if (line[0] == '#') { + LOG(logDEBUG1, ("Ignoring Comment\n")); + continue; + } + + // ignore empty lines + if (strlen(line) <= 1) { + LOG(logDEBUG1, ("Ignoring Empty line\n")); + continue; + } + + // removing leading spaces + if (line[0] == ' ' || line[0] == '\t') { + int len = strlen(line); + // find first valid character + int i = 0; + for (i = 0; i < len; ++i) { + if (line[i] != ' ' && line[i] != '\t') { + break; + } + } + // ignore the line full of spaces (last char \n) + if (i >= len - 1) { + LOG(logDEBUG1, ("Ignoring line full of spaces\n")); + continue; + } + // copying only valid char + char temp[LZ]; + memset(temp, 0, LZ); + memcpy(temp, line + i, strlen(line) - i); + memset(line, 0, LZ); + memcpy(line, temp, strlen(temp)); + LOG(logDEBUG1, ("Removing leading spaces.\n")); + } + + LOG(logDEBUG1, ("Command to process: (size:%d) %.*s\n", strlen(line), + strlen(line) - 1, line)); + memset(command, 0, LZ); + + // reg command + if (!strncmp(line, "reg", strlen("reg"))) { + uint32_t addr = 0; + uint32_t val = 0; + if (sscanf(line, "%s %x %x", command, &addr, &val) != 3) { + sprintf(mess, "Could not scan reg command. Line:[%s].\n", line); + LOG(logERROR, (mess)); + return FAIL; + } + bus_w(addr, val); + LOG(logINFOBLUE, ("Wrote 0x%x to 0x%x\n", val, addr)); + } + + // setbit command + else if (!strncmp(line, "setbit", strlen("setbit"))) { + uint32_t addr = 0; + uint32_t bit = 0; + if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) { + sprintf(mess, "Could not scan setbit command. Line:[%s].\n", + line); + LOG(logERROR, (mess)); + return FAIL; + } + bus_w(addr, bus_r(addr) | (1 << bit)); + LOG(logINFOBLUE, ("Set bit %d in 0x%x\n", bit, addr)); + } + + // clearbit command + else if (!strncmp(line, "clearbit", strlen("clearbit"))) { + uint32_t addr = 0; + uint32_t bit = 0; + if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) { + sprintf(mess, "Could not scan clearbit command. Line:[%s].\n", + line); + LOG(logERROR, (mess)); + return FAIL; + } + bus_w(addr, bus_r(addr) & ~(1 << bit)); + LOG(logINFOBLUE, ("Cleared bit %d in 0x%x\n", bit, addr)); + } + + // pollbit command + else if (!strncmp(line, "pollbit", strlen("pollbit"))) { + uint32_t addr = 0; + uint32_t bit = 0; + uint32_t val = 0; + if (sscanf(line, "%s %x %d %d", command, &addr, &bit, &val) != 4) { + sprintf(mess, "Could not scan pollbit command. Line:[%s].\n", + line); + LOG(logERROR, (mess)); + return FAIL; + } +#ifndef VIRTUAL + int times = 0; + while (((bus_r(addr) >> bit) & 0x1) != val) { + if (times++ > WAIT_TIME_OUT_0US_TIMES) { + sprintf(mess, "Polling bit %d in 0x%x timed out\n", bit, + addr); + LOG(logERROR, (mess)); + return FAIL; + } + usleep(0); + } +#endif + LOG(logINFOBLUE, ("Polled bit %d in 0x%x\n", bit, addr)); + } + + // patternX command + else if (!strncmp(line, "patternX", strlen("patternX"))) { + // take a file name and call loadPAtterFile + char patternFileName[LZ]; + if (sscanf(line, "%s %s", command, patternFileName) != 2) { + sprintf(mess, "Could not scan patternX command. Line:[%s].\n", + line); + LOG(logERROR, (mess)); + return FAIL; + } + if (loadPatternFile(patternFileName, mess) == FAIL) { + return FAIL; + } + LOG(logINFOBLUE, ("loaded pattern [%s].\n", patternFileName)); + } + + // sleep command + else if (!strncmp(line, "sleep", strlen("sleep"))) { + int time = 0; + if (sscanf(line, "%s %d", command, &time) != 2) { + sprintf(mess, "Could not scan sleep command. Line:[%s].\n", + line); + LOG(logERROR, (mess)); + return FAIL; + } + usleep(time * 1000 * 1000); + LOG(logINFOBLUE, ("Slept for %d s\n", time)); + } + + // other commands + else { + sprintf(mess, + "Could not scan command from on-board server " + "%s file. Line:[%s].\n", + fileType, line); + break; + } + memset(line, 0, LZ); + } + fclose(fd); + LOG(logINFOBLUE, ("Successfully read %s file.\n", fileType)); return OK; } @@ -1328,31 +1502,13 @@ int startStateMachine() { return OK; #endif - LOG(logINFOBLUE, ("Starting State Machine\n")); - // cleanFifos(); removing this for now as its done before readout pattern + LOG(logINFOBLUE, ("Starting readout\n")); - // start state machine - bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK); - - LOG(logINFORED, ("Waiting for exposing to be done\n")); - int exposingDone = (bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK); - while (exposingDone != 0) { - usleep(0); - exposingDone = (bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK); - } - - LOG(logINFORED, ("Starting readout of chip to fifo\n")); + // MM:readout via pattern does not work right now due to firmware bug, + // readout via MatterhornCTRL for the moment + // bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK); bus_w(MATTERHORNSPICTRL, bus_r(MATTERHORNSPICTRL) | STARTREAD_P_MSK); - LOG(logINFORED, ("Waiting until k-words or end of acquisition\n")); - usleep(0); - int commaDet = (bus_r(TRANSCEIVERSTATUS) & RXCOMMADET_MSK); - while (commaDet == 0) { - usleep(0); - commaDet = (bus_r(TRANSCEIVERSTATUS) & RXCOMMADET_MSK); - } - LOG(logINFORED, ("Kwords or end of acquisition detected\n")); - return OK; } @@ -1467,56 +1623,6 @@ int stopStateMachine() { return OK; } -int startReadOut() { - LOG(logINFOBLUE, ("Starting Readout\n")); -#ifdef VIRTUAL - // cannot set #frames and exptiem temporarily to 1 and 0, - // because have to set it back after readout (but this is non blocking) - return startStateMachine(); -#endif - // check if data in fifo - int ret = FAIL; - if (transceiverEnable) { - if ((bus_r(X_FIFO_EMPTY_STATUS_REG) & X_FIFO_EMPTY_STATUS_MSK) != - X_FIFO_EMPTY_STATUS_MSK) { - LOG(logINFO, ("Data in transceiver fifo\n")); - ret = OK; - } - } - if (analogEnable) { - if (bus_r(A_FIFO_EMPTY_STATUS_REG) != BIT32_MSK) { - LOG(logINFO, ("Data in analog fifo\n")); - ret = OK; - } - } - if (digitalEnable) { - if ((bus_r(D_FIFO_EMPTY_STATUS_REG) & D_FIFO_EMPTY_STATUS_MSK) != - D_FIFO_EMPTY_STATUS_MSK) { - LOG(logINFO, ("Data in digital fifo\n")); - ret = OK; - } - } - // if no module, dont check fifo empty - if (checkModuleFlag && ret == FAIL) { - LOG(logERROR, ("No data in fifo\n")); - return FAIL; - } - - LOG(logINFOBLUE, ("Streaming data from fifo\n")); - bus_w(FIFO_TO_GB_CONTROL_REG, - bus_r(FIFO_TO_GB_CONTROL_REG) | START_STREAMING_P_MSK); - - // wait until streaming is done (not same as fifo empty) - int streamingBusy = (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK); - while (streamingBusy != 0) { - usleep(0); - streamingBusy = (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK); - } - LOG(logINFORED, ("Streaming done\n")); - - return OK; -} - int softwareTrigger() { #ifndef VIRTUAL // ready for trigger @@ -1552,36 +1658,33 @@ enum runStatus getRunStatus() { LOG(logINFOBLUE, ("Status: IDLE\n")); return IDLE; #endif - uint32_t retval = bus_r(FLOW_STATUS_REG); - LOG(logINFO, ("Flow Status Register: %08x\n", retval)); + uint32_t retval = bus_r(STATUS_REG); + LOG(logINFO, ("Status Register: %08x\n", retval)); - if (retval & RSM_TRG_WAIT_MSK) { - LOG(logINFOBLUE, ("Status: WAITING\n")); - return WAITING; - } else if (retval & RSM_BUSY_MSK) { - LOG(logINFOBLUE, ("Status: RUNNING (exposing)\n")); - return RUNNING; - } else if (bus_r(MATTERHORNSPICTRL) & READOUTFROMASIC_MSK) { - LOG(logINFOBLUE, ("Status: RUNNING (data from chip to fifo)\n")); - return RUNNING; - } else if (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK) { - LOG(logINFOBLUE, ("Status: TRANSMITTING\n")); - return TRANSMITTING; + if (retval == 0x0) { + return IDLE; } - LOG(logINFOBLUE, ("Status: IDLE\n")); - return IDLE; - // TODO: STOPPED, ERROR? + if (retval & RX_NOT_GOOD_MSK) { + LOG(logINFOBLUE, ("Status: ERROR\n")); + return ERROR; + } + + if (retval & WAIT_FOR_TRIGGER_MSK) { + LOG(logINFOBLUE, ("Status: WAITING\n")); + return WAITING; + } + + LOG(logINFOBLUE, ("Status: RUNNING\n")); + return RUNNING; + // TODO: STOPPED? } u_int32_t runBusy() { #ifdef VIRTUAL return ((sharedMemory_getStatus() == RUNNING) ? 1 : 0); #endif - uint32_t exposingBusy = bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK; - uint32_t fillingFifoBusy = bus_r(MATTERHORNSPICTRL) & READOUTFROMASIC_MSK; - uint32_t streamingBusy = bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK; - return (exposingBusy || fillingFifoBusy || streamingBusy); + return (bus_r(STATUS_REG)); } void waitForAcquisitionEnd() { diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h index 54cb758de..df291c0d2 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h @@ -4,7 +4,7 @@ #include "RegisterDefs.h" #include "sls/sls_detector_defs.h" -#define REQRD_FRMWRE_VRSN (0x230710) +#define REQRD_FRMWRE_VRSN (0x250203) #define KERNEL_DATE_VRSN "Wed Nov 29 17:32:14 CET 2023" #define LINKED_SERVER_NAME "xilinx_ctbDetectorServer" @@ -40,6 +40,9 @@ #define SLOWADC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ai%d" #define TEMP_DRIVER_FILE_NAME DEVICE_TREE_DST "0/in_temp7_input" +#define CONFIG_CHIP_FILE "chip_config_xilinx.txt" +#define RESET_CHIP_FILE "reset_chip_xilinx.txt" + /** Default Parameters */ #define DEFAULT_NUM_FRAMES (1) #define DEFAULT_NUM_CYCLES (1) diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 6018bc31c..7fa4f1d0e 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -7,7 +7,7 @@ #define APIEIGER "developer 0x241107" #define APILIB "developer 0x241122" #define APIRECEIVER "developer 0x241122" -#define APIXILINXCTB "developer 0x250131" #define APICTB "developer 0x250131" #define APIMYTHEN3 "developer 0x250131" +#define APIXILINXCTB "developer 0x250213" #define APIJUNGFRAU "developer 0x250218"