Commit ff5c9c26 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll: synchronize slave channel DDMTD counter before starting MPLL (fixes…

softpll: synchronize slave channel DDMTD counter before starting MPLL (fixes reversed DMTD locking issues)
parent 07250b7b
......@@ -72,18 +72,21 @@ void _irq_entry()
switch(softpll.seq_state)
{
case SEQ_CLEAR_DACS:
SPLL->DAC_HPLL = 65535;
SPLL->DAC_MAIN = softpll.default_dac_main;
SPLL->OCER |= 1;
softpll.seq_state = SEQ_WAIT_CLEAR_DACS;
softpll.dac_timeout = timer_get_tics();
break;
case SEQ_WAIT_CLEAR_DACS:
if(timer_get_tics() - softpll.dac_timeout > 10000)
softpll.seq_state = (softpll.mode == SPLL_MODE_GRAND_MASTER ? SEQ_START_EXT : SEQ_START_HELPER);
break;
case SEQ_CLEAR_DACS:
SPLL->DAC_HPLL = 65535;
SPLL->DAC_MAIN = softpll.default_dac_main;
SPLL->OCER |= 1;
softpll.seq_state = SEQ_WAIT_CLEAR_DACS;
softpll.dac_timeout = timer_get_tics();
if(softpll.mode == SPLL_MODE_SLAVE)
spll_resync_dmtd_counter(softpll.mpll.id_ref);
break;
case SEQ_WAIT_CLEAR_DACS:
if(timer_get_tics() - softpll.dac_timeout > 10000)
softpll.seq_state = (softpll.mode == SPLL_MODE_GRAND_MASTER ? SEQ_START_EXT : SEQ_START_HELPER);
break;
case SEQ_DISABLED:
break;
......@@ -231,7 +234,7 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
SPLL->ECCR = 0;
SPLL->RCGER = 0;
SPLL->DCCR = 0;
SPLL->DEGLITCH_THR = 1000;
SPLL->DEGLITCH_THR = 300;
PPSG->ESCR = 0;
PPSG->CR = PPSG_CR_CNT_EN | PPSG_CR_CNT_RST | PPSG_CR_PWIDTH_W(100);
......@@ -276,6 +279,9 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
strcpy(mode_str, "Slave");
softpll.seq_state = SEQ_CLEAR_DACS;
spll_resync_dmtd_counter(slave_ref_channel);
while(!spll_check_dmtd_resync(slave_ref_channel));
helper_init(&softpll.helper, slave_ref_channel);
mpll_init(&softpll.mpll, slave_ref_channel, n_chan_ref);
......
......@@ -166,5 +166,22 @@ static void spll_enable_tagger(int channel, int enable)
SPLL->RCER &= ~ (1<<channel);
}
// TRACE("%s: ch %d, OCER 0x%x, RCER 0x%x\n", __FUNCTION__, channel, SPLL->OCER, SPLL->RCER);
TRACE("%s: ch %d, OCER 0x%x, RCER 0x%x\n", __FUNCTION__, channel, SPLL->OCER, SPLL->RCER);
}
static void spll_resync_dmtd_counter(int channel)
{
if(channel >= n_chan_ref) /* Output channel? */
SPLL->CRR_OUT = 1<< (channel - n_chan_ref);
else
SPLL->CRR_IN = 1<< channel;
}
static int spll_check_dmtd_resync(int channel)
{
if(channel >= n_chan_ref) /* Output channel? */
return (SPLL->CRR_OUT & (1<< (channel - n_chan_ref))) ? 1 : 0;
else
return (SPLL->CRR_IN & (1<< channel)) ? 1 :0;
}
\ No newline at end of file
......@@ -6,6 +6,7 @@
#define MATCH_WAIT_OUT 2
#undef WITH_SEQUENCING
//#define WITH_SEQUENCING
/* State of the Main PLL */
struct spll_main_state {
......@@ -15,7 +16,8 @@ struct spll_main_state {
spll_lock_det_t ld;
int adder_ref, adder_out, tag_ref, tag_out, tag_ref_d, tag_out_d;
int err_d0, err_d1;
// tag sequencing stuff
uint32_t seq_ref, seq_out;
int match_state;
......@@ -61,7 +63,7 @@ static void mpll_start(struct spll_main_state *s)
s->seq_ref = 0;
s->seq_out = 0;
s->match_state = MATCH_NEXT_TAG;
s->err_d0 = s->err_d1 = 0;
s->phase_shift_target = 0;
s->phase_shift_current = 0;
s->sample_n= 0;
......@@ -153,6 +155,15 @@ static int mpll_update(struct spll_main_state *s, int tag, int source)
#ifndef WITH_SEQUENCING
/* if(s->err_d0 - s->err_d1 > -(1<<HPLL_N)/2 && err - s->err_d0 < -(1<<HPLL_N)/2 )
err += (1<<HPLL_N);
if(s->err_d0 - s->err_d1 < (1<<HPLL_N)/2 && err - s->err_d0 > (1<<HPLL_N)/2 )
err -= (1<<HPLL_N);
s->err_d1 = s->err_d0;
s->err_d0 = err;*/
/* Hack: the PLL is locked, so the tags are close to each other. But when we start phase shifting, after reaching
full clock period, one of the reference tags will flip before the other, causing a suddent 2**HPLL_N jump in the error.
So, once the PLL is locked, we just mask out everything above 2**HPLL_N.
......@@ -168,19 +179,19 @@ static int mpll_update(struct spll_main_state *s, int tag, int source)
#endif
y = pi_update(&s->pi, err);
y = pi_update(&s->pi, err);
SPLL->DAC_MAIN = SPLL_DAC_MAIN_VALUE_W(y) | SPLL_DAC_MAIN_DAC_SEL_W(s->id_out);
spll_debug(DBG_MAIN | DBG_REF, s->tag_ref + s->adder_ref, 0);
spll_debug(DBG_MAIN | DBG_TAG, s->tag_out + s->adder_out, 0);
spll_debug(DBG_MAIN | DBG_ERR, err, 0);
spll_debug(DBG_MAIN | DBG_SAMPLE_ID, s->sample_n++, 0);
spll_debug(DBG_MAIN | DBG_Y, y, 1);
spll_debug(DBG_MAIN | DBG_SAMPLE_ID, s->sample_n++, 1);
// spll_debug(DBG_MAIN | DBG_Y, y, 1);
s->tag_out = -1;
s->tag_ref = -1;
if(s->adder_ref > 2*MPLL_TAG_WRAPAROUND && s->adder_out > 2*MPLL_TAG_WRAPAROUND)
if(s->adder_ref > 2*MPLL_TAG_WRAPAROUND && s->adder_out > 2*MPLL_TAG_WRAPAROUND)
{
s->adder_ref -= MPLL_TAG_WRAPAROUND;
s->adder_out -= MPLL_TAG_WRAPAROUND;
......
......@@ -34,6 +34,7 @@ static void ptracker_start(struct spll_ptracker_state *s)
s->sample_n= 0;
s->preserve_sign = 0;
spll_resync_dmtd_counter(s->id_b);
spll_enable_tagger(s->id_a, 1);
spll_enable_tagger(s->id_b, 1);
}
......
......@@ -3,7 +3,7 @@
* File : softpll_regs.h
* Author : auto-generated by wbgen2 from spll_wb_slave.wb
* Created : Mon Apr 16 16:49:35 2012
* Created : Mon Jul 23 15:02:57 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
......@@ -14,6 +14,8 @@
#ifndef __WBGEN2_REGDEFS_SPLL_WB_SLAVE_WB
#define __WBGEN2_REGDEFS_SPLL_WB_SLAVE_WB
#include <stdint.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
......@@ -146,6 +148,10 @@
#define SPLL_DFR_SPLL_EOS_W(value) WBGEN2_GEN_WRITE(value, 31, 1)
#define SPLL_DFR_SPLL_EOS_R(reg) WBGEN2_GEN_READ(reg, 31, 1)
/* definitions for register: Counter Resync Register - input channels */
/* definitions for register: Counter Resync Register - output channels */
/* definitions for register: Interrupt disable register */
/* definitions for field: Got a tag in reg: Interrupt disable register */
......@@ -243,8 +249,12 @@ PACKED struct SPLL_WB {
uint32_t DEGLITCH_THR;
/* [0x2c]: REG Debug FIFO Register - SPLL side */
uint32_t DFR_SPLL;
/* [0x30]: REG Counter Resync Register - input channels */
uint32_t CRR_IN;
/* [0x34]: REG Counter Resync Register - output channels */
uint32_t CRR_OUT;
/* padding to: 16 words */
uint32_t __padding_0[4];
uint32_t __padding_0[2];
/* [0x40]: REG Interrupt disable register */
uint32_t EIC_IDR;
/* [0x44]: REG Interrupt enable register */
......
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