mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-21 17:18:00 +02:00
set clock divider, phase and get clock freq for gotthard2, priliminary
This commit is contained in:
195
slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
Executable file
195
slsDetectorServers/slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
Executable file
@ -0,0 +1,195 @@
|
||||
#include "ALTERA_PLL_CYCLONE10.h"
|
||||
#include "clogger.h"
|
||||
#include "nios.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
#include <unistd.h> // 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user