mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-02-14 01:18:42 +01:00
ctb: add patternstart command, xilinx: fix frequency (#1307)
* add patternstart command for CTB, block end of execution udp packets if pattern was started by patternstart command * update docs * Dhanya's comments * more Dhanya comments * refactored * fixed tests for startpatttern, also clkfrequency not properly used in server * xilinx: fixed setfrequency, tick clock (with sync clock), clkfrequency set from getfrequency to get the exact value * xilinx freq in kHz, updated default values and prints --------- Co-authored-by: Martin Mueller <martin.mueller@psi.ch> Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch>
This commit is contained in:
@@ -384,6 +384,13 @@
|
||||
#define PLL_CNTRL_ADDR_OFST (16)
|
||||
#define PLL_CNTRL_ADDR_MSK (0x0000003F << PLL_CNTRL_ADDR_OFST)
|
||||
|
||||
/* Streaming Control RW regiser */
|
||||
#define STREAMING_CTRL_REG (0x3D << MEM_MAP_SHIFT)
|
||||
#define STREAMING_CTRL_ENA_OFST (15)
|
||||
#define STREAMING_CTRL_ENA_MSK (0x00000001 << STREAMING_CTRL_ENA_OFST)
|
||||
#define STREAMING_CTRL_SELECT_OFST (0)
|
||||
#define STREAMING_CTRL_SELECT_MSK (0x0000003F << STREAMING_CTRL_SELECT_OFST)
|
||||
|
||||
/* Pattern Control RW register */
|
||||
#define PATTERN_CNTRL_REG (0x88 << MEM_MAP_SHIFT)
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -4,7 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq);
|
||||
int XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq);
|
||||
uint32_t XILINX_PLL_getFrequency(uint32_t clkIDX);
|
||||
bool XILINX_PLL_isLocked();
|
||||
void XILINX_PLL_reset();
|
||||
|
||||
@@ -58,7 +58,8 @@ uint64_t getPatternMask();
|
||||
void setPatternBitMask(uint64_t mask);
|
||||
uint64_t getPatternBitMask();
|
||||
|
||||
#if defined(MYTHEN3D) || defined(XILINX_CHIPTESTBOARDD)
|
||||
#if defined(MYTHEN3D) || defined(XILINX_CHIPTESTBOARDD) || \
|
||||
defined(CHIPTESTBOARDD)
|
||||
void startPattern();
|
||||
#endif
|
||||
char *getPatternFileName();
|
||||
|
||||
@@ -72,14 +72,14 @@
|
||||
// clang-format on
|
||||
|
||||
// freq in kHz !!
|
||||
void XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
int XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
if (clk_index >= XILINX_PLL_NUM_CLKS) {
|
||||
LOG(logERROR, ("XILINX_PLL: Invalid clock index %d\n", clk_index));
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (freq < XILINX_PLL_MIN_FREQ || freq > XILINX_PLL_MAX_FREQ) {
|
||||
LOG(logERROR, ("XILINX_PLL: Frequency %d kHz is out of range\n", freq));
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// calculate base clock frequency
|
||||
@@ -103,7 +103,7 @@ void XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
if (clk_div < 1 || clk_div > XILINX_PLL_MAX_CLK_DIV) {
|
||||
LOG(logERROR,
|
||||
("XILINX_PLL: Invalid clock divider, need to change base clock\n"));
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t clk_div_frac = 0;
|
||||
@@ -140,18 +140,19 @@ void XILINX_PLL_setFrequency(uint32_t clk_index, uint32_t freq) {
|
||||
|
||||
// wait for firmware to measure the actual frequency
|
||||
usleep(2 * 1000 * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t XILINX_PLL_getFrequency(uint32_t clk_index) {
|
||||
if (clk_index >= XILINX_PLL_NUM_CLKS) {
|
||||
LOG(logERROR, ("XILINX_PLL: Invalid clock index %d\n", clk_index));
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (clk_index > XILINX_PLL_MAX_NUM_CLKS_FOR_GET) {
|
||||
LOG(logERROR,
|
||||
("XILINX_PLL: get frequency not implemented for this clock %d\n",
|
||||
clk_index));
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t base_addr = XILINX_PLL_MEASURE_BASE_ADDR0;
|
||||
|
||||
@@ -623,28 +623,43 @@ uint64_t getPatternBitMask() {
|
||||
return getU64BitReg(PATTERN_SET_LSB_REG, PATTERN_SET_MSB_REG);
|
||||
}
|
||||
|
||||
#ifdef MYTHEN3D
|
||||
void startPattern() {
|
||||
LOG(logINFOBLUE, ("Starting Pattern\n"));
|
||||
#ifdef MYTHEN3D
|
||||
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STRT_PATTERN_MSK);
|
||||
usleep(1);
|
||||
while (bus_r(PAT_STATUS_REG) & PAT_STATUS_RUN_BUSY_MSK) {
|
||||
usleep(1);
|
||||
}
|
||||
LOG(logINFOBLUE, ("Pattern done\n"));
|
||||
}
|
||||
#endif
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
void startPattern() {
|
||||
LOG(logINFOBLUE, ("Starting Pattern\n"));
|
||||
#elif CHIPTESTBOARDD
|
||||
// we only want to run the pattern here. No acquisition, no UDP packets
|
||||
|
||||
// disable 10G UDP temporarily
|
||||
// except if the pattern explicitly contains udp trigger points
|
||||
uint32_t conf_reg_tmp = bus_r(CONFIG_REG);
|
||||
if ((bus_r(STREAMING_CTRL_REG) & STREAMING_CTRL_ENA_MSK) == 0) {
|
||||
bus_w(CONFIG_REG, conf_reg_tmp & ~CONFIG_GB10_SND_UDP_MSK);
|
||||
}
|
||||
|
||||
// run the pattern, wait till done
|
||||
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STRT_ACQSTN_MSK);
|
||||
bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_STRT_ACQSTN_MSK);
|
||||
usleep(1);
|
||||
while (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK) {
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
// go back to original config
|
||||
bus_w(CONFIG_REG, conf_reg_tmp);
|
||||
#elif XILINX_CHIPTESTBOARDD
|
||||
bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK);
|
||||
usleep(1);
|
||||
while (bus_r(FLOW_CONTROL_REG) & RSM_BUSY_MSK) {
|
||||
usleep(1);
|
||||
}
|
||||
#endif
|
||||
LOG(logINFOBLUE, ("Pattern done\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
char *getPatternFileName() { return clientPatternfile; }
|
||||
|
||||
|
||||
@@ -5839,15 +5839,24 @@ int set_clock_frequency(int file_des) {
|
||||
LOG(logINFO, ("Same %s: %d %s\n", modeName, val,
|
||||
myDetectorType == GOTTHARD2 ? "Hz" : "MHz"));
|
||||
} else {
|
||||
setFrequency(c, val);
|
||||
int retval = getFrequency(c);
|
||||
LOG(logDEBUG1, ("retval %s: %d %s\n", modeName, retval,
|
||||
myDetectorType == GOTTHARD2 ? "Hz" : "MHz"));
|
||||
#if !defined( \
|
||||
XILINX_CHIPTESTBOARDD) // XCTB will give the actual frequency, which is not
|
||||
// 100% identical to the set frequency
|
||||
validate(&ret, mess, val, retval, modeName, DEC);
|
||||
int ret = setFrequency(c, val);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set %s to %d %s\n", modeName, val,
|
||||
myDetectorType == XILINX_CHIPTESTBOARD ? "kHz"
|
||||
: "MHz");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
int retval = getFrequency(c);
|
||||
LOG(logDEBUG1,
|
||||
("retval %s: %d %s\n", modeName, retval,
|
||||
myDetectorType == XILINX_CHIPTESTBOARD ? "kHz"
|
||||
: "MHz"));
|
||||
#if !defined(XILINX_CHIPTESTBOARDD)
|
||||
// XCTB will give the actual frequency, which is not
|
||||
// 100% identical to the set frequency
|
||||
validate(&ret, mess, val, retval, modeName, DEC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5902,8 +5911,11 @@ int get_clock_frequency(int file_des) {
|
||||
LOG(logDEBUG1,
|
||||
("retval %s clock (%d) frequency: %d %s\n", clock_names[c], (int)c,
|
||||
retval,
|
||||
myDetectorType == GOTTHARD2 || myDetectorType == MYTHEN3 ? "Hz"
|
||||
: "MHz"));
|
||||
myDetectorType == XILINX_CHIPTESTBOARD
|
||||
? "kHz"
|
||||
: (myDetectorType == GOTTHARD2 || myDetectorType == MYTHEN3
|
||||
? "Hz"
|
||||
: "MHz")));
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
@@ -7468,7 +7480,8 @@ int start_pattern(int file_des) {
|
||||
memset(mess, 0, sizeof(mess));
|
||||
|
||||
LOG(logDEBUG1, ("Starting Pattern\n"));
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD)
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) && \
|
||||
!defined(CHIPTESTBOARDD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
|
||||
Binary file not shown.
@@ -40,8 +40,7 @@ char initErrorMessage[MAX_STR_LENGTH];
|
||||
|
||||
int detPos[2] = {0, 0};
|
||||
|
||||
uint32_t clkFrequency[NUM_CLOCKS] = {20, 100, 20, 100};
|
||||
|
||||
uint32_t clkFrequency[NUM_CLOCKS] = {};
|
||||
int chipConfigured = 0;
|
||||
int analogEnable = 0;
|
||||
int digitalEnable = 0;
|
||||
@@ -376,6 +375,10 @@ void setupDetector() {
|
||||
LOG(logINFO, ("Setting up Server for 1 Xilinx Chip Test Board\n"));
|
||||
|
||||
// default variables
|
||||
clkFrequency[RUN_CLK] = DEFAULT_RUN_CLK;
|
||||
clkFrequency[ADC_CLK] = DEFAULT_ADC_CLK;
|
||||
clkFrequency[SYNC_CLK] = DEFAULT_SYNC_CLK;
|
||||
clkFrequency[DBIT_CLK] = DEFAULT_DBIT_CLK;
|
||||
chipConfigured = 0;
|
||||
analogEnable = 0;
|
||||
digitalEnable = 0;
|
||||
@@ -1061,12 +1064,12 @@ int setPeriod(int64_t val) {
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting period %lld ns\n", (long long int)val));
|
||||
val *= (1E-3 * RUN_CLK);
|
||||
val *= (1E-3 * clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(val, PERIOD_IN_REG_1, PERIOD_IN_REG_2);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getPeriod();
|
||||
val /= (1E-3 * RUN_CLK);
|
||||
val /= (1E-3 * clkFrequency[RUN_CLK]);
|
||||
if (val != retval) {
|
||||
return FAIL;
|
||||
}
|
||||
@@ -1074,7 +1077,8 @@ int setPeriod(int64_t val) {
|
||||
}
|
||||
|
||||
int64_t getPeriod() {
|
||||
return getU64BitReg(PERIOD_IN_REG_1, PERIOD_IN_REG_2) / (1E-3 * RUN_CLK);
|
||||
return getU64BitReg(PERIOD_IN_REG_1, PERIOD_IN_REG_2) /
|
||||
(1E-3 * clkFrequency[RUN_CLK]);
|
||||
}
|
||||
|
||||
int setDelayAfterTrigger(int64_t val) {
|
||||
@@ -1083,12 +1087,12 @@ int setDelayAfterTrigger(int64_t val) {
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting delay after trigger %ld ns\n", val));
|
||||
val *= (1E-3 * RUN_CLK);
|
||||
val *= (1E-3 * clkFrequency[RUN_CLK]);
|
||||
setU64BitReg(val, DELAY_IN_REG_1, DELAY_IN_REG_2);
|
||||
|
||||
// validate for tolerance
|
||||
int64_t retval = getDelayAfterTrigger();
|
||||
val /= (1E-3 * RUN_CLK);
|
||||
val /= (1E-3 * clkFrequency[RUN_CLK]);
|
||||
if (val != retval) {
|
||||
return FAIL;
|
||||
}
|
||||
@@ -1096,7 +1100,8 @@ int setDelayAfterTrigger(int64_t val) {
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTrigger() {
|
||||
return getU64BitReg(DELAY_IN_REG_1, DELAY_IN_REG_2) / (1E-3 * RUN_CLK);
|
||||
return getU64BitReg(DELAY_IN_REG_1, DELAY_IN_REG_2) /
|
||||
(1E-3 * clkFrequency[RUN_CLK]);
|
||||
}
|
||||
|
||||
int64_t getNumFramesLeft() {
|
||||
@@ -1108,11 +1113,13 @@ int64_t getNumTriggersLeft() {
|
||||
}
|
||||
|
||||
int64_t getDelayAfterTriggerLeft() {
|
||||
return getU64BitReg(DELAY_OUT_REG_1, DELAY_OUT_REG_2) / (1E-3 * RUN_CLK);
|
||||
return getU64BitReg(DELAY_OUT_REG_1, DELAY_OUT_REG_2) /
|
||||
(1E-3 * clkFrequency[RUN_CLK]);
|
||||
}
|
||||
|
||||
int64_t getPeriodLeft() {
|
||||
return getU64BitReg(PERIOD_OUT_REG_1, PERIOD_OUT_REG_2) / (1E-3 * RUN_CLK);
|
||||
return getU64BitReg(PERIOD_OUT_REG_1, PERIOD_OUT_REG_2) /
|
||||
(1E-3 * clkFrequency[RUN_CLK]);
|
||||
}
|
||||
|
||||
int64_t getFramesFromStart() {
|
||||
@@ -1122,12 +1129,12 @@ int64_t getFramesFromStart() {
|
||||
|
||||
int64_t getActualTime() {
|
||||
return getU64BitReg(TIME_FROM_START_OUT_REG_1, TIME_FROM_START_OUT_REG_2) /
|
||||
(1E-3 * TICK_CLK);
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
}
|
||||
|
||||
int64_t getMeasurementTime() {
|
||||
return getU64BitReg(FRAME_TIME_OUT_REG_1, FRAME_TIME_OUT_REG_2) /
|
||||
(1E-3 * TICK_CLK);
|
||||
(1E-3 * clkFrequency[SYNC_CLK]);
|
||||
}
|
||||
|
||||
/* parameters - dac, adc, hv */
|
||||
@@ -1792,10 +1799,16 @@ int setFrequency(enum CLKINDEX ind, int val) {
|
||||
}
|
||||
|
||||
char *clock_names[] = {CLK_NAMES};
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d MHz\n",
|
||||
LOG(logINFO, ("\tSetting %s clock (%d) frequency to %d kHz\n",
|
||||
clock_names[ind], ind, val));
|
||||
|
||||
XILINX_PLL_setFrequency(ind, val);
|
||||
if (XILINX_PLL_setFrequency(ind, val) == FAIL) {
|
||||
LOG(logERROR, ("\tCould not set %s clock (%d) frequency to %d kHz\n",
|
||||
clock_names[ind], ind, val));
|
||||
return FAIL;
|
||||
}
|
||||
clkFrequency[ind] = val;
|
||||
// TODO later: connect setPhase as phase gets reset on freq change
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1804,5 +1817,8 @@ int getFrequency(enum CLKINDEX ind) {
|
||||
LOG(logERROR, ("Unknown clock index %d to get frequency\n", ind));
|
||||
return -1;
|
||||
}
|
||||
return XILINX_PLL_getFrequency(ind);
|
||||
#ifndef VIRTUAL
|
||||
clkFrequency[ind] = XILINX_PLL_getFrequency(ind);
|
||||
#endif
|
||||
return clkFrequency[ind];
|
||||
}
|
||||
@@ -71,8 +71,6 @@
|
||||
#define POWER_RGLTR_MAX (2661)
|
||||
#define VIO_MIN_MV (1200) // for fpga to function
|
||||
|
||||
#define TICK_CLK (20) // MHz (trig_timeFromStart, frametime, timeFromStart)
|
||||
|
||||
/* Defines in the Firmware */
|
||||
#define WAIT_TIME_PATTERN_READ (10)
|
||||
#define WAIT_TIME_OUT_0US_TIMES (35000) // 2s
|
||||
@@ -156,4 +154,9 @@ typedef struct udp_header_struct {
|
||||
#define UDP_IP_HEADER_LENGTH_BYTES (28)
|
||||
|
||||
enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
#define CLK_NAMES "run", "adc", "sync", "dbit"
|
||||
#define CLK_NAMES "run", "adc", "sync", "dbit"
|
||||
|
||||
#define DEFAULT_RUN_CLK (20000) // 20 MHz
|
||||
#define DEFAULT_ADC_CLK (100000) // 100 MHz
|
||||
#define DEFAULT_SYNC_CLK (20000) // 20 MHz
|
||||
#define DEFAULT_DBIT_CLK (100000) // 100 MHz
|
||||
Reference in New Issue
Block a user