From be50344b45c991bbb7c26ab3537ce548c634a2b0 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 17 Oct 2019 16:39:41 +0200 Subject: [PATCH] set clock divider, phase and get clock freq for gotthard2, priliminary --- .../gotthard2DetectorServer/CMakeLists.txt | 1 + .../gotthard2DetectorServer/Makefile | 4 +- .../gotthard2DetectorServer/RegisterDefs.h | 33 +- .../slsDetectorFunctionList.c | 191 +++++++++++- .../slsDetectorServer_defs.h | 15 +- .../include/ALTERA_PLL_CYCLONE10.h | 72 +++++ .../slsDetectorServer/include/nios.h | 13 + .../include/slsDetectorFunctionList.h | 17 ++ .../include/slsDetectorServer_funcs.h | 7 + .../src/ALTERA_PLL_CYCLONE10.c | 195 ++++++++++++ .../slsDetectorServer/src/nios.c | 72 +++-- .../src/slsDetectorServer_funcs.c | 284 +++++++++++++++++- slsDetectorSoftware/include/CmdProxy.h | 10 +- slsDetectorSoftware/include/Detector.h | 27 ++ slsDetectorSoftware/include/slsDetector.h | 21 ++ slsDetectorSoftware/src/CmdProxy.cpp | 106 +++++++ slsDetectorSoftware/src/Detector.cpp | 36 +++ slsDetectorSoftware/src/slsDetector.cpp | 51 ++++ .../tests/test-multiSlsDetectorClient.cpp | 1 + slsSupportLib/include/sls_detector_funcs.h | 15 + slsSupportLib/include/versionAPI.h | 2 +- 21 files changed, 1119 insertions(+), 54 deletions(-) create mode 100755 slsDetectorServers/slsDetectorServer/include/ALTERA_PLL_CYCLONE10.h create mode 100755 slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c diff --git a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt index f1a08f896..7e9dc9580 100644 --- a/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/gotthard2DetectorServer/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(gotthard2DetectorServer_virtual ../slsDetectorServer/src/DAC6571.c ../slsDetectorServer/src/common.c ../slsDetectorServer/src/LTC2620_Driver.c + ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ) include_directories( diff --git a/slsDetectorServers/gotthard2DetectorServer/Makefile b/slsDetectorServers/gotthard2DetectorServer/Makefile index a20cb55b4..fbb66561a 100755 --- a/slsDetectorServers/gotthard2DetectorServer/Makefile +++ b/slsDetectorServers/gotthard2DetectorServer/Makefile @@ -5,14 +5,14 @@ support_lib = ../../slsSupportLib/include/ CROSS = nios2-buildroot-linux-gnu- CC = $(CROSS)gcc -CFLAGS += -Wall -DGOTTHARD2D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +CFLAGS += -Wall -DGOTTHARD2D -DSTOP_SERVER -I$(main_inc) -I$(support_lib) -I$(current_dir) -DDEBUG1 #-DVERBOSEI #-DVERBOSE LDLIBS += -lm PROGS = gotthard2DetectorServer DESTDIR ?= bin INSTMODE = 0777 SRCS = slsDetectorFunctionList.c -SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c +SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c OBJS = $(SRCS:.c=.o) diff --git a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h index dab12d79c..e2aca049c 100644 --- a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h @@ -2,8 +2,35 @@ /* Definitions for FPGA*/ #define REG_OFFSET (4) + +/* cspbase 0x1804 0000 */ +#define BASE_READOUT_PLL (0x000) +#define BASE_SYSTEM_PLL (0x800) + +#define READOUT_PLL_RESET_REG (0x1 * REG_OFFSET + BASE_READOUT_PLL) //TODO + +#define READOUT_PLL_RESET_OFST (0) +#define READOUT_PLL_RESET_MSK (0x00000001 << READOUT_PLL_RESET_OFST) + +#define SYSTEM_PLL_RESET_REG (0x1 * REG_OFFSET + BASE_SYSTEM_PLL) //TODO + +#define SYSTEM_PLL_RESET_OFST (0) +#define SYSTEM_PLL_RESET_MSK (0x00000001 << SYSTEM_PLL_RESET_OFST) + +#define READOUT_PLL_WAIT_REG (0x2 * REG_OFFSET + BASE_READOUT_PLL) //TODO + +#define READOUT_PLL_WAIT_OFST (0) +#define READOUT_PLL_WAIT_MSK (0x00000001 << READOUT_PLL_WAIT_OFST) + +#define SYSTEM_PLL_WAIT_REG (0x2 * REG_OFFSET + BASE_SYSTEM_PLL) //TODO + +#define SYSTEM_PLL_WAIT_OFST (0) +#define SYSTEM_PLL_WAIT_MSK (0x00000001 << SYSTEM_PLL_WAIT_OFST) + + +/* cspbase 0x1806 0000 */ #define BASE_CONTROL (0x000) -#define BASE_ACQUISITION (0x200) +#define BASE_ACQUISITION (0x200) //???TODO #define BASE_UDP_RAM (0x1000) /* Module Control Board Serial Number register */ @@ -44,7 +71,9 @@ #define DTA_OFFSET_REG (0x104 * REG_OFFSET + BASE_CONTROL) -/* Pattern Control FPGA registers TODO --------------------------------------------------*/ + + +/* BASE_ACQUISITION FPGA registers TODO --------------------------------------------------*/ /* Cycles left 64bit Register */ #define GET_CYCLES_LSB_REG (0x10 + BASE_ACQUISITION) diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index c0fa1bee5..2cd883982 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -6,6 +6,7 @@ #include "DAC6571.h" #include "LTC2620_Driver.h" #include "common.h" +#include "ALTERA_PLL_CYCLONE10.h" // pll #ifdef VIRTUAL #include "communication_funcs_UDP.h" #endif @@ -17,7 +18,7 @@ #include #endif - +enum {READOUT_PLL, SYSTEM_PLL}; // Global variable from slsDetectorServer_funcs @@ -34,8 +35,8 @@ int virtual_status = 0; int virtual_stop = 0; #endif - -uint32_t clkDivider[NUM_CLOCKS] = {125, 20, 80}; +int32_t clkPhase[NUM_CLOCKS] = {0, 0, 0, 0, 0, 0}; +uint32_t clkDivider[NUM_CLOCKS] = {0, 0, 0, 0, 0, 0}; int highvoltage = 0; int dacValues[NDAC] = {0}; int detPos[2] = {0, 0}; @@ -338,12 +339,20 @@ void initStopServer() { void setupDetector() { FILE_LOG(logINFO, ("This Server is for 1 Gotthard2 module \n")); - clkDivider[RUN_CLK] = DEFAULT_RUN_CLK; - clkDivider[TICK_CLK] = DEFAULT_TICK_CLK; - clkDivider[SAMPLING_CLK] = DEFAULT_SAMPLING_CLK; + clkDivider[READOUT_C0] = DEFAULT_READOUT_C0; + clkDivider[READOUT_C1] = DEFAULT_READOUT_C1; + clkDivider[SYSTEM_C0] = DEFAULT_SYSTEM_C0; + clkDivider[SYSTEM_C1] = DEFAULT_SYSTEM_C1; + clkDivider[SYSTEM_C2] = DEFAULT_SYSTEM_C2; + clkDivider[SYSTEM_C3] = DEFAULT_SYSTEM_C3; + + highvoltage = 0; { int i; + for (i = 0; i < NUM_CLOCKS; ++i) { + clkPhase[i] = 0; + } for (i = 0; i < NDAC; ++i) { dacValues[i] = 0; } @@ -351,6 +360,10 @@ void setupDetector() { #ifndef VIRTUAL + // pll defines + ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, READOUT_PLL_RESET_REG, SYSTEM_PLL_RESET_REG, READOUT_PLL_RESET_MSK, SYSTEM_PLL_RESET_MSK, READOUT_PLL_WAIT_REG, SYSTEM_PLL_WAIT_REG, READOUT_PLL_WAIT_MSK, SYSTEM_PLL_WAIT_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ); + ALTERA_PLL_C10_ResetPLL(READOUT_PLL); + ALTERA_PLL_C10_ResetPLL(SYSTEM_PLL); // hv DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME); // dacs @@ -396,7 +409,7 @@ int64_t setTimer(enum timerIndex ind, int64_t val) { int64_t retval = -1; - switch(ind){ + switch(ind) { case FRAME_NUMBER: // defined in sls_detector_defs.h (general) if(val >= 0) { @@ -407,20 +420,20 @@ int64_t setTimer(enum timerIndex ind, int64_t val) { break; case ACQUISITION_TIME: - if(val >= 0){ + if(val >= 0) { FILE_LOG(logINFO, ("Setting exptime: %lldns\n", (long long int)val)); - val *= (1E-3 * RUN_CLK); + val *= (1E-9 * READOUT_C0); //TODO } - retval = set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / (1E-3 * RUN_CLK); // CLK defined in slsDetectorServer_defs.h + retval = set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / (1E-9 * READOUT_C0); //TODO FILE_LOG(logDEBUG1, ("Getting exptime: %lldns\n", (long long int)retval)); break; case FRAME_PERIOD: if(val >= 0){ FILE_LOG(logINFO, ("Setting period: %lldns\n",(long long int)val)); - val *= (1E-3 * TICK_CLK); + val *= (1E-9 * SYSTEM_C0);//TODO } - retval = set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG )/ (1E-3 * TICK_CLK); + retval = set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG )/ (1E-9 * SYSTEM_C0); //TODO FILE_LOG(logDEBUG1, ("Getting period: %lldns\n", (long long int)retval)); break; case CYCLES_NUMBER: @@ -445,17 +458,17 @@ int validateTimer(enum timerIndex ind, int64_t val, int64_t retval) { switch(ind) { case ACQUISITION_TIME: // convert to freq - val *= (1E-3 * RUN_CLK); + val *= (1E-9 * READOUT_C0);//TODO // convert back to timer - val = (val) / (1E-3 * RUN_CLK); + val = (val) / (1E-9 * READOUT_C0);//TODO if (val != retval) return FAIL; break; case FRAME_PERIOD: // convert to freq - val *= (1E-3 * TICK_CLK); + val *= (1E-9 * SYSTEM_C0);//TODO // convert back to timer - val = (val) / (1E-3 * TICK_CLK); + val = (val) / (1E-9 * SYSTEM_C0);//TODO if (val != retval) return FAIL; break; @@ -675,6 +688,152 @@ void calcChecksum(udp_header* udp) { udp->ip_checksum = checksum; } +// Detector Specific +int setPhase(enum CLKINDEX ind, int val, int degrees) { + char clock_names[6][15]={"Readout_c0", "Readout_c1", "System_c0", "System_c1", "System_c2", "System_c3"}; + FILE_LOG(logDEBUG1, ("\tConfiguring Phase of C%d(%s) to %d (degree mode: %d)\n", ind, clock_names[ind], val, degrees)); + + int maxShift = getMaxPhase(ind); + int valShift = val; + // convert to phase shift + if (degrees) { + ConvertToDifferentRange(0, 359, 0, maxShift - 1, val, &valShift); + } + FILE_LOG(logDEBUG1, ("\tphase shift: %d (degrees/shift: %d)\n", valShift, val)); + + int relativePhase = valShift - clkPhase[ind]; + FILE_LOG(logDEBUG1, ("\trelative phase shift: %d (Current phase: %d)\n", relativePhase, clkPhase[ind])); + + // same phase + if (!relativePhase) { + FILE_LOG(logINFO, ("\tNothing to do in Phase Shift\n")); + return OK; + } + FILE_LOG(logINFOBLUE, ("\tConfiguring Phase of C%d(%s) to %d (degree mode: %d)\n", ind, clock_names[ind], val, degrees)); + + int phase = 0; + if (relativePhase > 0) { + phase = (maxShift - relativePhase); + } else { + phase = (-1) * relativePhase; + } + FILE_LOG(logDEBUG1, ("\t[Single Direction] Phase:%d (0x%x). Max Phase shifts:%d\n", phase, phase, maxShift)); + + int pllIndex = ind >= SYSTEM_C0 ? SYSTEM_PLL : READOUT_PLL; + int clkIndex = ind >= SYSTEM_C0 ? ind - SYSTEM_C0 : ind; + int ret = ALTERA_PLL_C10_SetPhaseShift(pllIndex, clkIndex, phase, 0); + + clkPhase[ind] = valShift; + return ret; +} + +int getPhase(enum CLKINDEX ind, int degrees) { + if (!degrees) + return clkPhase[ind]; + // convert back to degrees + int val = 0; + ConvertToDifferentRange(0, getMaxPhase(ind) - 1, 0, 359, clkPhase[ind], &val); + return val; +} + +int getMaxPhase(enum CLKINDEX ind) { + int vcofreq = getVCOFrequency(ind); + int maxshiftstep = ALTERA_PLL_C10_GetMaxPhaseShiftStepsofVCO(); + int ret = ((double)vcofreq / (double)clkDivider[ind]) * maxshiftstep; + + char clock_names[6][15]={"Readout_c0", "Readout_c1", "System_c0", "System_c1", "System_c2", "System_c3"}; + FILE_LOG(logDEBUG1, ("\tMax Phase Shift (%s): %d (Clock: %d Hz, VCO:%d Hz)\n", + clock_names[ind], ret, clkDivider[ind], vcofreq)); + + return ret; +} + +int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval) { + if (val == -1) + return OK; + FILE_LOG(logDEBUG1, ("validating phase in degrees for clk %d\n", (int)ind)); + int maxShift = getMaxPhase(ind); + // convert degrees to shift + // convert degrees to shift + int valShift = 0; + ConvertToDifferentRange(0, 359, 0, maxShift - 1, val, &valShift); + // convert back to degrees + ConvertToDifferentRange(0, maxShift - 1, 0, 359, valShift, &val); + + if (val == retval) + return OK; + return FAIL; +} + + + +int getFrequency(enum CLKINDEX ind) { + return clkDivider[ind]; +} + +int getVCOFrequency(enum CLKINDEX ind) { + int pllIndex = ind >= SYSTEM_C0 ? SYSTEM_PLL : READOUT_PLL; + return ALTERA_PLL_C10_GetVCOFrequency(pllIndex); +} + +int getMaxClockDivider() { + return ALTERA_PLL_C10_GetMaxClockDivider(); +} + +int setClockDivider(enum CLKINDEX ind, int val) { + char clock_names[6][15]={"Readout_c0", "Readout_c1", "System_c0", "System_c1", "System_c2", "System_c3"}; + + int vcofreq = getVCOFrequency(ind); + int currentdiv = vcofreq / clkDivider[ind]; + int newfreq = vcofreq / val; + + FILE_LOG(logINFO, ("\tConfiguring Click Divider of C%d(%s) from %d (%d Hz) to %d (%d Hz). \n\t(Vcofreq: %d Hz)\n", ind, clock_names[ind], currentdiv, clkDivider[ind], val, newfreq, vcofreq)); + + // Remembering old phases + int oldPhases[NUM_CLOCKS]; + { + int i = 0; + for (i = 0; i < NUM_CLOCKS; ++i) { + oldPhases [i] = getPhase(i, 0); + FILE_LOG(logDEBUG1, ("\tRemembering C%d (%s) phase: %d\n", ind, clock_names, oldPhases[i])); + } + } + + // Calculate and set output frequency + int pllIndex = ind >= SYSTEM_C0 ? SYSTEM_PLL : READOUT_PLL; + int clkIndex = ind >= SYSTEM_C0 ? ind - SYSTEM_C0 : ind; + int ret = ALTERA_PLL_C10_SetOuputFrequency (pllIndex, clkIndex, newfreq); + clkDivider[ind] = newfreq; + FILE_LOG(logINFO, ("\tC%d(%s): Clock Divider set to %d (%d Hz)\n", ind, clock_names[ind], val, clkDivider[ind])); + + // phase is reset by pll (when setting output frequency) + if (ind >= READOUT_C0) { + clkPhase[READOUT_C0] = 0; + clkPhase[READOUT_C1] = 0; + } else { + clkPhase[SYSTEM_C0] = 0; + clkPhase[SYSTEM_C1] = 0; + clkPhase[SYSTEM_C2] = 0; + clkPhase[SYSTEM_C3] = 0; + } + + // set the phase if custom set + { + int i = 0; + for (i = 0; i < NUM_CLOCKS; ++i) { + if (clkPhase[i] != oldPhases[i]) { + FILE_LOG(logINFO, ("\tPhase reset by PLL\n\tCorrecting C%d(%s) to %d\n", i, clock_names[i], oldPhases[i])); + setPhase(i, oldPhases[i], 0); + } + } + } + return ret; +} + +int getClockDivider(enum CLKINDEX ind) { + return (getVCOFrequency(ind) / clkDivider[ind]); +} + /* aquisition */ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index b24b4c90d..40cec2220 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -23,14 +23,19 @@ #define DEFAULT_EXPTIME (1 * 1000 * 1000) // 1 ms #define DEFAULT_PERIOD (1 * 1000 * 1000 * 1000) // 1 s #define DEFAULT_HIGH_VOLTAGE (0) -#define DEFAULT_RUN_CLK (125) -#define DEFAULT_TICK_CLK (20) // will be fixed later. Not configurable -#define DEFAULT_SAMPLING_CLK (80) - +#define DEFAULT_READOUT_C0 (144444448) // rdo_clk, 144 MHz +#define DEFAULT_READOUT_C1 (288888896) // rdo_x2_clk, 288 MHz +#define DEFAULT_SYSTEM_C0 (144444448) // run_clk, 144 MHz +#define DEFAULT_SYSTEM_C1 (72222224) // chip_clk, 72 MHz +#define DEFAULT_SYSTEM_C2 (18055556) // sync_clk, 18 MHz +#define DEFAULT_SYSTEM_C3 (144444448) // str_clk, 144 MHz #define DEFAULT_TX_UDP_PORT (0x7e9a) /* Firmware Definitions */ #define IP_HEADER_SIZE (20) +#define READOUT_PLL_VCO_FREQ_HZ (866666688) // Hz +#define SYSTEM_PLL_VCO_FREQ_HZ (722222240) // Hz + /** Other Definitions */ #define BIT16_MASK (0xFFFF) @@ -71,7 +76,7 @@ enum DACINDEX {G_VREF_H_ADC, /* 0 */ \ 0, /* 14 (0 mV) DAC_UNUSED2*/ \ 1400 /* 15 (700 mV) VCOM_ADC2*/ \ }; -enum CLKINDEX {RUN_CLK, TICK_CLK, SAMPLING_CLK, NUM_CLOCKS}; +enum CLKINDEX {READOUT_C0, READOUT_C1, SYSTEM_C0, SYSTEM_C1, SYSTEM_C2, SYSTEM_C3, NUM_CLOCKS}; /* Struct Definitions */ typedef struct udp_header_struct { diff --git a/slsDetectorServers/slsDetectorServer/include/ALTERA_PLL_CYCLONE10.h b/slsDetectorServers/slsDetectorServer/include/ALTERA_PLL_CYCLONE10.h new file mode 100755 index 000000000..2fe6c3a0c --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/include/ALTERA_PLL_CYCLONE10.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +/** + * Set defines + * @param regofst register offset + * @param baseaddr0 base address of pll 0 + * @param baseaddr1 base address of pll 1 + * @param resetreg0 reset register of pll 0 + * @param resetreg1 reset register of pll 1 + * @param resetmsk reset mask of pll 0 + * @param resetms1 reset mask of pll 1 + * @param waitreg0 wait register of pll 0 + * @param waitreg1 wait register of pll 1 + * @param waitmsk0 wait mask of pll 0 + * @param waitmsk1 wait mask of pll 1 + * @param vcofreq0 vco frequency of pll 0 + * @param vcofreq1 vco frequency of pll 1 + */ +void ALTERA_PLL_C10_SetDefines(int regofst, uint32_t baseaddr0, uint32_t baseaddr1, uint32_t resetreg0, uint32_t resetreg1, uint32_t resetmsk0, uint32_t resetmsk1, uint32_t waitreg0, uint32_t waitreg1, uint32_t waitmsk0, uint32_t waitmsk1, int vcofreq0, int vcofreq1); + +/** + * Get Max Clock Divider + */ +int ALTERA_PLL_C10_GetMaxClockDivider(); + +/** + * Get VCO frequency based on pll Index + * @param pllIndex pll index + * @returns VCO frequency + */ +int ALTERA_PLL_C10_GetVCOFrequency(int pllIndex); + +/** + * Get maximum phase shift steps of vco frequency + * @returns max phase shift steps of vco + */ +int ALTERA_PLL_C10_GetMaxPhaseShiftStepsofVCO(); + +/** + * Start reconfiguration and wait till its complete + * @param pllIndex pll index + * @returns FAIL if wait request signal took too long to deassert, else OK + */ +int ALTERA_PLL_C10_Reconfigure(int pllIndex); + +/** + * Reset pll + * @param pllIndex pll index + */ +void ALTERA_PLL_C10_ResetPLL (int pllIndex); + +/** + * Set Phase Shift + * @param pllIndex pll index + * @param clkIndex clock index + * @param phase phase shift + * @param pos 1 if up down direction of shift is positive, else 0 + * @returns OK or FAIL or reconfigure + */ +int ALTERA_PLL_C10_SetPhaseShift(int pllIndex, int clkIndex, int phase, int pos); + +/** + * Calculate and write output frequency + * @param pllIndex pll index + * @param clkIndex clock index + * @param value frequency in Hz to set to + * @returns OK or FAIL of reconfigure + */ +int ALTERA_PLL_C10_SetOuputFrequency (int pllIndex, int clkIndex, int value); + diff --git a/slsDetectorServers/slsDetectorServer/include/nios.h b/slsDetectorServers/slsDetectorServer/include/nios.h index b71b74a1c..34c05bbc4 100755 --- a/slsDetectorServers/slsDetectorServer/include/nios.h +++ b/slsDetectorServers/slsDetectorServer/include/nios.h @@ -3,6 +3,19 @@ #include #include +/** + * Write into a 32 bit register for cspbase 1 + * @param offset address offset + * @param data 32 bit data + */ +void bus_w_csp1(u_int32_t offset, u_int32_t data); + +/** + * Read from a 32 bit register for cspbase 1 + * @param offset address offset + * @retuns 32 bit data read + */ +u_int32_t bus_r_csp1(u_int32_t offset); /** * Write into a 32 bit register diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 609d5c846..7b2555a4d 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -380,8 +380,25 @@ uint64_t writePatternWord(int addr, uint64_t word); int setPatternWaitAddress(int level, int addr); uint64_t setPatternWaitTime(int level, uint64_t t); void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop); + + +#elif GOTTHARD2D +int setPhase(enum CLKINDEX ind, int val, int degrees); +int getPhase(enum CLKINDEX ind, int degrees); +int getMaxPhase(enum CLKINDEX ind); +int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval); +//int setFrequency(enum CLKINDEX ind, int val); +int getFrequency(enum CLKINDEX ind); +int getVCOFrequency(enum CLKINDEX ind); +int getMaxClockDivider(); +int setClockDivider(enum CLKINDEX ind, int val); +int getClockDivider(enum CLKINDEX ind); #endif + + + + #if defined(JUNGFRAUD) || defined(EIGERD) int setNetworkParameter(enum NETWORKINDEX mode, int value); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 4b1250f2f..21a572c17 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -144,3 +144,10 @@ int set_storeinram(int); int get_storeinram(int); int set_readout_mode(int); int get_readout_mode(int); +int set_clock_frequency(int); +int get_clock_frequency(int); +int set_clock_phase(int); +int get_clock_phase(int); +int get_max_clock_phase_shift(int); +int set_clock_divider(int); +int get_clock_divider(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c b/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c new file mode 100755 index 000000000..5a38907be --- /dev/null +++ b/slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c @@ -0,0 +1,195 @@ +#include "ALTERA_PLL_CYCLONE10.h" +#include "clogger.h" +#include "nios.h" +#include "sls_detector_defs.h" + +#include // usleep + +/* Altera PLL CYCLONE 10 DEFINES */ + +/** PLL Reconfiguration Registers */ +// https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/an/an728.pdf + + +// c counter (C0-C8 (+1 to base address)) +#define ALTERA_PLL_C10_C_COUNTER_BASE_REG (0x0C0) + +#define ALTERA_PLL_C10_C_COUNTER_MAX_DIVIDER_VAL (0xFF) +#define ALTERA_PLL_C10_C_COUNTER_LW_CNT_OFST (0) +#define ALTERA_PLL_C10_C_COUNTER_LW_CNT_MSK (0x000000FF << ALTERA_PLL_C10_C_COUNTER_LW_CNT_OFST) +#define ALTERA_PLL_C10_C_COUNTER_HGH_CNT_OFST (8) +#define ALTERA_PLL_C10_C_COUNTER_HGH_CNT_MSK (0x000000FF << ALTERA_PLL_C10_C_COUNTER_HGH_CNT_OFST) +/* total_div = lw_cnt + hgh_cnt */ +#define ALTERA_PLL_C10_C_COUNTER_BYPSS_ENBL_OFST (16) +#define ALTERA_PLL_C10_C_COUNTER_BYPSS_ENBL_MSK (0x00000001 << ALTERA_PLL_C10_C_COUNTER_BYPSS_ENBL_OFST) +/* if bypss_enbl = 0, fout = f(vco)/total_div; else fout = f(vco) (c counter is bypassed) */ +#define ALTERA_PLL_C10_C_COUNTER_ODD_DVSN_OFST (17) +#define ALTERA_PLL_C10_C_COUNTER_ODD_DVSN_MSK (0x00000001 << ALTERA_PLL_C10_C_COUNTER_ODD_DVSN_OFST) +/** if odd_dvsn = 0 (even), duty cycle = hgh_cnt/ total_div; else duty cycle = (hgh_cnt - 0.5) / total_div */ + + +// dynamic phase shift (C0-C8 (+1 to base address), 0xF for all counters) +#define ALTERA_PLL_C10_PHASE_SHIFT_BASE_REG (0x100) + +#define ALTERA_PLL_C10_MAX_SHIFTS_PER_OPERATION (7) +#define ALTERA_PLL_C10_SHIFT_NUM_SHIFTS_OFST (0) +#define ALTERA_PLL_C10_SHIFT_NUM_SHIFTS_MSK (0x00000007 << ALTERA_PLL_C10_SHIFT_NUM_SHIFTS_OFST) + +#define ALTERA_PLL_C10_SHIFT_UP_DOWN_OFST (3) +#define ALTERA_PLL_C10_SHIFT_UP_DOWN_MSK (0x00000001 << ALTERA_PLL_C10_SHIFT_UP_DOWN_OFST) +#define ALTERA_PLL_C10_SHIFT_UP_DOWN_NEG_VAL ((0x0 << ALTERA_PLL_C10_SHIFT_UP_DOWN_OFST) & ALTERA_PLL_C10_SHIFT_UP_DOWN_MSK) +#define ALTERA_PLL_C10_SHIFT_UP_DOWN_POS_VAL ((0x1 << ALTERA_PLL_C10_SHIFT_UP_DOWN_OFST) & ALTERA_PLL_C10_SHIFT_UP_DOWN_MSK) + +#define ALTERA_PLL_C10_PHASE_SHIFT_STEP_OF_VCO (8) +#define ALTERA_PLL_C10_WAIT_TIME_US (10 * 1000) + + +int ALTERA_PLL_C10_Reg_offset = 0x0; +const int ALTERA_PLL_C10_NUM = 2; +uint32_t ALTERA_PLL_C10_BaseAddress[2] = {0x0, 0x0}; +uint32_t ALTERA_PLL_C10_Reset_Reg[2] = {0x0, 0x0}; +uint32_t ALTERA_PLL_C10_Reset_Msk[2] = {0x0, 0x0}; +uint32_t ALTERA_PLL_C10_Wait_Reg[2] = {0x0, 0x0}; +uint32_t ALTERA_PLL_C10_Wait_Msk[2] = {0x0, 0x0}; +int ALTERA_PLL_C10_VCO_FREQ[2] = {0, 0}; + +void ALTERA_PLL_C10_SetDefines(int regofst, uint32_t baseaddr0, uint32_t baseaddr1, uint32_t resetreg0, uint32_t resetreg1, uint32_t resetmsk0, uint32_t resetmsk1, uint32_t waitreg0, uint32_t waitreg1, uint32_t waitmsk0, uint32_t waitmsk1, int vcofreq0, int vcofreq1) { + ALTERA_PLL_C10_Reg_offset = regofst; + ALTERA_PLL_C10_BaseAddress[0] = baseaddr0; + ALTERA_PLL_C10_BaseAddress[1] = baseaddr1; + ALTERA_PLL_C10_Reset_Reg[0] = resetreg0; + ALTERA_PLL_C10_Reset_Reg[1] = resetreg1; + ALTERA_PLL_C10_Reset_Msk[0] = resetmsk0; + ALTERA_PLL_C10_Reset_Msk[1] = resetmsk1; + ALTERA_PLL_C10_Wait_Reg[0] = waitreg0; + ALTERA_PLL_C10_Wait_Reg[1] = waitreg1; + ALTERA_PLL_C10_Wait_Msk[0] = waitmsk0; + ALTERA_PLL_C10_Wait_Msk[1] = waitmsk1; + ALTERA_PLL_C10_VCO_FREQ[0] = vcofreq0; + ALTERA_PLL_C10_VCO_FREQ[1] = vcofreq1; +} + +int ALTERA_PLL_C10_GetMaxClockDivider() { + return ALTERA_PLL_C10_C_COUNTER_MAX_DIVIDER_VAL; +} + +int ALTERA_PLL_C10_GetVCOFrequency(int pllIndex) { + return ALTERA_PLL_C10_VCO_FREQ[pllIndex]; +} + +int ALTERA_PLL_C10_GetMaxPhaseShiftStepsofVCO() { + return ALTERA_PLL_C10_PHASE_SHIFT_STEP_OF_VCO; +} + +int ALTERA_PLL_C10_Reconfigure(int pllIndex) { + FILE_LOG(logINFO, ("\tReconfiguring PLL %d\n", pllIndex)); + uint32_t waitreg = ALTERA_PLL_C10_Wait_Reg[pllIndex]; + uint32_t waitmsk = ALTERA_PLL_C10_Wait_Msk[pllIndex]; + + // write anything to base address to start reconfiguring + FILE_LOG(logDEBUG1, ("\tWriting 1 to base address 0x%x to start reconfiguring\n", ALTERA_PLL_C10_BaseAddress[pllIndex])); + //bus_w_csp1(ALTERA_PLL_C10_BaseAddress[pllIndex], 0x1); + + // wait for write operation to be completed by polling wait request bit + int ret = OK; + + FILE_LOG(logDEBUG1, ("\tWaiting a second (instead of wait request bit in fw)\n")); + usleep(1 * 1000 * 1000); + + /* TODO wait reg and wait mask to be done in firware, so wait instead (above) + int counter = 0; + while (bus_r_csp1(waitreg) & waitmsk) { + usleep(ALTERA_PLL_C10_WAIT_TIME_US); + ++counter; + if (counter >= 100) { + FILE_LOG(logERROR, ("Waited for the pll wait request for 1 s. Not waiting anymore.")); + ret = FAIL; + break; + } + } + FILE_LOG(logINFO, ("\tReconfiguring PLL %d done with %s\n", pllIndex, ret == FAIL ? "failure" : "success")); + */ + FILE_LOG(logDEBUG1, ("\tWaiting done\n")); + return ret; +} + +void ALTERA_PLL_C10_ResetPLL (int pllIndex) { + FILE_LOG(logINFO, ("Resetting PLL %d\n", pllIndex)); + uint32_t resetreg = ALTERA_PLL_C10_Reset_Reg[pllIndex]; + uint32_t resetmsk = ALTERA_PLL_C10_Reset_Msk[pllIndex]; + + FILE_LOG(logERROR, ("Reset not implemented yet!\n")); + /* TODO reset reg and reset mask to be done in firware, so wait instead (above) + bus_w_csp1(resetreg, bus_r_csp1(resetreg) | resetmsk); + usleep(ALTERA_PLL_C10_WAIT_TIME_US); //FIXME + bus_w_csp1(resetreg, bus_r_csp1(resetreg) & ~resetmsk);//FIXME + */ +} + + +int ALTERA_PLL_C10_SetPhaseShift(int pllIndex, int clkIndex, int phase, int pos) { + FILE_LOG(logINFO, ("\tC%d: Writing PLL %d Phase Shift [phase:%d, pos:%d]\n", clkIndex, pllIndex, phase, pos)); + FILE_LOG(logDEBUG1, ("\tBase address: 0x%x phasebasereg:0x%x\n", ALTERA_PLL_C10_BaseAddress[pllIndex], ALTERA_PLL_C10_PHASE_SHIFT_BASE_REG)); + + uint32_t addr = ALTERA_PLL_C10_BaseAddress[pllIndex] + (ALTERA_PLL_C10_PHASE_SHIFT_BASE_REG + (int)clkIndex) * ALTERA_PLL_C10_Reg_offset; + + + int maxshifts = ALTERA_PLL_C10_MAX_SHIFTS_PER_OPERATION; + + // only 7 shifts at a time + int ret = OK; + while (phase > 0) { + int phaseToDo = (phase > maxshifts) ? maxshifts : phase; + uint32_t value = (((phaseToDo << ALTERA_PLL_C10_SHIFT_NUM_SHIFTS_OFST) & ALTERA_PLL_C10_SHIFT_NUM_SHIFTS_MSK) | + (pos ? ALTERA_PLL_C10_SHIFT_UP_DOWN_POS_VAL : ALTERA_PLL_C10_SHIFT_UP_DOWN_NEG_VAL)); + FILE_LOG(logDEBUG1, ("\t[addr:0x%x, phaseTodo:%d phaseleft:%d phase word:0x%08x]\n", addr, phaseToDo, phase, value)); + //bus_w_csp1(addr, value); + + if (ALTERA_PLL_C10_Reconfigure(pllIndex) == FAIL) { + ret = FAIL; + } + + phase -= phaseToDo; + } + return ret; +} + + +int ALTERA_PLL_C10_SetOuputFrequency (int pllIndex, int clkIndex, int value) { + int pllVCOFreqHz = ALTERA_PLL_C10_VCO_FREQ[pllIndex]; + FILE_LOG(logDEBUG1, ("\tC%d: Setting output frequency for pll %d to %d (pllvcofreq: %dHz)\n", clkIndex, pllIndex, value, pllVCOFreqHz)); + + // calculate output frequency + float total_div = (float)pllVCOFreqHz / (float)value; + + // assume 50% duty cycle + uint32_t low_count = total_div / 2; + uint32_t high_count = low_count; + uint32_t odd_division = 0; + + // odd division + if (total_div > (float)(2 * low_count)) { + ++high_count; + odd_division = 1; + } + FILE_LOG(logINFO, ("\tC%d: Low:%d, High:%d, Odd:%d\n", clkIndex, low_count, high_count, odd_division)); + + // command to set output frequency + uint32_t addr = ALTERA_PLL_C10_BaseAddress[pllIndex] + (ALTERA_PLL_C10_C_COUNTER_BASE_REG + (int)clkIndex) * ALTERA_PLL_C10_Reg_offset; + uint32_t val = (((low_count << ALTERA_PLL_C10_C_COUNTER_LW_CNT_OFST) & ALTERA_PLL_C10_C_COUNTER_LW_CNT_MSK) | + ((high_count << ALTERA_PLL_C10_C_COUNTER_HGH_CNT_OFST) & ALTERA_PLL_C10_C_COUNTER_HGH_CNT_MSK) | + ((odd_division << ALTERA_PLL_C10_C_COUNTER_ODD_DVSN_OFST) & ALTERA_PLL_C10_C_COUNTER_ODD_DVSN_MSK)); + FILE_LOG(logDEBUG1, ("\t[addr:0x%x, word:0x%08x]\n", addr, val)); + + // write frequency + //bus_w_csp1(addr, val); + + int ret = ALTERA_PLL_C10_Reconfigure(pllIndex); + + // reset required to keep the phase relationships (must reconfigure adcs again after this as adc clock is stopped temporarily when resetting pll) + ALTERA_PLL_C10_ResetPLL (pllIndex); + + return ret; +} + + diff --git a/slsDetectorServers/slsDetectorServer/src/nios.c b/slsDetectorServers/slsDetectorServer/src/nios.c index 3dc8f1469..a9efa5584 100755 --- a/slsDetectorServers/slsDetectorServer/src/nios.c +++ b/slsDetectorServers/slsDetectorServer/src/nios.c @@ -12,6 +12,20 @@ u_int32_t* csp0base = 0; #define CSP0 0x18060000 #define MEM_SIZE 0x100000 +u_int32_t* csp1base = 0; +#define CSP1 0x18040000 + +void bus_w_csp1(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(csp1base + offset/(sizeof(u_int32_t))); + *ptr1=data; +} + +u_int32_t bus_r_csp1(u_int32_t offset) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(csp1base + offset/(sizeof(u_int32_t))); + return *ptr1; +} void bus_w(u_int32_t offset, u_int32_t data) { volatile u_int32_t *ptr1; @@ -72,38 +86,46 @@ u_int32_t writeRegister(u_int32_t offset, u_int32_t data) { int mapCSP0(void) { - // if not mapped - if (csp0base == 0) { - FILE_LOG(logINFO, ("Mapping memory\n")); + u_int32_t csps[2] = {CSP0, CSP1}; + u_int32_t** cspbases[2] = {&csp0base, &csp1base}; + char names[2][10]={"csp0base","csp1base"}; + + int i = 0; + for (i = 0; i < 2; ++i) { + // if not mapped + if (*cspbases[i] == 0) { + FILE_LOG(logINFO, ("Mapping memory for %s\n", names[i])); #ifdef VIRTUAL - csp0base = malloc(MEM_SIZE); - if (csp0base == NULL) { - FILE_LOG(logERROR, ("Could not allocate virtual memory.\n")); - return FAIL; - } - FILE_LOG(logINFO, ("memory allocated\n")); + *cspbases[i] = malloc(MEM_SIZE); + if (*cspbases[i] == NULL) { + FILE_LOG(logERROR, ("Could not allocate virtual memory for %s.\n", names[i])); + return FAIL; + } + FILE_LOG(logINFO, ("memory allocated for %s\n", names[i])); #else - int fd = open("/dev/mem", O_RDWR | O_SYNC, 0); - if (fd == -1) { - FILE_LOG(logERROR, ("Can't find /dev/mem\n")); - return FAIL; - } - FILE_LOG(logDEBUG1, ("/dev/mem opened\n")); - csp0base = (u_int32_t*)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); - if (csp0base == MAP_FAILED) { - FILE_LOG(logERROR, ("Can't map memmory area\n")); - return FAIL; - } + int fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + FILE_LOG(logERROR, ("Can't find /dev/mem for %s\n", names[i])); + return FAIL; + } + FILE_LOG(logDEBUG1, ("/dev/mem opened for %s, (CSP:0x%x)\n", names[i], csps[i])); + *cspbases[i] = (u_int32_t*)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, csps[i]); + if (*cspbases[i] == MAP_FAILED) { + FILE_LOG(logERROR, ("Can't map memmory area for %s\n", names[i])); + return FAIL; + } #endif - FILE_LOG(logINFO, ("CSPOBASE mapped from 0x%p to 0x%p\n", - csp0base, csp0base+MEM_SIZE)); - //FILE_LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG))); - }else - FILE_LOG(logINFO, ("Memory already mapped before\n")); + FILE_LOG(logINFO, ("%s mapped from %p to %p,(CSP:0x%x) \n", + names[i], *cspbases[i], *cspbases[i]+MEM_SIZE, csps[i])); + //FILE_LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG))); + } else + FILE_LOG(logINFO, ("Memory %s already mapped before\n", names[i])); + } return OK; } + u_int32_t* Nios_getBaseAddress() { return csp0base; } \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 76696a9fd..9cdbd9353 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -284,6 +284,15 @@ const char* getFunctionName(enum detFuncs func) { case F_GET_STOREINRAM_MODE: return "F_GET_STOREINRAM_MODE"; case F_SET_READOUT_MODE: return "F_SET_READOUT_MODE"; case F_GET_READOUT_MODE: return "F_GET_READOUT_MODE"; + case F_SET_CLOCK_FREQUENCY: return "F_SET_CLOCK_FREQUENCY"; + case F_GET_CLOCK_FREQUENCY: return "F_GET_CLOCK_FREQUENCY"; + case F_SET_CLOCK_PHASE: return "F_SET_CLOCK_PHASE"; + case F_GET_CLOCK_PHASE: return "F_GET_CLOCK_PHASE"; + case F_GET_MAX_CLOCK_PHASE_SHIFT: return "F_GET_MAX_CLOCK_PHASE_SHIFT"; + case F_SET_CLOCK_DIVIDER: return "F_SET_CLOCK_DIVIDER"; + case F_GET_CLOCK_DIVIDER: return "F_GET_CLOCK_DIVIDER"; + + default: return "Unknown Function"; } } @@ -403,6 +412,13 @@ void function_table() { flist[F_GET_STOREINRAM_MODE] = &get_storeinram; flist[F_SET_READOUT_MODE] = &set_readout_mode; flist[F_GET_READOUT_MODE] = &get_readout_mode; + flist[F_SET_CLOCK_FREQUENCY] = &set_clock_frequency; + flist[F_GET_CLOCK_FREQUENCY] = &get_clock_frequency; + flist[F_SET_CLOCK_PHASE] = &set_clock_phase; + flist[F_GET_CLOCK_PHASE] = &get_clock_phase; + flist[F_GET_MAX_CLOCK_PHASE_SHIFT] = &get_max_clock_phase_shift; + flist[F_SET_CLOCK_DIVIDER] = &set_clock_divider; + flist[F_GET_CLOCK_DIVIDER] = &get_clock_divider; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -4830,11 +4846,11 @@ int get_dest_udp_port(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); int retval = -1; - FILE_LOG(logDEBUG1, ("Getting destination port\n")); + FILE_LOG(logDEBUG1, ("Getting destination porstore in ram moden")); // get only retval = udpDetails.dstport; - FILE_LOG(logDEBUG, ("udp destination port retval: %u\n", retval)); + FILE_LOG(logDEBUG, ("udp destination port retstore in ram model: %u\n", retval)); return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } @@ -5184,3 +5200,267 @@ int get_readout_mode(int file_des) { return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } + + + + +int set_clock_frequency(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting frequency of clock %d: %u\n", args[0], args[1])); + + + functionNotImplemented(); +/* + // only set + if (Server_VerifyLock() == OK) { + enum CLKINDEX c = (enum CLKINDEX)args[0]; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot set frequency of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + ret = setFrequency(c, args[1]); + if (ret == FAIL) { + strcpy(mess, "Set frequency in unknown state. Reconfigure did not return.\n"); + FILE_LOG(logERROR, (mess)); + } else { + int retval = getFrequency(c); + FILE_LOG(logDEBUG1, ("retval frequency of clock %d: %d\n", (int)c, retval)); + + char cval[100]; + memset(cval, 0, 100); + sprintf(cval, "set frequency of clock %d Hz", (int)c); + validate(args[1], retval, cval, DEC); + } + } + } +*/ + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int get_clock_frequency(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Getting frequency of clock %d\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + enum CLKINDEX c = (enum CLKINDEX)arg; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot get frequency of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + retval = getFrequency(c); + FILE_LOG(logDEBUG1, ("retval frequency of clock %d Hz: %d\n", (int)c, retval)); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); +} + + + + +int set_clock_phase(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[3] = {-1, -1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting phase of clock %d: %u %s\n", args[0], args[1], (args[2] == 0 ? "" : "degrees"))); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + enum CLKINDEX c = (enum CLKINDEX)args[0]; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot set phase for clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + int val = args[1]; + int degrees = args[2]; + if (degrees && (val < 0 || val > 359)) { + ret = FAIL; + sprintf(mess, "Cannot set phase. Phase provided for C%d outside limits (0 - 359°C)\n", (int)c); + FILE_LOG(logERROR, (mess)); + } else if (!degrees && (val < 0 || val > getMaxPhase(c) - 1)) { + ret = FAIL; + sprintf(mess, "Cannot set phase. Phase provided for C%d outside limits (0 - %d phase shifts)\n", (int)c, getMaxPhase(c) - 1); + FILE_LOG(logERROR, (mess)); + } else { + ret = setPhase(c, val, degrees); + if (ret == FAIL) { + strcpy(mess, "Set phase in unknown state. Reconfigure did not return.\n"); + FILE_LOG(logERROR, (mess)); + } else { + int retval = getPhase(c, degrees); + FILE_LOG(logDEBUG1, ("retval phase for clock %d: %d %s \n", (int)c, retval, (degrees == 0 ? "" : "degrees"))); + + char cval[100]; + memset(cval, 0, 100); + sprintf(cval, "set phase for clock %d",(int)c); + if (!degrees) { + validate(val, retval, cval, DEC); + } else { + ret = validatePhaseinDegrees(c, val, retval); + if (ret == FAIL) { + sprintf(mess, "Could not set %s. Set %d degrees, got %d degrees\n", cval, val, retval); + FILE_LOG(logERROR,(mess)); + } + } + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int get_clock_phase(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + int retval = -1; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Getting phase for clock %d %s \n", args[0], (args[1] == 0 ? "" : "in degrees"))); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + enum CLKINDEX c = (enum CLKINDEX)args[0]; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot get phase of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + retval = getPhase(c, args[1]); + FILE_LOG(logDEBUG1, ("retval phase for clock %d: %d %s\n", (int)c, retval, (args[1] == 0 ? "" : "degrees"))); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); +} + + +int get_max_clock_phase_shift(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Getting max phase shift of clock %d\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + enum CLKINDEX c = (enum CLKINDEX)arg; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot get frequency of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + retval = getMaxPhase(c); + FILE_LOG(logDEBUG1, ("retval max phase shift of clock %d: %d\n", (int)c, retval)); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); +} + + +int set_clock_divider(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting divider of clock %d: %u\n", args[0], args[1])); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + enum CLKINDEX c = (enum CLKINDEX)args[0]; + int val = args[1]; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot set divider of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else if (getClockDivider(c) == val) { + FILE_LOG(logINFO, ("Same clock divider %d\n")); + } else if (val < 2 || val > getMaxClockDivider()) { + ret = FAIL; + sprintf(mess, "Cannot set divider of clock %d to %d. Value should be in range [2-%d]\n", (int)c, val, getMaxClockDivider()); + FILE_LOG(logERROR, (mess)); + } else { + ret = setClockDivider(c, val); + if (ret == FAIL) { + strcpy(mess, "Set divider in unknown state. Reconfigure did not return.\n"); + FILE_LOG(logERROR, (mess)); + } else { + int retval = getClockDivider(c); + FILE_LOG(logDEBUG1, ("retval divider of clock %d: %d\n", (int)c, retval)); + + char cval[100]; + memset(cval, 0, 100); + sprintf(cval, "set divider of clock %d Hz", (int)c); + validate(val, retval, cval, DEC); + } + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int get_clock_divider(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logDEBUG1, ("Getting divider of clock %d\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + enum CLKINDEX c = (enum CLKINDEX)arg; + if (c >= NUM_CLOCKS) { + ret = FAIL; + sprintf(mess, "Cannot get divider of clock %d. Max number of clocks is %d.\n", (int)c, NUM_CLOCKS - 1); + FILE_LOG(logERROR, (mess)); + } else { + retval = getClockDivider(c); + FILE_LOG(logDEBUG1, ("retval divider of clock %d Hz: %d\n", (int)c, retval)); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); +} + diff --git a/slsDetectorSoftware/include/CmdProxy.h b/slsDetectorSoftware/include/CmdProxy.h index 01fe1a97a..e9dce0948 100644 --- a/slsDetectorSoftware/include/CmdProxy.h +++ b/slsDetectorSoftware/include/CmdProxy.h @@ -141,7 +141,11 @@ class CmdProxy { {"rx_udpport", &CmdProxy::rx_udpport}, {"rx_udpport2", &CmdProxy::rx_udpport2}, {"numinterfaces", &CmdProxy::numinterfaces}, - {"selinterface", &CmdProxy::selinterface}}; + {"selinterface", &CmdProxy::selinterface}, + {"clkfreq", &CmdProxy::ClockFrequency}, + {"clkphase", &CmdProxy::ClockPhase}, + {"maxclkphaseshift", &CmdProxy::MaxClockPhaseShift}, + {"clkdiv", &CmdProxy::ClockDivider}}; StringMap depreciated_functions{{"r_readfreq", "rx_readfreq"}, {"r_padding", "rx_padding"}, @@ -171,6 +175,10 @@ class CmdProxy { std::string Period(int action); std::string Exptime(int action); std::string SubExptime(int action); + std::string ClockFrequency(int action); + std::string ClockPhase(int action); + std::string MaxClockPhaseShift(int action); + std::string ClockDivider(int action); INTEGER_COMMAND( rx_fifodepth, getRxFifoDepth, setRxFifoDepth, std::stoi, diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index b5dfeeda3..1edd384a8 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -1196,6 +1196,33 @@ class Detector { Result getRxCurrentFrameIndex(Positions pos = {}) const; + /** [Gotthard2] Hz */ + Result getClockFrequency(int clkIndex, Positions pos = {}); + + /** [unknown] Hz */ + void setClockFrequency(int clkIndex, int value, Positions pos = {}); + + /** [Gotthard2] */ + Result getClockPhase(int clkIndex, Positions pos = {}); + + /** [Gotthard2] */ + void setClockPhase(int clkIndex, int value, Positions pos = {}); + + /** [Gotthard2] */ + Result getMaxClockPhaseShift(int clkIndex, Positions pos = {}); + + /** [Gotthard2] */ + Result getClockPhaseinDegrees(int clkIndex, Positions pos = {}); + + /** [Gotthard2] */ + void setClockPhaseinDegrees(int clkIndex, int value, Positions pos = {}); + + /** [Gotthard2] */ + Result getClockDivider(int clkIndex, Positions pos = {}); + + /** [Gotthard2] */ + void setClockDivider(int clkIndex, int value, Positions pos = {}); + private: std::vector getPortNumbers(int start_port); }; diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 71fa755a9..e3e26da9a 100755 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -1679,6 +1679,27 @@ class slsDetector : public virtual slsDetectorDefs { */ void setDigitalIODelay(uint64_t pinMask, int delay); + /** [Gotthard2] */ + int getClockFrequency(int clkIndex); + + /** [Gotthard2] */ + void setClockFrequency(int clkIndex, int value); + + /** [Gotthard2] */ + int getClockPhase(int clkIndex, bool inDegrees); + + /** [Gotthard2] */ + void setClockPhase(int clkIndex, int value, bool inDegrees); + + /** [Gotthard2] */ + int getMaxClockPhaseShift(int clkIndex); + + /** [Gotthard2] */ + int getClockDivider(int clkIndex); + + /** [Gotthard2] */ + void setClockDivider(int clkIndex, int value); + private: /** * Send function parameters to detector (control server) diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index a18f7f497..45009e63e 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -181,4 +181,110 @@ std::string CmdProxy::ListCommands(int action) { } } + + +std::string CmdProxy::ClockFrequency(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[n_clock (0-8)] [freq_in_Hz]\n\t[Gotthard2] Frequency of clock n_clock in Hz. Use clkdiv to set frequency." << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + auto t = det->getClockFrequency(std::stoi(args[0]), {det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 2) { + WrongNumberOfParameters(2); + } + det->setClockFrequency(std::stoi(args[0]), std::stoi(args[1])); + //TODO print args + os << std::stoi(args[1]) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + + +std::string CmdProxy::ClockPhase(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[n_clock (0-8)] [phase] [deg (optional)]\n\t[Gotthard2] Phase of clock n_clock. If deg, then phase shift in degrees, else absolute phase shift values." << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() == 1) { + auto t = det->getClockPhase(std::stoi(args[0]), {det_id}); + os << OutString(t) << '\n'; + } else if (args.size() == 2) { + if (args[1] != "deg") { + throw sls::RuntimeError("Cannot scan argument" + args[1] + ". Did you mean deg?"); + } + auto t = det->getClockPhaseinDegrees(std::stoi(args[0]), {det_id}); + os << OutString(t) << '\n'; + } else { + WrongNumberOfParameters(1); + } + } else if (action == defs::PUT_ACTION) { + if (args.size() == 2) { + det->setClockPhase(std::stoi(args[0]), std::stoi(args[1]), {det_id}); + os << args[1] << '\n'; + } else if (args.size() == 3) { + if (args[2] != "deg") { + throw sls::RuntimeError("Cannot scan argument" + args[2] + ". Did you mean deg?"); + } + det->setClockPhaseinDegrees(std::stoi(args[0]), std::stoi(args[1]), {det_id}); + os << std::stoi(args[1]) << '\n'; + } else { + WrongNumberOfParameters(1); + } + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + +std::string CmdProxy::MaxClockPhaseShift(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[n_clock (0-8)]\n\t[Gotthard2] Absolute Maximum Phase shift of clock n_clock." << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + auto t = det->getMaxClockPhaseShift(std::stoi(args[0]), {det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + throw sls::RuntimeError("Cannot put"); + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + +std::string CmdProxy::ClockDivider(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[n_clock (0-8)] [n_divider]\n\t[Gotthard2] Clock Divider of clock n_clock. Must be greater than 1." << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + auto t = det->getClockDivider(std::stoi(args[0]), {det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 2) { + WrongNumberOfParameters(2); + } + det->setClockDivider(std::stoi(args[0]), std::stoi(args[1])); + //TODO print args + os << std::stoi(args[1]) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} } // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 22a22ecec..a9955bda3 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1544,6 +1544,42 @@ Result Detector::getRxCurrentFrameIndex(Positions pos) const { return pimpl->Parallel(&slsDetector::getReceiverCurrentFrameIndex, pos); } +Result Detector::getClockFrequency(int clkIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getClockFrequency, pos, clkIndex); +} + +void Detector::setClockFrequency(int clkIndex, int value, Positions pos) { + pimpl->Parallel(&slsDetector::setClockFrequency, pos, clkIndex, value); +} + +Result Detector::getClockPhase(int clkIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getClockPhase, pos, clkIndex, false); +} + +void Detector::setClockPhase(int clkIndex, int value, Positions pos) { + pimpl->Parallel(&slsDetector::setClockPhase, pos, clkIndex, value, false); +} + +Result Detector::getMaxClockPhaseShift(int clkIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getMaxClockPhaseShift, pos, clkIndex); +} + +Result Detector::getClockPhaseinDegrees(int clkIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getClockPhase, pos, clkIndex, true); +} + +void Detector::setClockPhaseinDegrees(int clkIndex, int value, Positions pos) { + pimpl->Parallel(&slsDetector::setClockPhase, pos, clkIndex, value, true); +} + +Result Detector::getClockDivider(int clkIndex, Positions pos) { + return pimpl->Parallel(&slsDetector::getClockDivider, pos, clkIndex); +} + +void Detector::setClockDivider(int clkIndex, int value, Positions pos) { + pimpl->Parallel(&slsDetector::setClockDivider, pos, clkIndex, value); +} + std::vector Detector::getPortNumbers(int start_port) { int num_sockets_per_detector = 1; switch (getDetectorType({}).squash()) { diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index 1c0c57f40..760cd34b0 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -3425,6 +3425,57 @@ void slsDetector::setDigitalIODelay(uint64_t pinMask, int delay) { FILE_LOG(logDEBUG1) << "Digital IO Delay successful"; } +int slsDetector::getClockFrequency(int clkIndex) { + int retval = -1; + FILE_LOG(logDEBUG1) << "Getting Clock " << clkIndex << " frequency"; + sendToDetector(F_GET_CLOCK_FREQUENCY, clkIndex, retval); + FILE_LOG(logDEBUG1) << "Clock " << clkIndex << " frequency: " << retval; + return retval; +} + +void slsDetector::setClockFrequency(int clkIndex, int value) { + int args[]{clkIndex, value}; + FILE_LOG(logDEBUG1) << "Setting Clock " << clkIndex << " frequency to " << value; + sendToDetector(F_SET_CLOCK_FREQUENCY, args, nullptr); +} + +int slsDetector::getClockPhase(int clkIndex, bool inDegrees) { + int args[]{clkIndex, static_cast(inDegrees)}; + int retval = -1; + FILE_LOG(logDEBUG1) << "Getting Clock " << clkIndex << " phase " << (inDegrees ? "in degrees" : ""); + sendToDetector(F_GET_CLOCK_PHASE, args, retval); + FILE_LOG(logDEBUG1) << "Clock " << clkIndex << " frequency: " << retval << (inDegrees ? "degrees" : ""); + return retval; +} + +void slsDetector::setClockPhase(int clkIndex, int value, bool inDegrees) { + int args[]{clkIndex, value, static_cast(inDegrees)}; + FILE_LOG(logDEBUG1) << "Setting Clock " << clkIndex << " phase to " << value << (inDegrees ? "degrees" : ""); + sendToDetector(F_SET_CLOCK_PHASE, args, nullptr); +} + +int slsDetector::getMaxClockPhaseShift(int clkIndex) { + int retval = -1; + FILE_LOG(logDEBUG1) << "Getting Max Phase Shift for Clock " << clkIndex; + sendToDetector(F_GET_MAX_CLOCK_PHASE_SHIFT, clkIndex, retval); + FILE_LOG(logDEBUG1) << "Max Phase Shift for Clock " << clkIndex << ": " << retval; + return retval; +} + +int slsDetector::getClockDivider(int clkIndex) { + int retval = -1; + FILE_LOG(logDEBUG1) << "Getting Clock " << clkIndex << " divider"; + sendToDetector(F_GET_CLOCK_DIVIDER, clkIndex, retval); + FILE_LOG(logDEBUG1) << "Clock " << clkIndex << " divider: " << retval; + return retval; +} + +void slsDetector::setClockDivider(int clkIndex, int value) { + int args[]{clkIndex, value}; + FILE_LOG(logDEBUG1) << "Setting Clock " << clkIndex << " divider to " << value; + sendToDetector(F_SET_CLOCK_DIVIDER, args, nullptr); +} + sls_detector_module slsDetector::interpolateTrim(sls_detector_module *a, sls_detector_module *b, const int energy, const int e1, diff --git a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp index c7dcd85a7..fc35e4ea9 100644 --- a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp +++ b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp @@ -9,6 +9,7 @@ auto GET = slsDetectorDefs::GET_ACTION; auto PUT = slsDetectorDefs::PUT_ACTION; + TEST_CASE("rx_fifodepth", "[.cmd]") { { diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index 4271dc68d..bf0286f4d 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -124,6 +124,13 @@ enum detFuncs{ F_GET_STOREINRAM_MODE, F_SET_READOUT_MODE, F_GET_READOUT_MODE, + F_SET_CLOCK_FREQUENCY, + F_GET_CLOCK_FREQUENCY, + F_SET_CLOCK_PHASE, + F_GET_CLOCK_PHASE, + F_GET_MAX_CLOCK_PHASE_SHIFT, + F_SET_CLOCK_DIVIDER, + F_GET_CLOCK_DIVIDER, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 128, /**< detector function should not exceed this (detector server should not compile anyway) */ @@ -307,6 +314,14 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_STOREINRAM_MODE: return "F_GET_STOREINRAM_MODE"; case F_SET_READOUT_MODE: return "F_SET_READOUT_MODE"; case F_GET_READOUT_MODE: return "F_GET_READOUT_MODE"; + case F_SET_CLOCK_FREQUENCY: return "F_SET_CLOCK_FREQUENCY"; + case F_GET_CLOCK_FREQUENCY: return "F_GET_CLOCK_FREQUENCY"; + case F_SET_CLOCK_PHASE: return "F_SET_CLOCK_PHASE"; + case F_GET_CLOCK_PHASE: return "F_GET_CLOCK_PHASE"; + case F_GET_MAX_CLOCK_PHASE_SHIFT: return "F_GET_MAX_CLOCK_PHASE_SHIFT"; + case F_SET_CLOCK_DIVIDER: return "F_SET_CLOCK_DIVIDER"; + case F_GET_CLOCK_DIVIDER: return "F_GET_CLOCK_DIVIDER"; + case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 88452f0a4..c76e5d22b 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -7,6 +7,6 @@ #define APICTB 0x190930 #define APIGOTTHARD 0x190930 #define APIEIGER 0x190930 -#define APIGOTTHARD2 0x191008 #define APIMYTHEN3 0x191008 #define APIJUNGFRAU 0x191008 +#define APIGOTTHARD2 0x191017