Commit c0ffd31c authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'greg-wrs-low-jitter' into proposed_master

parents 780ed522 de1a914a
......@@ -69,23 +69,15 @@ struct ad9516_reg {
#define SPI_CTRL_GO_BSY (1<<8)
#define SPI_CTRL_CHAR_LEN(x) ((x) & 0x7f)
#define GPIO_PLL_RESET_N 1
#define GPIO_SYS_CLK_SEL 0
#define GPIO_PERIPH_RESET_N 3
#define CS_PLL 0 /* AD9516 on SPI CS0 */
static void *oc_spi_base;
static int oc_spi_init(void *base_addr)
{
oc_spi_base = base_addr;
writel(100, oc_spi_base + SPI_REG_DIVIDER);
writel(100, base_addr + SPI_REG_DIVIDER);
return 0;
}
static int oc_spi_txrx(int ss, int nbits, uint32_t in, uint32_t *out)
static int oc_spi_txrx(void *base, int ss, int nbits, uint32_t in, uint32_t *out)
{
uint32_t rval;
......@@ -94,17 +86,17 @@ static int oc_spi_txrx(int ss, int nbits, uint32_t in, uint32_t *out)
writel(SPI_CTRL_ASS | SPI_CTRL_CHAR_LEN(nbits)
| SPI_CTRL_TXNEG,
oc_spi_base + SPI_REG_CTRL);
base + SPI_REG_CTRL);
writel(in, oc_spi_base + SPI_REG_TX0);
writel((1 << ss), oc_spi_base + SPI_REG_SS);
writel(in, base + SPI_REG_TX0);
writel((1 << ss), base + SPI_REG_SS);
writel(SPI_CTRL_ASS | SPI_CTRL_CHAR_LEN(nbits)
| SPI_CTRL_TXNEG | SPI_CTRL_GO_BSY,
oc_spi_base + SPI_REG_CTRL);
base + SPI_REG_CTRL);
while(readl(oc_spi_base + SPI_REG_CTRL) & SPI_CTRL_GO_BSY)
while(readl(base + SPI_REG_CTRL) & SPI_CTRL_GO_BSY)
;
*out = readl(oc_spi_base + SPI_REG_RX0);
*out = readl(base + SPI_REG_RX0);
return 0;
}
......@@ -113,39 +105,39 @@ static int oc_spi_txrx(int ss, int nbits, uint32_t in, uint32_t *out)
* "reg" is 12 bits, "val" is 8 bits, but both are better used as int
*/
static void ad9516_write_reg(int reg, int val)
static void ad9516_write_reg(void *base, int reg, int val)
{
oc_spi_txrx(CS_PLL, 24, (reg << 8) | val, NULL);
oc_spi_txrx(base, CS_PLL, 24, (reg << 8) | val, NULL);
}
static int ad9516_read_reg(int reg)
static int ad9516_read_reg(void *base, int reg)
{
uint32_t rval;
oc_spi_txrx(CS_PLL, 24, (reg << 8) | (1 << 23), &rval);
oc_spi_txrx(base, CS_PLL, 24, (reg << 8) | (1 << 23), &rval);
return rval & 0xff;
}
static void ad9516_load_regset(const struct ad9516_reg *regs, int n_regs, int commit)
static void ad9516_load_regset(void *base, const struct ad9516_reg *regs, int n_regs, int commit)
{
int i;
for(i=0; i<n_regs; i++)
ad9516_write_reg(regs[i].reg, regs[i].val);
ad9516_write_reg(base, regs[i].reg, regs[i].val);
if(commit)
ad9516_write_reg(0x232, 1);
ad9516_write_reg(base, 0x232, 1);
}
static void ad9516_wait_lock(void)
static void ad9516_wait_lock(void *base)
{
while ((ad9516_read_reg(0x1f) & 1) == 0);
while ((ad9516_read_reg(base, 0x1f) & 1) == 0);
}
#define SECONDARY_DIVIDER 0x100
static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
static int ad9516_set_output_divider(void *spi_base, int output, int ratio, int phase_offset)
{
uint8_t lcycles = (ratio/2) - 1;
uint8_t hcycles = (ratio - (ratio / 2)) - 1;
......@@ -158,12 +150,12 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
if(ratio == 1) /* bypass the divider */
{
uint8_t div_ctl = ad9516_read_reg(base + 1);
ad9516_write_reg(base + 1, div_ctl | (1<<7) | (phase_offset & 0xf));
uint8_t div_ctl = ad9516_read_reg(spi_base, base + 1);
ad9516_write_reg(spi_base, base + 1, div_ctl | (1<<7) | (phase_offset & 0xf));
} else {
uint8_t div_ctl = ad9516_read_reg(base + 1);
ad9516_write_reg(base + 1, (div_ctl & (~(1<<7))) | (phase_offset & 0xf)); /* disable bypass bit */
ad9516_write_reg(base, (lcycles << 4) | hcycles);
uint8_t div_ctl = ad9516_read_reg(spi_base, base + 1);
ad9516_write_reg(spi_base, base + 1, (div_ctl & (~(1<<7))) | (phase_offset & 0xf)); /* disable bypass bit */
ad9516_write_reg(spi_base, base, (lcycles << 4) | hcycles);
}
} else { /* LVDS/CMOS outputs */
......@@ -174,16 +166,16 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
if(!secondary)
{
if(ratio == 1) /* bypass the divider 1 */
ad9516_write_reg(base + 3, ad9516_read_reg(base + 3) | 0x10);
ad9516_write_reg(spi_base, base + 3, ad9516_read_reg(spi_base, base + 3) | 0x10);
else {
ad9516_write_reg(base, (lcycles << 4) | hcycles);
ad9516_write_reg(base + 1, phase_offset & 0xf);
ad9516_write_reg(spi_base, base, (lcycles << 4) | hcycles);
ad9516_write_reg(spi_base, base + 1, phase_offset & 0xf);
}
} else {
if(ratio == 1) /* bypass the divider 2 */
ad9516_write_reg(base + 3, ad9516_read_reg(base + 3) | 0x20);
ad9516_write_reg(spi_base, base + 3, ad9516_read_reg(spi_base, base + 3) | 0x20);
else {
ad9516_write_reg(base + 2, (lcycles << 4) | hcycles);
ad9516_write_reg(spi_base, base + 2, (lcycles << 4) | hcycles);
// ad9516_write_reg(base + 1, phase_offset & 0xf);
}
......@@ -191,40 +183,46 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
}
/* update */
ad9516_write_reg(0x232, 0x0);
ad9516_write_reg(0x232, 0x1);
ad9516_write_reg(0x232, 0x0);
ad9516_write_reg(spi_base, 0x232, 0x0);
ad9516_write_reg(spi_base, 0x232, 0x1);
ad9516_write_reg(spi_base, 0x232, 0x0);
return 0;
}
static int ad9516_set_vco_divider(int ratio) /* Sets the VCO divider (2..6) or 0 to enable static output */
static int ad9516_set_vco_divider(void *spi_base, int ratio) /* Sets the VCO divider (2..6) or 0 to enable static output */
{
if(ratio == 0)
ad9516_write_reg(0x1e0, 0x5); /* static mode */
ad9516_write_reg(spi_base, 0x1e0, 0x5); /* static mode */
else
ad9516_write_reg(0x1e0, (ratio-2));
ad9516_write_reg(0x232, 0x1);
ad9516_write_reg(spi_base, 0x1e0, (ratio-2));
ad9516_write_reg(spi_base, 0x232, 0x1);
ad9516_write_reg(spi_base, 0x232, 0x0);
return 0;
}
static void ad9516_sync_outputs(void)
static void ad9516_sync_outputs(void *spi_base)
{
/* VCO divider: static mode */
ad9516_write_reg(0x1E0, 0x7);
ad9516_write_reg(0x232, 0x1);
ad9516_write_reg(spi_base, 0x1E0, 0x7);
ad9516_write_reg(spi_base, 0x232, 0x1);
/* Sync the outputs when they're inactive to avoid +-1 cycle uncertainity */
ad9516_write_reg(0x230, 1);
ad9516_write_reg(0x232, 1);
ad9516_write_reg(0x230, 0);
ad9516_write_reg(0x232, 1);
ad9516_write_reg(spi_base, 0x230, 1);
ad9516_write_reg(spi_base, 0x232, 1);
ad9516_write_reg(spi_base, 0x230, 0);
ad9516_write_reg(spi_base, 0x232, 1);
ad9516_write_reg(spi_base, 0x232, 0x0);
}
int ad9516_init(int scb_version)
int ad9516_init(int scb_version, int ljd_present)
{
pp_printf("Initializing AD9516 PLL...\n");
oc_spi_init((void *)BASE_SPI);
void *spi_base = (void *)BASE_SPI;
gpio_out(GPIO_SYS_CLK_SEL, 0); /* switch to the standby reference clock, since the PLL is off after reset */
......@@ -235,30 +233,34 @@ int ad9516_init(int scb_version)
timer_delay(10);
/* Use unidirectional SPI mode */
ad9516_write_reg(0x000, 0x99);
ad9516_write_reg(spi_base, 0x000, 0x99);
/* Check the presence of the chip */
if (ad9516_read_reg(0x3) != 0xc3) {
if (ad9516_read_reg(spi_base, 0x3) != 0xc3) {
pp_printf("Error: AD9516 PLL not responding.\n");
return -1;
}
if( scb_version >= 34) //New SCB v3.4. 10MHz Output.
ad9516_load_regset(ad9516_base_config_34, ARRAY_SIZE(ad9516_base_config_34), 0);
ad9516_load_regset(spi_base, ad9516_base_config_34, ARRAY_SIZE(ad9516_base_config_34), 0);
else //Old one
ad9516_load_regset(ad9516_base_config_33, ARRAY_SIZE(ad9516_base_config_33), 0);
ad9516_load_regset(spi_base, ad9516_base_config_33, ARRAY_SIZE(ad9516_base_config_33), 0);
ad9516_load_regset(ad9516_ref_tcxo, ARRAY_SIZE(ad9516_ref_tcxo), 1);
ad9516_wait_lock();
/* Set R divider value depending on Low-Jitter Daughterboard presence */
if (ljd_present)
ad9516_load_regset(spi_base, ad9516_ref_ljd, ARRAY_SIZE(ad9516_ref_tcxo), 1);
else
ad9516_load_regset(spi_base, ad9516_ref_tcxo, ARRAY_SIZE(ad9516_ref_tcxo), 1);
ad9516_wait_lock(spi_base);
ad9516_sync_outputs();
ad9516_sync_outputs(spi_base);
if( scb_version >= 34) { //New SCB v3.4. 10MHz Output.
ad9516_set_output_divider(2, 4, 0); // OUT2. 187.5 MHz. - not anymore
ad9516_set_output_divider(3, 4, 0); // OUT3. 187.5 MHz. - not anymore
ad9516_set_output_divider(spi_base, 2, 4, 0); // OUT2. 187.5 MHz. - not anymore
ad9516_set_output_divider(spi_base, 3, 4, 0); // OUT3. 187.5 MHz. - not anymore
ad9516_set_output_divider(4, 1, 0); // OUT4. 500 MHz.
ad9516_set_output_divider(spi_base, 4, 1, 0); // OUT4. 500 MHz.
/*The following PLL outputs have been configured through the ad9516_base_config_34 register,
* so it doesn't need to replicate the configuration:
......@@ -271,13 +273,13 @@ int ad9516_init(int scb_version)
} else { //Old one
ad9516_set_output_divider(9, 4, 0); /* AUX/SWCore = 187.5 MHz */ //not needed anymore
ad9516_set_output_divider(7, 8, 0); /* REF = 62.5 MHz */
ad9516_set_output_divider(4, 8, 0); /* GTX = 62.5 MHz */
ad9516_set_output_divider(spi_base, 9, 4, 0); /* AUX/SWCore = 187.5 MHz */ //not needed anymore
ad9516_set_output_divider(spi_base, 7, 8, 0); /* REF = 62.5 MHz */
ad9516_set_output_divider(spi_base, 4, 8, 0); /* GTX = 62.5 MHz */
}
ad9516_sync_outputs();
ad9516_set_vco_divider(3);
ad9516_sync_outputs(spi_base);
ad9516_set_vco_divider(spi_base, 3);
pp_printf("AD9516 locked.\n");
......@@ -288,6 +290,33 @@ int ad9516_init(int scb_version)
return 0;
}
int ljd_ad9516_init (void) {
pp_printf("Initializing Low-Jitter Daughterboard AD9516 PLL...\n");
oc_spi_init((void *)BASE_SPI_LJD_BOARD);
void *spi_base = (void *)BASE_SPI_LJD_BOARD;
/* Use unidirectional SPI mode */
ad9516_write_reg((void *)spi_base, 0x000, 0x99);
/* Check the presence of the chip */
if (ad9516_read_reg((void *)spi_base, 0x3) != 0xc3) {
pp_printf("Error: Low-Jitter Daughterboard AD9516 PLL not responding.\n");
return -1;
}
ad9516_write_reg(spi_base, 0x018, 0x0); // reset VCO calibration
ad9516_write_reg(spi_base, 0x232, 0x0);
ad9516_write_reg(spi_base, 0x232, 0x1);
ad9516_write_reg(spi_base, 0x232, 0x0);
ad9516_set_vco_divider(spi_base, 3);
ad9516_load_regset(spi_base, ad9516_ljd_base_config, ARRAY_SIZE(ad9516_ljd_base_config), 1);
ad9516_set_output_divider(spi_base, 6, 8, 0); // OUT6. 62.5MHz
ad9516_set_output_divider(spi_base, 8, 20, 0); // OUT6. 62.5MHz
return 0;
}
int rts_debug_command(int command, int value)
{
......@@ -296,13 +325,13 @@ int rts_debug_command(int command, int value)
case RTS_DEBUG_ENABLE_SERDES_CLOCKS:
if(value)
{
ad9516_write_reg(0xf4, 0x08); // OUT4 enabled
ad9516_write_reg(0x232, 0x0);
ad9516_write_reg(0x232, 0x1);
ad9516_write_reg((void *)BASE_SPI, 0xf4, 0x08); // OUT4 enabled
ad9516_write_reg((void *)BASE_SPI, 0x232, 0x0);
ad9516_write_reg((void *)BASE_SPI, 0x232, 0x1);
} else {
ad9516_write_reg(0xf4, 0x0a); // OUT4 power-down, no serdes clock
ad9516_write_reg(0x232, 0x0);
ad9516_write_reg(0x232, 0x1);
ad9516_write_reg((void *)BASE_SPI, 0xf4, 0x0a); // OUT4 power-down, no serdes clock
ad9516_write_reg((void *)BASE_SPI, 0x232, 0x0);
ad9516_write_reg((void *)BASE_SPI, 0x232, 0x1);
}
break;
}
......
......@@ -143,10 +143,85 @@ const struct ad9516_reg ad9516_base_config_34[] = {
{0x0231, 0x00},
};
/* Configuration for the SCB version greater than or equal 3.4: Base + 6, 7, 8, 9 outputs*/
const struct ad9516_reg ad9516_ljd_base_config[] = {
{0x0000, 0x99},
{0x0001, 0x00},
{0x0002, 0x10},
{0x0003, 0xC3},
{0x0004, 0x00},
{0x0010, 0x4C},
{0x0011, 0x00},
{0x0012, 0x00},
{0x0013, 0x06},
{0x0014, 0x12},
{0x0015, 0x00},
{0x0016, 0x04},
{0x0017, 0x00},
{0x0018, 0x07},
{0x0019, 0x00},
{0x001A, 0x00},
{0x001B, 0x00},
{0x001C, 0x01},
{0x001D, 0x00},
{0x001E, 0x00},
{0x001F, 0x0E},
{0x00A0, 0x01},
{0x00A1, 0x00},
{0x00A2, 0x00},
{0x00A3, 0x01},
{0x00A4, 0x00},
{0x00A5, 0x00},
{0x00A6, 0x01},
{0x00A7, 0x00},
{0x00A8, 0x00},
{0x00A9, 0x01},
{0x00AA, 0x00},
{0x00AB, 0x00},
{0x00F0, 0x0A},
{0x00F1, 0x0A},
{0x00F2, 0x0A},
{0x00F3, 0x0A},
{0x00F4, 0x08},
{0x00F5, 0x08},
// The following registers configure the PLL outputs from 6 to 9.
{0x0140, 0x42},
{0x0141, 0x42},
{0x0142, 0x08},
{0x0143, 0x4E},
{0x0190, 0x55},
{0x0191, 0x00},
{0x0192, 0x00},
{0x0193, 0x11},
{0x0194, 0x00},
{0x0195, 0x00},
{0x0196, 0x10},
{0x0197, 0x00},
{0x0198, 0x00},
{0x0199, 0x33},
{0x019A, 0x00},
{0x019B, 0x11},
{0x019C, 0x20},
{0x019D, 0x00},
{0x019E, 0x33},
{0x019F, 0x00},
{0x01A0, 0x11},
{0x01A1, 0x20},
{0x01A2, 0x00},
{0x01A3, 0x00},
//
{0x01E0, 0x01},
{0x01E1, 0x02},
{0x0230, 0x00},
{0x0231, 0x00},
};
/* Config for 25 MHz VCTCXO reference (RDiv = 5, use REF1) */
const struct ad9516_reg ad9516_ref_tcxo[] = {
{0x0011, 0x05},
{0x0012, 0x00}, /* RDiv = 5 */
{0x0012, 0x00}, /* RDiv = 4 */
{0x001C, 0x06} /* Use REF1 */
};
......@@ -157,3 +232,9 @@ const struct ad9516_reg ad9516_ref_ext[] = {
{0x001C, 0x46} /* Use REF1 */
};
/* Config for Low-Jitter Daughterboard */
const struct ad9516_reg ad9516_ref_ljd[] = {
{0x0011, 0x04},
{0x0012, 0x00}, /* RDiv = 4 */
{0x001C, 0x06} /* Use REF1 */
};
......@@ -21,6 +21,7 @@
#define BASE_GPIO 0x10300
#define BASE_TIMER 0x10400
#define BASE_PPS_GEN 0x10500
#define BASE_SPI_LJD_BOARD 0x10700
/* spll parameter that are board-specific */
#define BOARD_DIVIDE_DMTD_CLOCKS 0
......
......@@ -10,6 +10,13 @@
#include "board.h"
#define GPIO_SYS_CLK_SEL 0
#define GPIO_PLL_RESET_N 1
#define GPIO_PERIPH_RESET_N 3
#define GPIO_LJD_BOARD_DETECT 4
extern int ljd_present;
struct GPIO_WB
{
uint32_t CODR; /*Clear output register*/
......@@ -36,7 +43,7 @@ static inline void gpio_dir(int pin, int val)
__gpio->DDR &= ~(1<<pin);
}
static inline int gpio_in(int bank, int pin)
static inline int gpio_in(int pin)
{
return __gpio->PSR & (1<<pin) ? 1: 0;
}
......
......@@ -70,7 +70,8 @@ extern int abs(int val);
extern int wrc_ui_refperiod;
/* Init functions and defaults for the wrs build */
int ad9516_init(int scb_ver);
int ad9516_init(int scb_ver, int ljd_present);
int ljd_ad9516_init(void);
void rts_init(void);
int rtipc_init(void);
void rts_update(void);
......
......@@ -32,7 +32,7 @@ volatile struct SPLL_WB *SPLL;
volatile struct PPSG_WB *PPSG;
int spll_n_chan_ref, spll_n_chan_out;
int ljd_present = 0; /* Low-jitter Daughterboard presence indicator */
#define MAIN_CHANNEL (spll_n_chan_ref)
......@@ -485,12 +485,12 @@ void spll_show_stats()
if (softpll.mode > 0)
pp_printf("softpll: irqs %d seq %s mode %d "
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d\n",
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d setpoint:%d\n",
s->irq_count, statename,
s->mode, s->ext.align_state,
s->helper.ld.locked, s->mpll.ld.locked,
s->helper.pi.y, s->mpll.pi.y,
s->delock_count);
s->delock_count, s->mpll.phase_shift_current);
}
int spll_shifter_busy(int channel)
......@@ -649,7 +649,7 @@ int spll_update()
return ret != 0;
}
static int spll_measure_frequency(int osc)
int spll_measure_frequency(int osc)
{
volatile uint32_t *reg;
......@@ -667,7 +667,7 @@ static int spll_measure_frequency(int osc)
return 0;
}
timer_delay_ms(2000);
// timer_delay_ms(2000);
return (*reg ) & (0xfffffff);
}
......@@ -699,20 +699,20 @@ static int calc_apr(int meas_min, int meas_max, int f_center )
void check_vco_frequencies()
{
disable_irq();
//disable_irq();
int f_min, f_max;
pll_verbose("SoftPLL VCO Frequency/APR test:\n");
spll_set_dac(-1, 0);
// spll_set_dac(-1, 0);
f_min = spll_measure_frequency(SPLL_OSC_DMTD);
spll_set_dac(-1, 65535);
// spll_set_dac(-1, 65535);
f_max = spll_measure_frequency(SPLL_OSC_DMTD);
pll_verbose("DMTD VCO: Low=%d Hz Hi=%d Hz, APR = %d ppm.\n", f_min, f_max, calc_apr(f_min, f_max, 62500000));
spll_set_dac(0, 0);
// spll_set_dac(0, 0);
f_min = spll_measure_frequency(SPLL_OSC_REF);
spll_set_dac(0, 65535);
// spll_set_dac(0, 65535);
f_max = spll_measure_frequency(SPLL_OSC_REF);
pll_verbose("REF VCO: Low=%d Hz Hi=%d Hz, APR = %d ppm.\n", f_min, f_max, calc_apr(f_min, f_max, REF_CLOCK_FREQ_HZ));
......
......@@ -107,6 +107,7 @@ void spll_set_dac(int out_channel, int value);
int spll_get_dac(int out_channel);
void check_vco_frequencies(void);
int spll_measure_frequency(int osc);
/*
* Aux and main state:
......@@ -148,6 +149,7 @@ struct spll_fifo_log {
};
#define FIFO_LOG_LEN 16
extern int ljd_present;
#endif // __SOFTPLL_NG_H
......@@ -14,13 +14,14 @@
#include "softpll_ng.h"
#include "irq.h"
#define ALIGN_SAMPLE_PERIOD 100000
#define ALIGN_TARGET 0
#define EXT_PERIOD_NS 100
#define EXT_FREQ_HZ 10000000
#define EXT_PPS_LATENCY_PS 30000 // fixme: make configurable
// fixme: make configurable
#define EXT_PPS_LATENCY_PS 30000 // for regular ext channel
#define EXT_PPS_LATENCY_LJD_PS 63000 // for low-jitter daughterboard
void external_init(volatile struct spll_external_state *s, int ext_ref,
......@@ -28,6 +29,8 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
{
int idx = spll_n_chan_ref + spll_n_chan_out;
if (ljd_present)
idx++;
helper_init(s->helper, idx);
mpll_init(s->main, idx, spll_n_chan_ref);
......@@ -38,7 +41,7 @@ void external_init(volatile struct spll_external_state *s, int ext_ref,
void external_start(struct spll_external_state *s)
{
helper_start(s->helper);
helper_start(s->helper);
SPLL->ECCR = SPLL_ECCR_EXT_EN;
......@@ -50,10 +53,10 @@ void external_start(struct spll_external_state *s)
int external_locked(volatile struct spll_external_state *s)
{
if (!s->helper->ld.locked || !s->main->ld.locked ||
!(SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED) || // ext PLL became unlocked
(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED)) // 10MHz unplugged (only SPEC)
!(SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED) || // ext PLL became unlocked
(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED)) // 10MHz unplugged (only SPEC)
return 0;
switch(s->align_state) {
case ALIGN_STATE_EXT_OFF:
case ALIGN_STATE_WAIT_CLKIN:
......@@ -83,27 +86,53 @@ static int align_sample(int channel, int *v)
return 0; // sample not valid
}
static inline int get_pps_latency(int sel)
{
if (sel)
return EXT_PPS_LATENCY_LJD_PS;
else
return EXT_PPS_LATENCY_PS;
}
int external_align_fsm(volatile struct spll_external_state *s)
{
int v, done_sth = 0;
static int timeout;
switch(s->align_state) {
case ALIGN_STATE_EXT_OFF:
break;
case ALIGN_STATE_WAIT_CLKIN:
if( !(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED) ) {
if(!ljd_present && !(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED) ) {
SPLL->ECCR |= SPLL_ECCR_EXT_REF_PLLRST;
s->align_state = ALIGN_STATE_WAIT_PLOCK;
done_sth++;
}
#if defined(CONFIG_WR_SWITCH)
else if (ljd_present) {
uint32_t f_ext;
int ljd_ad9516_stat;
/* reset ljd ad9516 */
SPLL->ECCR |= SPLL_ECCR_EXT_REF_PLLRST;
timer_delay(10);
SPLL->ECCR &= (~SPLL_ECCR_EXT_REF_PLLRST);
timer_delay(10);
ljd_ad9516_stat = ljd_ad9516_init();
f_ext = spll_measure_frequency(SPLL_OSC_EXT);
if (!ljd_ad9516_stat && (f_ext > 9999000) && (f_ext < 10001000)) {
s->align_state = ALIGN_STATE_WAIT_PLOCK;
pp_printf("External AD9516 locked\n");
}
}
#endif
break;
case ALIGN_STATE_WAIT_PLOCK:
SPLL->ECCR &= (~SPLL_ECCR_EXT_REF_PLLRST);
if( SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED )
if(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED )
s->align_state = ALIGN_STATE_WAIT_CLKIN;
else if( SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED )
else if(SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED)
s->align_state = ALIGN_STATE_START;
done_sth++;
break;
......@@ -115,6 +144,9 @@ int external_align_fsm(volatile struct spll_external_state *s)
enable_irq();
s->align_state = ALIGN_STATE_START_MAIN;
done_sth++;
} else if (time_after(timer_get_tics(), timeout + 5*TICS_PER_SECOND)) {
pll_verbose("EXT: timeout, restarting\n");
s->align_state = ALIGN_STATE_WAIT_CLKIN;
}
break;
......@@ -127,6 +159,9 @@ int external_align_fsm(volatile struct spll_external_state *s)
s->align_state = ALIGN_STATE_INIT_CSYNC;
pll_verbose("EXT: DMTD locked.\n");
done_sth++;
} else if (time_after(timer_get_tics(), timeout + 5*TICS_PER_SECOND)) {
pll_verbose("EXT: timeout, restarting\n");
s->align_state = ALIGN_STATE_WAIT_CLKIN;
}
break;
......@@ -171,8 +206,8 @@ int external_align_fsm(volatile struct spll_external_state *s)
s->align_shift += s->align_step;
mpll_set_phase_shift(s->main, s->align_shift);
} else if (v == s->align_target) {
s->align_shift += EXT_PPS_LATENCY_PS;
mpll_set_phase_shift(s->main, s->align_shift);
s->align_shift += get_pps_latency(ljd_present);
mpll_set_phase_shift(s->main, s->align_shift);
s->align_state = ALIGN_STATE_COMPENSATE_DELAY;
}
done_sth++;
......@@ -197,5 +232,8 @@ int external_align_fsm(volatile struct spll_external_state *s)
default:
break;
}
if (done_sth > 0) {
timeout = timer_get_tics();
}
return done_sth != 0;
}
......@@ -17,8 +17,13 @@ void helper_init(struct spll_helper_state *s, int ref_channel)
/* Phase branch PI controller */
s->pi.y_min = 5;
s->pi.y_max = (1 << DAC_BITS) - 5;
#if defined(CONFIG_WR_NODE)
s->pi.kp = -150;//(int)(0.3 * 32.0 * 16.0); // / 2;
s->pi.ki = -2;//(int)(0.03 * 32.0 * 3.0); // / 2;
#else
s->pi.kp = 150;
s->pi.ki = 2;
#endif
s->pi.anti_windup = 1;
/* Phase branch lock detection */
......@@ -83,8 +88,11 @@ void helper_start(struct spll_helper_state *s)
{
/* Set the bias to the upper end of tuning range. This is to ensure that
the HPLL will always lock on positive frequency offset. */
#if defined(CONFIG_WR_SWITCH)
s->pi.bias = s->pi.y_max;
#else
s->pi.bias = s->pi.y_min;
#endif
s->p_setpoint = 0;
s->p_adder = 0;
s->sample_n = 0;
......
......@@ -31,8 +31,13 @@ void mpll_init(struct spll_main_state *s, int id_ref,
s->pi.anti_windup = 1;
s->pi.bias = 30000;
#if defined(CONFIG_WR_SWITCH)
s->pi.kp = -1100; // / 2;
s->pi.ki = -30; // / 2;
if (ljd_present) {
s->pi.kp = 2000;
s->pi.ki = 15;
} else {
s->pi.kp = 1100; // / 2;
s->pi.ki = 30; // / 2;
}
#elif defined(CONFIG_WR_NODE)
s->pi.kp = -1100; // / 2;
s->pi.ki = -30; // / 2;
......@@ -157,11 +162,19 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
if (s->ld.locked) {
if (s->phase_shift_current < s->phase_shift_target) {
s->phase_shift_current++;
#if defined(CONFIG_WR_SWITCH)
s->adder_ref++;
#else
s->adder_ref--;
#endif
} else if (s->phase_shift_current >
s->phase_shift_target) {
s->phase_shift_current--;
#if defined(CONFIG_WR_SWITCH)
s->adder_ref--;
#else
s->adder_ref++;
#endif
}
}
if (ld_update((spll_lock_det_t *)&s->ld, err))
......
......@@ -56,8 +56,11 @@ int ptrackers_update(struct spll_ptracker_state *ptrackers, int tag,
if(!s->enabled)
return 0;
#if defined(CONFIG_WR_NODE)
register int delta = (tag - tag_ref) & ((1 << HPLL_N) - 1);
#else
register int delta = (tag_ref - tag) & ((1 << HPLL_N) - 1);
#endif
register int index = delta >> (HPLL_N - 2);
......
......@@ -13,6 +13,7 @@
#include "minipc.h"
#include "revision.h"
#include "system_checks.h"
#include "gpio-wrs.h"
int scb_ver = 33; /* SCB version */
......@@ -40,6 +41,12 @@ int main(void)
build_revision, build_date, build_time);
pp_printf("SCB version: %d. %s\n", scb_ver,(scb_ver>=34)?"10 MHz SMC Output.":"" );
pp_printf("Start counter %d\n", stats.start_cnt);
/* Low-jitter Daughterboard detection */
ljd_present = gpio_in(GPIO_LJD_BOARD_DETECT);
if (ljd_present) {
pp_printf("\n--- WRS Low jitter board detected. ---\n");
pp_printf("Allow 1 hour of warming up before starting measurements\n");
}
pp_printf("--\n");
if (stats.start_cnt > 1) {
......@@ -47,7 +54,7 @@ int main(void)
/* for sure problem is in calling second time ad9516_init,
* but not only */
}
ad9516_init(scb_ver);
ad9516_init(scb_ver, ljd_present);
rts_init();
rtipc_init();
spll_very_init();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment